refactor: remove Lecturer model and resources in favor of string-based lecturer names in Course model
This commit is contained in:
parent
a30f4c5967
commit
0070c6b0b1
@ -26,7 +26,7 @@ protected function setUp(): void
|
||||
$action->makeModalSubmitAction('createAnother', arguments: ['another' => true])
|
||||
->label('Simpan dan Tambah Lagi'),
|
||||
])
|
||||
->modalWidth(Width::Large)
|
||||
->modalWidth(Width::ThreeExtraLarge)
|
||||
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ protected function setUp(): void
|
||||
->modalHeading('Ubah Jadwal Kuliah')
|
||||
->modalSubmitActionLabel('Simpan')
|
||||
->modalCancelActionLabel('Batal')
|
||||
->modalWidth(Width::Large)
|
||||
->modalWidth(Width::ThreeExtraLarge)
|
||||
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,21 +95,14 @@ public function deleteScheduleAction(): Action
|
||||
|
||||
public function getSchedules(): Collection
|
||||
{
|
||||
$user = auth()->user();
|
||||
$lecturer = $user->lecturer;
|
||||
|
||||
$query = CourseSchedule::with(['course.lecturer']);
|
||||
|
||||
if ($lecturer) {
|
||||
$query->whereHas('course', fn ($q) => $q->where('lecturer_id', $lecturer->id));
|
||||
}
|
||||
$query = CourseSchedule::with(['course']);
|
||||
|
||||
$query->whereHas('course', fn ($q) => $q->where('semester', app(GeneralSettings::class)->current_semester));
|
||||
|
||||
if ($this->search) {
|
||||
$query->where(function ($q) {
|
||||
$q->whereHas('course', fn ($sq) => $sq->where('name', 'like', "%{$this->search}%"))
|
||||
->orWhereHas('course.lecturer', fn ($sq) => $sq->where('full_name', 'like', "%{$this->search}%"));
|
||||
$q->whereHas('course', fn ($sq) => $sq->where('name', 'like', "%{$this->search}%")
|
||||
->orWhere('lecturer', 'like', "%{$this->search}%"));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ public function getSchedules()
|
||||
->whereHas('course', function ($q) use ($semester) {
|
||||
$q->where('semester', $semester);
|
||||
})
|
||||
->with(['course.lecturer', 'attendances' => function ($q) use ($student) {
|
||||
->with(['course', 'attendances' => function ($q) use ($student) {
|
||||
$q->where('student_id', $student->id)
|
||||
->whereDate('date', now()->toDateString());
|
||||
}])
|
||||
@ -88,7 +88,7 @@ public function getScheduleCards()
|
||||
return (object) [
|
||||
'id' => $schedule->id,
|
||||
'course_name' => $schedule->course->name,
|
||||
'lecturer_name' => $schedule->course->lecturer?->full_name ?? 'Belum Ditentukan',
|
||||
'lecturer_name' => $schedule->course->lecturer ?? 'Belum Ditentukan',
|
||||
'time_range' => $schedule->start_time->format('H:i').' - '.$schedule->end_time->format('H:i'),
|
||||
'is_attended' => $isAttended,
|
||||
'can_attend' => $canAttend && ! $isAttended,
|
||||
@ -187,7 +187,7 @@ public function table(Table $table): Table
|
||||
->searchable()
|
||||
->sortable()
|
||||
->wrap()
|
||||
->description(fn (Attendance $record): string => $record->courseSchedule->course->lecturer->full_name),
|
||||
->description(fn (Attendance $record): string => $record->courseSchedule->course->lecturer ?? 'Belum Ditentukan'),
|
||||
])
|
||||
->defaultSort('date', 'desc')
|
||||
->filters([
|
||||
|
||||
@ -120,7 +120,7 @@ public function getTodaySessions(): Collection
|
||||
->whereHas('course', function ($query) {
|
||||
$query->where('semester', app(GeneralSettings::class)->current_semester);
|
||||
})
|
||||
->with(['course.lecturer', 'course.classSessions' => fn ($q) => $q->whereDate('date', now())])
|
||||
->with(['course', 'course.classSessions' => fn ($q) => $q->whereDate('date', now())])
|
||||
->orderBy('start_time', 'asc')
|
||||
->get();
|
||||
|
||||
@ -143,13 +143,13 @@ public function getCourses(): Collection
|
||||
{
|
||||
$query = Course::query()
|
||||
->where('semester', app(GeneralSettings::class)->current_semester)
|
||||
->with(['classSessions' => fn ($q) => $q->orderBy('session_number', 'asc'), 'lecturer']);
|
||||
->with(['classSessions' => fn ($q) => $q->orderBy('session_number', 'asc')]);
|
||||
|
||||
if ($this->search) {
|
||||
$query->where(function ($q) {
|
||||
$q->where('name', 'like', "%{$this->search}%")
|
||||
->orWhere('code', 'like', "%{$this->search}%")
|
||||
->orWhereHas('lecturer', fn ($sq) => $sq->where('full_name', 'like', "%{$this->search}%"));
|
||||
->orWhere('lecturer', 'like', "%{$this->search}%");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
use App\Models\Course;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
@ -35,6 +34,8 @@ class CourseResource extends Resource
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
protected static ?string $title = 'Mata Kuliah';
|
||||
|
||||
protected static ?string $navigationLabel = 'Mata Kuliah';
|
||||
|
||||
protected static ?int $navigationSort = 15;
|
||||
@ -82,13 +83,11 @@ public static function form(Schema $schema): Schema
|
||||
->maxValue(8)
|
||||
->helperText('Semester ke berapa mata kuliah ini diajarkan (1-8).'),
|
||||
|
||||
Select::make('lecturer_id')
|
||||
TextInput::make('lecturer')
|
||||
->label('Dosen Pengampu')
|
||||
->placeholder('Pilih Dosen')
|
||||
->relationship('lecturer', 'full_name')
|
||||
->preload()
|
||||
->searchable()
|
||||
->helperText('Pilih dosen yang mengampu mata kuliah ini.')
|
||||
->placeholder('Ujang')
|
||||
->maxLength(100)
|
||||
->helperText('Masukkan nama dosen yang mengampu mata kuliah ini.')
|
||||
->required(),
|
||||
|
||||
])
|
||||
@ -112,8 +111,9 @@ public static function table(Table $table): Table
|
||||
->label('SKS')
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('lecturer.full_name')
|
||||
TextColumn::make('lecturer')
|
||||
->label('Dosen Pengampu')
|
||||
->placeholder('Belum ditentukan')
|
||||
->searchable(),
|
||||
|
||||
...TimestampColumns::make(),
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Master\Lecturers;
|
||||
|
||||
use App\Filament\Resources\Master\Lecturers\Pages\CreateLecturer;
|
||||
use App\Filament\Resources\Master\Lecturers\Pages\EditLecturer;
|
||||
use App\Filament\Resources\Master\Lecturers\Pages\ListLecturers;
|
||||
use App\Filament\Resources\Master\Lecturers\Schemas\LecturerForm;
|
||||
use App\Filament\Resources\Master\Lecturers\Tables\LecturersTable;
|
||||
use App\Models\Lecturer;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use UnitEnum;
|
||||
|
||||
class LecturerResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Lecturer::class;
|
||||
|
||||
protected static string|UnitEnum|null $navigationGroup = 'Master';
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedUserGroup;
|
||||
|
||||
protected static ?string $navigationLabel = 'Dosen';
|
||||
|
||||
protected static ?int $navigationSort = 10;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'full_name';
|
||||
|
||||
protected static ?string $slug = 'master/lecturers';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return LecturerForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return LecturersTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListLecturers::route('/'),
|
||||
'create' => CreateLecturer::route('/create'),
|
||||
'edit' => EditLecturer::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Master\Lecturers\Pages;
|
||||
|
||||
use App\Filament\Actions\BackAction;
|
||||
use App\Filament\Resources\Master\Lecturers\LecturerResource;
|
||||
use App\Filament\Support\SystemNotification;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateLecturer extends CreateRecord
|
||||
{
|
||||
protected static string $resource = LecturerResource::class;
|
||||
|
||||
protected ?string $heading = 'Tambah Dosen';
|
||||
|
||||
protected static ?string $title = 'Tambah Dosen';
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
BackAction::make()
|
||||
->url(ListLecturers::getUrl()),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->getResource()::getUrl('index');
|
||||
}
|
||||
|
||||
protected function getCreatedNotification(): ?Notification
|
||||
{
|
||||
return SystemNotification::create();
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Master\Lecturers\Pages;
|
||||
|
||||
use App\Filament\Actions\BackAction;
|
||||
use App\Filament\Resources\Master\Lecturers\LecturerResource;
|
||||
use App\Filament\Support\SystemNotification;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditLecturer extends EditRecord
|
||||
{
|
||||
protected static string $resource = LecturerResource::class;
|
||||
|
||||
protected ?string $heading = 'Ubah Dosen';
|
||||
|
||||
protected static ?string $title = 'Ubah Dosen';
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
BackAction::make()
|
||||
->url(ListLecturers::getUrl()),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->getResource()::getUrl('index');
|
||||
}
|
||||
|
||||
protected function getSavedNotification(): ?Notification
|
||||
{
|
||||
return SystemNotification::update();
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Master\Lecturers\Pages;
|
||||
|
||||
use App\Filament\Actions\Cheerful\CreateAction;
|
||||
use App\Filament\Resources\Master\Lecturers\LecturerResource;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListLecturers extends ListRecords
|
||||
{
|
||||
protected static string $resource = LecturerResource::class;
|
||||
|
||||
protected static ?string $title = 'Dosen';
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make()
|
||||
->label('Tambah'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,121 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Master\Lecturers\Schemas;
|
||||
|
||||
use App\Enums\Sex;
|
||||
use App\Models\Course;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Radio;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class LecturerForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
|
||||
Section::make('Informasi Dosen')
|
||||
->schema([
|
||||
TextInput::make('full_name')
|
||||
->label('Nama Lengkap')
|
||||
->placeholder('John Doe')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(100)
|
||||
->minLength(3)
|
||||
->autofocus()
|
||||
->helperText('Masukkan nama lengkap dosen beserta gelar akademik.')
|
||||
->columnSpanFull(),
|
||||
|
||||
Grid::make(3)
|
||||
->schema([
|
||||
TextInput::make('lecturer_identification_number')
|
||||
->label('NIDN')
|
||||
->placeholder('1234567890')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->numeric()
|
||||
->rules(['digits:10'])
|
||||
->unique(ignoreRecord: true),
|
||||
|
||||
TextInput::make('phone_number')
|
||||
->label('Nomor Telepon')
|
||||
->placeholder('0812 3456 78910')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(20)
|
||||
->minLength(10)
|
||||
->rules(['regex:/^[0-9 ]+$/'])
|
||||
->mask('9999 9999 99999'),
|
||||
|
||||
Radio::make('sex')
|
||||
->label('Jenis Kelamin')
|
||||
->options(Sex::class)
|
||||
->required()
|
||||
->inline(),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
|
||||
Textarea::make('address')
|
||||
->label('Alamat')
|
||||
->placeholder('Jl. Contoh No. 123, Kota, Provinsi')
|
||||
->autocomplete(false)
|
||||
->rows(3)
|
||||
->nullable()
|
||||
->columnSpanFull(),
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
DatePicker::make('date_of_birth')
|
||||
->label('Tanggal Lahir')
|
||||
->placeholder('Pilih Tanggal')
|
||||
->required()
|
||||
->native(false)
|
||||
->displayFormat('l, d F Y')
|
||||
->maxDate(Carbon::now()->subYears(25)),
|
||||
|
||||
TextInput::make('place_of_birth')
|
||||
->label('Tempat Lahir')
|
||||
->placeholder('Purwakarta')
|
||||
->autocomplete(false)
|
||||
->required()
|
||||
->maxLength(50)
|
||||
->minLength(3),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columns(2),
|
||||
|
||||
Section::make('Mata Kuliah')
|
||||
->description('Daftar mata kuliah yang diampu oleh dosen ini.')
|
||||
->schema([
|
||||
Select::make('courses')
|
||||
->label('Mata Kuliah')
|
||||
->multiple()
|
||||
->relationship('courses', 'name')
|
||||
->options(function () {
|
||||
return Course::all()
|
||||
->groupBy('semester')
|
||||
->mapWithKeys(function ($courses, $semester) {
|
||||
return [
|
||||
"Semester $semester" => $courses->pluck('name', 'id')->toArray(),
|
||||
];
|
||||
})
|
||||
->toArray();
|
||||
})
|
||||
->searchable()
|
||||
->preload()
|
||||
->live()
|
||||
->required(),
|
||||
]),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
}
|
||||
@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Master\Lecturers\Tables;
|
||||
|
||||
use App\Enums\RoleEnum;
|
||||
use App\Enums\Sex;
|
||||
use App\Filament\Actions\Cheerful\DeleteAction;
|
||||
use App\Filament\Actions\Cheerful\EditAction;
|
||||
use App\Filament\Actions\Cheerful\ForceDeleteAction;
|
||||
use App\Filament\Actions\Cheerful\RestoreAction;
|
||||
use App\Filament\Actions\DefaultBulkActions;
|
||||
use App\Filament\Columns\TimestampColumns;
|
||||
use App\Models\Lecturer;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class LecturersTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
|
||||
TextColumn::make('full_name')
|
||||
->label('Nama Lengkap')
|
||||
->searchable(query: function (Builder $query, string $search) {
|
||||
$query->where('full_name', 'like', "%{$search}%")
|
||||
->orWhere('lecturer_identification_number', 'like', "%{$search}%");
|
||||
})
|
||||
->sortable()
|
||||
->description(fn (Lecturer $record) => $record->lecturer_identification_number),
|
||||
|
||||
TextColumn::make('phone_number')
|
||||
->label('No. Telepon')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('sex')
|
||||
->label('Jenis Kelamin')
|
||||
->badge()
|
||||
->sortable()
|
||||
->searchable(query: function ($query, string $search) {
|
||||
$search = strtolower($search);
|
||||
|
||||
if (str_contains('laki-laki', $search)) {
|
||||
$query->orWhere('sex', 'male');
|
||||
}
|
||||
|
||||
if (str_contains('perempuan', $search)) {
|
||||
$query->orWhere('sex', 'female');
|
||||
}
|
||||
}),
|
||||
|
||||
TextColumn::make('date_of_birth')
|
||||
->label('TTL')
|
||||
->date('d F Y')
|
||||
->sortable()
|
||||
->prefix(fn (Lecturer $record) => $record->place_of_birth ? $record->place_of_birth.', ' : ''),
|
||||
|
||||
TextColumn::make('address')
|
||||
->label('Alamat')
|
||||
->limit(50),
|
||||
|
||||
TextColumn::make('courses.name')
|
||||
->label('Mata Kuliah')
|
||||
->badge()
|
||||
->searchable()
|
||||
->listWithLineBreaks(),
|
||||
|
||||
...TimestampColumns::make(),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('sex')
|
||||
->label('Jenis Kelamin')
|
||||
->options(Sex::class)
|
||||
->native(false),
|
||||
|
||||
SelectFilter::make('courses')
|
||||
->label('Mata Kuliah')
|
||||
->relationship('courses', 'name')
|
||||
->multiple()
|
||||
->preload(),
|
||||
|
||||
TrashedFilter::make()
|
||||
->native(false)
|
||||
->visible(fn () => auth()->user()->hasRole(RoleEnum::Developer)),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make()
|
||||
->modalWidth(Width::Large),
|
||||
|
||||
DeleteAction::make(),
|
||||
|
||||
ForceDeleteAction::make(),
|
||||
|
||||
RestoreAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
...DefaultBulkActions::make('Dosen'),
|
||||
]),
|
||||
])
|
||||
->emptyStateIcon(Heroicon::OutlinedUserGroup)
|
||||
->emptyStateDescription('Setelah Anda membuat data pertama, maka akan muncul disini.')
|
||||
->defaultSort('created_at', 'desc')
|
||||
->deferFilters(false)
|
||||
->paginated([25, 50, 100, 'all'])
|
||||
->defaultPaginationPageOption(25);
|
||||
}
|
||||
}
|
||||
@ -2,10 +2,8 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -23,18 +21,6 @@ protected static function booted()
|
||||
});
|
||||
}
|
||||
|
||||
public function lecturer(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Lecturer::class);
|
||||
}
|
||||
|
||||
public static function getOptionsForLecturer(Lecturer $lecturer): Collection
|
||||
{
|
||||
return static::query()
|
||||
->where('lecturer_id', $lecturer->id)
|
||||
->get();
|
||||
}
|
||||
|
||||
public function materials(): HasMany
|
||||
{
|
||||
return $this->hasMany(Material::class);
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\Sex;
|
||||
use Illuminate\Database\Eloquent\Attributes\Scope;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Lecturer extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'date_of_birth' => 'date',
|
||||
'sex' => Sex::class,
|
||||
];
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function female(Builder $query): void
|
||||
{
|
||||
$query->where('sex', Sex::Female);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function male(Builder $query): void
|
||||
{
|
||||
$query->where('sex', Sex::Male);
|
||||
}
|
||||
|
||||
public function courses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Course::class);
|
||||
}
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Lecturer;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
|
||||
class LecturerPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Lecturer');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Lecturer $lecturer): bool
|
||||
{
|
||||
return $authUser->can('View:Lecturer');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Lecturer');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Lecturer $lecturer): bool
|
||||
{
|
||||
return $authUser->can('Update:Lecturer');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Lecturer $lecturer): bool
|
||||
{
|
||||
return $authUser->can('Delete:Lecturer');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Lecturer $lecturer): bool
|
||||
{
|
||||
return $authUser->can('Restore:Lecturer');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Lecturer $lecturer): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Lecturer');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Lecturer');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Lecturer');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Lecturer $lecturer): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Lecturer');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Lecturer');
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\Sex;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('lecturers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('lecturer_identification_number', 10)->unique();
|
||||
$table->string('full_name', 100);
|
||||
$table->string('phone_number', 20);
|
||||
$table->enum('sex', Sex::cases());
|
||||
$table->text('address')->nullable();
|
||||
$table->date('date_of_birth');
|
||||
$table->string('place_of_birth', 50);
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('lecturers');
|
||||
}
|
||||
};
|
||||
@ -13,7 +13,7 @@ public function up(): void
|
||||
{
|
||||
Schema::create('courses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('lecturer_id')->nullable()->constrained()->nullOnDelete();
|
||||
$table->string('lecturer', 100)->nullable();
|
||||
$table->string('code', 20)->unique();
|
||||
$table->string('name', 100);
|
||||
$table->integer('credit')->default(3);
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Course;
|
||||
use App\Models\Lecturer;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class CourseSeeder extends Seeder
|
||||
@ -13,6 +12,17 @@ class CourseSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$lecturers = [
|
||||
'Dr. Ahmad Hidayat',
|
||||
'Siti Aminah, M.Kom.',
|
||||
'Budi Santoso, S.T., M.T.',
|
||||
'Dr. Ir. Heru Prasetyo',
|
||||
'Lusi Fitriani, M.Sc.',
|
||||
'Andi Wijaya, M.T.',
|
||||
'Rina Wahyuni, Ph.D.',
|
||||
'Dian Pratama, M.Kom.',
|
||||
];
|
||||
|
||||
$courses = [
|
||||
// Semester 1
|
||||
['code' => 'SIU101', 'name' => 'Ilmu Amaliah, Sosial, dan Budaya Dasar', 'credit' => 2, 'semester' => 1],
|
||||
@ -84,31 +94,8 @@ public function run(): void
|
||||
['code' => 'FSI839', 'name' => 'Startup Digital', 'credit' => 2, 'semester' => 8],
|
||||
];
|
||||
|
||||
$lecturers = Lecturer::pluck('id')->toArray();
|
||||
|
||||
shuffle($lecturers);
|
||||
|
||||
$lecturerSemesterMap = [];
|
||||
|
||||
foreach ($courses as $i => &$course) {
|
||||
|
||||
$semester = $course['semester'];
|
||||
|
||||
if ($i < count($lecturers)) {
|
||||
$lecturerId = $lecturers[$i];
|
||||
} else {
|
||||
|
||||
do {
|
||||
$lecturerId = $lecturers[array_rand($lecturers)];
|
||||
} while (
|
||||
isset($lecturerSemesterMap[$lecturerId]) &&
|
||||
in_array($semester, $lecturerSemesterMap[$lecturerId])
|
||||
);
|
||||
}
|
||||
|
||||
$course['lecturer_id'] = $lecturerId;
|
||||
|
||||
$lecturerSemesterMap[$lecturerId][] = $semester;
|
||||
foreach ($courses as &$course) {
|
||||
$course['lecturer'] = $lecturers[array_rand($lecturers)];
|
||||
}
|
||||
|
||||
Course::insert($courses);
|
||||
|
||||
@ -17,7 +17,6 @@ public function run(): void
|
||||
$this->call([
|
||||
ShieldSeeder::class,
|
||||
UserSeeder::class,
|
||||
LecturerSeeder::class,
|
||||
StudentSeeder::class,
|
||||
CourseSeeder::class,
|
||||
CourseScheduleSeeder::class,
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\Sex;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LecturerSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$names = [
|
||||
'Dr. Budi Santoso, S.Kom, M.Sc',
|
||||
'Prof. Siti Rahmawati, M.T',
|
||||
'Dr. Ahmad Fauzan, M.Kom',
|
||||
'Ir. Dwi Prasetyo, M.Eng',
|
||||
'Dr. Maya Kartika, M.Sc',
|
||||
'Dr. Andi Saputra, M.Kom',
|
||||
'Prof. Rizky Maulana, Ph.D',
|
||||
'Dr. Nanda Putri, M.T',
|
||||
'Ir. Fajar Hidayat, M.Eng',
|
||||
'Dr. Taufik Ramadhan, M.Kom',
|
||||
'Dr. Indah Permata Sari, M.Sc',
|
||||
'Prof. Yoga Pratama, Ph.D',
|
||||
'Dr. Dian Lestari, M.T',
|
||||
'Ir. Arif Nugroho, M.Eng',
|
||||
'Dr. Bagus Sekali Namanya, M.Kom',
|
||||
];
|
||||
|
||||
$cities = [
|
||||
'Bandung',
|
||||
'Jakarta',
|
||||
'Surabaya',
|
||||
'Yogyakarta',
|
||||
'Semarang',
|
||||
'Bogor',
|
||||
'Depok',
|
||||
'Bekasi',
|
||||
'Malang',
|
||||
'Solo',
|
||||
'Padang',
|
||||
'Medan',
|
||||
'Palembang',
|
||||
'Makassar',
|
||||
'Denpasar',
|
||||
];
|
||||
|
||||
for ($i = 0; $i < 15; $i++) {
|
||||
DB::table('lecturers')->insert([
|
||||
'lecturer_identification_number' => str_pad($i + 1, 10, '0', STR_PAD_LEFT),
|
||||
'full_name' => $names[$i],
|
||||
'phone_number' => '08123456'.rand(1000, 9999),
|
||||
'sex' => $i % 2 === 0 ? Sex::Male->value : Sex::Female->value,
|
||||
'address' => 'Jl. Kampus No. '.rand(1, 200),
|
||||
'date_of_birth' => Carbon::now()->subYears(rand(30, 55))->toDateString(),
|
||||
'place_of_birth' => $cities[$i],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,17 +34,6 @@ public function run(): void
|
||||
"Replicate:Student",
|
||||
"Reorder:Student",
|
||||
|
||||
"ViewAny:Lecturer",
|
||||
"View:Lecturer",
|
||||
"Create:Lecturer",
|
||||
"Update:Lecturer",
|
||||
"Delete:Lecturer",
|
||||
"Restore:Lecturer",
|
||||
"ForceDelete:Lecturer",
|
||||
"ForceDeleteAny:Lecturer",
|
||||
"RestoreAny:Lecturer",
|
||||
"Replicate:Lecturer",
|
||||
"Reorder:Lecturer",
|
||||
|
||||
"ViewAny:Course",
|
||||
"View:Course",
|
||||
@ -153,8 +142,6 @@ public function run(): void
|
||||
"ViewAny:Student",
|
||||
"View:Student",
|
||||
|
||||
"ViewAny:Lecturer",
|
||||
"View:Lecturer",
|
||||
|
||||
"ViewAny:Course",
|
||||
"View:Course",
|
||||
@ -183,9 +170,6 @@ public function run(): void
|
||||
"Update:Student",
|
||||
"Delete:Student",
|
||||
|
||||
"Create:Lecturer",
|
||||
"Update:Lecturer",
|
||||
"Delete:Lecturer",
|
||||
|
||||
"Create:Course",
|
||||
"Update:Course",
|
||||
|
||||
@ -1,135 +1,138 @@
|
||||
<x-filament-panels::page>
|
||||
<x-filament::section>
|
||||
<div
|
||||
class="fi-section-content rounded-xl border border-info-200 bg-info-50 dark:bg-info-500/10 dark:border-info-500/30 p-4 mb-6">
|
||||
<div class="flex items-start gap-3">
|
||||
<x-heroicon-o-information-circle class="w-5 h-5 text-info-600 dark:text-info-400 mt-0.5" />
|
||||
<div>
|
||||
<x-filament::section>
|
||||
<div
|
||||
class="fi-section-content rounded-xl border border-info-200 bg-info-50 dark:bg-info-500/10 dark:border-info-500/30 p-4 mb-6">
|
||||
<div class="flex items-start gap-3">
|
||||
<x-heroicon-o-information-circle class="w-5 h-5 text-info-600 dark:text-info-400 mt-0.5" />
|
||||
|
||||
<div class="text-sm text-info-800 dark:text-info-200">
|
||||
Geser ke samping untuk melihat hari lainnya.
|
||||
<div class="text-sm text-info-800 dark:text-info-200">
|
||||
Geser ke samping untuk melihat hari lainnya.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between gap-4 mb-6">
|
||||
<div class="w-full max-w-xl">
|
||||
{{ $this->form }}
|
||||
<div class="flex items-center justify-between gap-4 mb-6">
|
||||
<div class="w-full max-w-xl">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($schedules->isNotEmpty())
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex flex-nowrap gap-6 min-w-max pb-4">
|
||||
@if ($schedules->isNotEmpty())
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex flex-nowrap gap-6 min-w-max pb-4">
|
||||
|
||||
@foreach ($days as $dayNumber => $dayName)
|
||||
@php
|
||||
$daySchedules = $schedules->get($dayNumber);
|
||||
@endphp
|
||||
@foreach ($days as $dayNumber => $dayName)
|
||||
@php
|
||||
$daySchedules = $schedules->get($dayNumber);
|
||||
@endphp
|
||||
|
||||
@if ($daySchedules && $daySchedules->count() > 0)
|
||||
<section class="w-80 shrink-0 space-y-4">
|
||||
@if ($daySchedules && $daySchedules->count() > 0)
|
||||
<section class="w-80 shrink-0 space-y-4">
|
||||
|
||||
<div class="flex items-center gap-2 border-b border-gray-200 dark:border-gray-700 pb-2">
|
||||
<x-heroicon-o-calendar class="w-5 h-5 text-primary-500" />
|
||||
<h2 class="text-lg font-semibold tracking-tight text-gray-950 dark:text-white">
|
||||
{{ $dayName }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 border-b border-gray-200 dark:border-gray-700 pb-2">
|
||||
<x-heroicon-o-calendar class="w-5 h-5 text-primary-500" />
|
||||
<h2 class="text-lg font-semibold tracking-tight text-gray-950 dark:text-white">
|
||||
{{ $dayName }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
@foreach ($daySchedules as $schedule)
|
||||
<div
|
||||
class="fi-card rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 shadow-sm hover:shadow-md transition">
|
||||
<div class="space-y-4">
|
||||
@foreach ($daySchedules as $schedule)
|
||||
<div
|
||||
class="fi-card rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 shadow-sm hover:shadow-md transition">
|
||||
|
||||
<div class="p-5 space-y-4">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
class="inline-flex items-center rounded-md bg-primary-50 dark:bg-primary-500/10 px-2 py-1 text-xs font-semibold text-primary-700 dark:text-primary-300 ring-1 ring-inset ring-primary-600/20">
|
||||
{{ $schedule->course->code ?? 'MATKUL' }}
|
||||
</span>
|
||||
|
||||
@if ($schedule->mode)
|
||||
@php
|
||||
$color = $schedule->mode->getColor();
|
||||
@endphp
|
||||
<div class="p-5 space-y-4">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
class="inline-flex items-center rounded-md bg-{{ $color }}-50 dark:bg-{{ $color }}-500/10 px-2 py-1 text-xs font-semibold text-{{ $color }}-700 dark:text-{{ $color }}-300 ring-1 ring-inset ring-{{ $color }}-600/20">
|
||||
{{ $schedule->mode->getLabel() }}
|
||||
class="inline-flex items-center rounded-md bg-primary-50 dark:bg-primary-500/10 px-2 py-1 text-xs font-semibold text-primary-700 dark:text-primary-300 ring-1 ring-inset ring-primary-600/20">
|
||||
{{ $schedule->course->code ?? 'MATKUL' }}
|
||||
</span>
|
||||
|
||||
@if ($schedule->mode)
|
||||
@php
|
||||
$color = $schedule->mode->getColor();
|
||||
@endphp
|
||||
<span
|
||||
class="inline-flex items-center rounded-md bg-{{ $color }}-50 dark:bg-{{ $color }}-500/10 px-2 py-1 text-xs font-semibold text-{{ $color }}-700 dark:text-{{ $color }}-300 ring-1 ring-inset ring-{{ $color }}-600/20">
|
||||
{{ $schedule->mode->getLabel() }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($schedule->room)
|
||||
<span
|
||||
class="inline-flex items-center text-xs text-gray-500 dark:text-gray-400">
|
||||
<x-heroicon-m-map-pin class="w-4 h-4 mr-1 opacity-70" />
|
||||
{{ $schedule->room }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($schedule->room)
|
||||
<span
|
||||
class="inline-flex items-center text-xs text-gray-500 dark:text-gray-400">
|
||||
<x-heroicon-m-map-pin class="w-4 h-4 mr-1 opacity-70" />
|
||||
{{ $schedule->room }}
|
||||
<h3
|
||||
class="text-base font-semibold leading-tight text-gray-950 dark:text-white">
|
||||
{{ $schedule->course->name ?? 'Mata Kuliah Tidak Diketahui' }}
|
||||
</h3>
|
||||
|
||||
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
||||
<x-heroicon-m-user class="w-4 h-4 mr-1.5 opacity-70" />
|
||||
<span class="truncate">
|
||||
{{ $schedule->course->lecturer ?? 'Dosen Belum Ditentukan' }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<h3
|
||||
class="text-base font-semibold leading-tight text-gray-950 dark:text-white">
|
||||
{{ $schedule->course->name ?? 'Mata Kuliah Tidak Diketahui' }}
|
||||
</h3>
|
||||
<div class="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
||||
<x-heroicon-m-user class="w-4 h-4 mr-1.5 opacity-70" />
|
||||
<span class="truncate">
|
||||
{{ $schedule->course->lecturer->full_name ?? 'Dosen Belum Ditentukan' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-2 mt-1">
|
||||
@if ($schedule->course?->semester)
|
||||
<span
|
||||
class="inline-flex items-center gap-1 rounded-md bg-amber-50 dark:bg-amber-500/10 px-2 py-1 text-xs font-medium text-amber-700 dark:text-amber-300 ring-1 ring-inset ring-amber-600/20">
|
||||
<x-heroicon-m-academic-cap class="w-3 h-3" />
|
||||
Semester {{ $schedule->course->semester }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex items-center justify-between pt-3 border-t border-gray-100 dark:border-gray-800 text-sm">
|
||||
<div
|
||||
class="flex items-center font-medium text-gray-800 dark:text-gray-200">
|
||||
<x-heroicon-o-clock class="w-4 h-4 mr-1.5 text-primary-500" />
|
||||
{{ $schedule->start_time->format('H:i') }}
|
||||
<span class="mx-1">–</span>
|
||||
{{ $schedule->end_time->format('H:i') }}
|
||||
</div>
|
||||
|
||||
<span
|
||||
class="text-[11px] font-semibold tracking-wide text-gray-400 uppercase">
|
||||
{{ $schedule->course->credit ?? '-' }} SKS
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@canAny(['Update:CourseSchedule', 'Delete:CourseSchedule'])
|
||||
<div
|
||||
class="flex items-center justify-end gap-1 pt-3 border-t border-gray-100 dark:border-gray-800">
|
||||
{{ ($this->editScheduleAction)(['schedule' => $schedule->id]) }}
|
||||
|
||||
{{ ($this->deleteScheduleAction)(['schedule' => $schedule->id]) }}
|
||||
<div class="flex flex-wrap items-center gap-2 mt-1">
|
||||
@if ($schedule->course?->semester)
|
||||
<span
|
||||
class="inline-flex items-center gap-1 rounded-md bg-amber-50 dark:bg-amber-500/10 px-2 py-1 text-xs font-medium text-amber-700 dark:text-amber-300 ring-1 ring-inset ring-amber-600/20">
|
||||
<x-heroicon-m-academic-cap class="w-3 h-3" />
|
||||
Semester {{ $schedule->course->semester }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@endcanAny
|
||||
|
||||
<div
|
||||
class="flex items-center justify-between pt-3 border-t border-gray-100 dark:border-gray-800 text-sm">
|
||||
<div
|
||||
class="flex items-center font-medium text-gray-800 dark:text-gray-200">
|
||||
<x-heroicon-o-clock class="w-4 h-4 mr-1.5 text-primary-500" />
|
||||
{{ $schedule->start_time->format('H:i') }}
|
||||
<span class="mx-1">–</span>
|
||||
{{ $schedule->end_time->format('H:i') }}
|
||||
</div>
|
||||
|
||||
<span
|
||||
class="text-[11px] font-semibold tracking-wide text-gray-400 uppercase">
|
||||
{{ $schedule->course->credit ?? '-' }} SKS
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@canAny(['Update:CourseSchedule', 'Delete:CourseSchedule'])
|
||||
<div
|
||||
class="flex items-center justify-end gap-1 pt-3 border-t border-gray-100 dark:border-gray-800">
|
||||
{{ ($this->editScheduleAction)(['schedule' => $schedule->id]) }}
|
||||
|
||||
{{ ($this->deleteScheduleAction)(['schedule' => $schedule->id]) }}
|
||||
</div>
|
||||
@endcanAny
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if ($schedules->isEmpty())
|
||||
<x-filament::empty-state icon="heroicon-o-calendar-days" heading="Tidak ada data yang ditemukan"
|
||||
description="Setelah Anda membuat data pertama, maka akan muncul disini." iconColor="gray">
|
||||
</x-filament::empty-state>
|
||||
@endif
|
||||
</x-filament::section>
|
||||
@if ($schedules->isEmpty())
|
||||
<x-filament::empty-state icon="heroicon-o-calendar-days" heading="Tidak ada data yang ditemukan"
|
||||
description="Setelah Anda membuat data pertama, maka akan muncul disini." iconColor="gray">
|
||||
</x-filament::empty-state>
|
||||
@endif
|
||||
</x-filament::section>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
{{ $session->course->name }}
|
||||
</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mt-0.5 font-medium">
|
||||
{{ $session->course->code }} • {{ $session->course->lecturer->full_name ?? '-' }}
|
||||
{{ $session->course->code }} • {{ $session->course->lecturer ?? '-' }}
|
||||
</p>
|
||||
</div>
|
||||
<div @class([
|
||||
@ -123,7 +123,7 @@ class="text-base font-bold text-gray-950 dark:text-white leading-tight group-hov
|
||||
<div class="flex items-center text-sm text-gray-500 dark:text-gray-400">
|
||||
<x-heroicon-m-user class="w-4 h-4 mr-1.5 opacity-70" />
|
||||
<span
|
||||
class="truncate">{{ $course->lecturer->full_name ?? 'Dosen Belum Ditentukan' }}</span>
|
||||
class="truncate">{{ $course->lecturer ?? 'Dosen Belum Ditentukan' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -40,7 +40,7 @@ class="w-4 h-4 transition-transform duration-300"
|
||||
</h3>
|
||||
<div class="flex items-center text-sm text-gray-500 dark:text-gray-400">
|
||||
<x-heroicon-m-user class="w-4 h-4 mr-1.5 opacity-70" />
|
||||
<span class="truncate">{{ $course->lecturer->full_name ?? 'Dosen Belum Ditentukan' }}</span>
|
||||
<span class="truncate">{{ $course->lecturer ?? 'Dosen Belum Ditentukan' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -108,7 +108,7 @@ class="badge bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 capit
|
||||
<h1 class="text-3xl font-bold tracking-tighter">{{ $course->name }}</h1>
|
||||
<p class="text-zinc-500 flex items-center gap-2 tracking-tight text-sm font-medium">
|
||||
<x-heroicon-o-user class="w-4 h-4 opacity-50" />
|
||||
{{ $course->lecturer->full_name }}
|
||||
{{ $course->lecturer }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user