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])
|
$action->makeModalSubmitAction('createAnother', arguments: ['another' => true])
|
||||||
->label('Simpan dan Tambah Lagi'),
|
->label('Simpan dan Tambah Lagi'),
|
||||||
])
|
])
|
||||||
->modalWidth(Width::Large)
|
->modalWidth(Width::ThreeExtraLarge)
|
||||||
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ protected function setUp(): void
|
|||||||
->modalHeading('Ubah Jadwal Kuliah')
|
->modalHeading('Ubah Jadwal Kuliah')
|
||||||
->modalSubmitActionLabel('Simpan')
|
->modalSubmitActionLabel('Simpan')
|
||||||
->modalCancelActionLabel('Batal')
|
->modalCancelActionLabel('Batal')
|
||||||
->modalWidth(Width::Large)
|
->modalWidth(Width::ThreeExtraLarge)
|
||||||
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,21 +95,14 @@ public function deleteScheduleAction(): Action
|
|||||||
|
|
||||||
public function getSchedules(): Collection
|
public function getSchedules(): Collection
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
$query = CourseSchedule::with(['course']);
|
||||||
$lecturer = $user->lecturer;
|
|
||||||
|
|
||||||
$query = CourseSchedule::with(['course.lecturer']);
|
|
||||||
|
|
||||||
if ($lecturer) {
|
|
||||||
$query->whereHas('course', fn ($q) => $q->where('lecturer_id', $lecturer->id));
|
|
||||||
}
|
|
||||||
|
|
||||||
$query->whereHas('course', fn ($q) => $q->where('semester', app(GeneralSettings::class)->current_semester));
|
$query->whereHas('course', fn ($q) => $q->where('semester', app(GeneralSettings::class)->current_semester));
|
||||||
|
|
||||||
if ($this->search) {
|
if ($this->search) {
|
||||||
$query->where(function ($q) {
|
$query->where(function ($q) {
|
||||||
$q->whereHas('course', fn ($sq) => $sq->where('name', 'like', "%{$this->search}%"))
|
$q->whereHas('course', fn ($sq) => $sq->where('name', 'like', "%{$this->search}%")
|
||||||
->orWhereHas('course.lecturer', fn ($sq) => $sq->where('full_name', 'like', "%{$this->search}%"));
|
->orWhere('lecturer', 'like', "%{$this->search}%"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,7 @@ public function getSchedules()
|
|||||||
->whereHas('course', function ($q) use ($semester) {
|
->whereHas('course', function ($q) use ($semester) {
|
||||||
$q->where('semester', $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)
|
$q->where('student_id', $student->id)
|
||||||
->whereDate('date', now()->toDateString());
|
->whereDate('date', now()->toDateString());
|
||||||
}])
|
}])
|
||||||
@ -88,7 +88,7 @@ public function getScheduleCards()
|
|||||||
return (object) [
|
return (object) [
|
||||||
'id' => $schedule->id,
|
'id' => $schedule->id,
|
||||||
'course_name' => $schedule->course->name,
|
'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'),
|
'time_range' => $schedule->start_time->format('H:i').' - '.$schedule->end_time->format('H:i'),
|
||||||
'is_attended' => $isAttended,
|
'is_attended' => $isAttended,
|
||||||
'can_attend' => $canAttend && ! $isAttended,
|
'can_attend' => $canAttend && ! $isAttended,
|
||||||
@ -187,7 +187,7 @@ public function table(Table $table): Table
|
|||||||
->searchable()
|
->searchable()
|
||||||
->sortable()
|
->sortable()
|
||||||
->wrap()
|
->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')
|
->defaultSort('date', 'desc')
|
||||||
->filters([
|
->filters([
|
||||||
|
|||||||
@ -120,7 +120,7 @@ public function getTodaySessions(): Collection
|
|||||||
->whereHas('course', function ($query) {
|
->whereHas('course', function ($query) {
|
||||||
$query->where('semester', app(GeneralSettings::class)->current_semester);
|
$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')
|
->orderBy('start_time', 'asc')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@ -143,13 +143,13 @@ public function getCourses(): Collection
|
|||||||
{
|
{
|
||||||
$query = Course::query()
|
$query = Course::query()
|
||||||
->where('semester', app(GeneralSettings::class)->current_semester)
|
->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) {
|
if ($this->search) {
|
||||||
$query->where(function ($q) {
|
$query->where(function ($q) {
|
||||||
$q->where('name', 'like', "%{$this->search}%")
|
$q->where('name', 'like', "%{$this->search}%")
|
||||||
->orWhere('code', '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 App\Models\Course;
|
||||||
use BackedEnum;
|
use BackedEnum;
|
||||||
use Filament\Actions\BulkActionGroup;
|
use Filament\Actions\BulkActionGroup;
|
||||||
use Filament\Forms\Components\Select;
|
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
@ -35,6 +34,8 @@ class CourseResource extends Resource
|
|||||||
|
|
||||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||||
|
|
||||||
|
protected static ?string $title = 'Mata Kuliah';
|
||||||
|
|
||||||
protected static ?string $navigationLabel = 'Mata Kuliah';
|
protected static ?string $navigationLabel = 'Mata Kuliah';
|
||||||
|
|
||||||
protected static ?int $navigationSort = 15;
|
protected static ?int $navigationSort = 15;
|
||||||
@ -82,13 +83,11 @@ public static function form(Schema $schema): Schema
|
|||||||
->maxValue(8)
|
->maxValue(8)
|
||||||
->helperText('Semester ke berapa mata kuliah ini diajarkan (1-8).'),
|
->helperText('Semester ke berapa mata kuliah ini diajarkan (1-8).'),
|
||||||
|
|
||||||
Select::make('lecturer_id')
|
TextInput::make('lecturer')
|
||||||
->label('Dosen Pengampu')
|
->label('Dosen Pengampu')
|
||||||
->placeholder('Pilih Dosen')
|
->placeholder('Ujang')
|
||||||
->relationship('lecturer', 'full_name')
|
->maxLength(100)
|
||||||
->preload()
|
->helperText('Masukkan nama dosen yang mengampu mata kuliah ini.')
|
||||||
->searchable()
|
|
||||||
->helperText('Pilih dosen yang mengampu mata kuliah ini.')
|
|
||||||
->required(),
|
->required(),
|
||||||
|
|
||||||
])
|
])
|
||||||
@ -112,8 +111,9 @@ public static function table(Table $table): Table
|
|||||||
->label('SKS')
|
->label('SKS')
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
|
||||||
TextColumn::make('lecturer.full_name')
|
TextColumn::make('lecturer')
|
||||||
->label('Dosen Pengampu')
|
->label('Dosen Pengampu')
|
||||||
|
->placeholder('Belum ditentukan')
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
|
||||||
...TimestampColumns::make(),
|
...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;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
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
|
public function materials(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Material::class);
|
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) {
|
Schema::create('courses', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('lecturer_id')->nullable()->constrained()->nullOnDelete();
|
$table->string('lecturer', 100)->nullable();
|
||||||
$table->string('code', 20)->unique();
|
$table->string('code', 20)->unique();
|
||||||
$table->string('name', 100);
|
$table->string('name', 100);
|
||||||
$table->integer('credit')->default(3);
|
$table->integer('credit')->default(3);
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\Course;
|
use App\Models\Course;
|
||||||
use App\Models\Lecturer;
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class CourseSeeder extends Seeder
|
class CourseSeeder extends Seeder
|
||||||
@ -13,6 +12,17 @@ class CourseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
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 = [
|
$courses = [
|
||||||
// Semester 1
|
// Semester 1
|
||||||
['code' => 'SIU101', 'name' => 'Ilmu Amaliah, Sosial, dan Budaya Dasar', 'credit' => 2, '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],
|
['code' => 'FSI839', 'name' => 'Startup Digital', 'credit' => 2, 'semester' => 8],
|
||||||
];
|
];
|
||||||
|
|
||||||
$lecturers = Lecturer::pluck('id')->toArray();
|
foreach ($courses as &$course) {
|
||||||
|
$course['lecturer'] = $lecturers[array_rand($lecturers)];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Course::insert($courses);
|
Course::insert($courses);
|
||||||
|
|||||||
@ -17,7 +17,6 @@ public function run(): void
|
|||||||
$this->call([
|
$this->call([
|
||||||
ShieldSeeder::class,
|
ShieldSeeder::class,
|
||||||
UserSeeder::class,
|
UserSeeder::class,
|
||||||
LecturerSeeder::class,
|
|
||||||
StudentSeeder::class,
|
StudentSeeder::class,
|
||||||
CourseSeeder::class,
|
CourseSeeder::class,
|
||||||
CourseScheduleSeeder::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",
|
"Replicate:Student",
|
||||||
"Reorder: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",
|
"ViewAny:Course",
|
||||||
"View:Course",
|
"View:Course",
|
||||||
@ -153,8 +142,6 @@ public function run(): void
|
|||||||
"ViewAny:Student",
|
"ViewAny:Student",
|
||||||
"View:Student",
|
"View:Student",
|
||||||
|
|
||||||
"ViewAny:Lecturer",
|
|
||||||
"View:Lecturer",
|
|
||||||
|
|
||||||
"ViewAny:Course",
|
"ViewAny:Course",
|
||||||
"View:Course",
|
"View:Course",
|
||||||
@ -183,9 +170,6 @@ public function run(): void
|
|||||||
"Update:Student",
|
"Update:Student",
|
||||||
"Delete:Student",
|
"Delete:Student",
|
||||||
|
|
||||||
"Create:Lecturer",
|
|
||||||
"Update:Lecturer",
|
|
||||||
"Delete:Lecturer",
|
|
||||||
|
|
||||||
"Create:Course",
|
"Create:Course",
|
||||||
"Update:Course",
|
"Update:Course",
|
||||||
|
|||||||
@ -1,135 +1,138 @@
|
|||||||
<x-filament-panels::page>
|
<x-filament-panels::page>
|
||||||
<x-filament::section>
|
<div>
|
||||||
<div
|
<x-filament::section>
|
||||||
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
|
||||||
<div class="flex items-start gap-3">
|
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">
|
||||||
<x-heroicon-o-information-circle class="w-5 h-5 text-info-600 dark:text-info-400 mt-0.5" />
|
<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">
|
<div class="text-sm text-info-800 dark:text-info-200">
|
||||||
Geser ke samping untuk melihat hari lainnya.
|
Geser ke samping untuk melihat hari lainnya.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center justify-between gap-4 mb-6">
|
<div class="flex items-center justify-between gap-4 mb-6">
|
||||||
<div class="w-full max-w-xl">
|
<div class="w-full max-w-xl">
|
||||||
{{ $this->form }}
|
{{ $this->form }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($schedules->isNotEmpty())
|
@if ($schedules->isNotEmpty())
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<div class="flex flex-nowrap gap-6 min-w-max pb-4">
|
<div class="flex flex-nowrap gap-6 min-w-max pb-4">
|
||||||
|
|
||||||
@foreach ($days as $dayNumber => $dayName)
|
@foreach ($days as $dayNumber => $dayName)
|
||||||
@php
|
@php
|
||||||
$daySchedules = $schedules->get($dayNumber);
|
$daySchedules = $schedules->get($dayNumber);
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@if ($daySchedules && $daySchedules->count() > 0)
|
@if ($daySchedules && $daySchedules->count() > 0)
|
||||||
<section class="w-80 shrink-0 space-y-4">
|
<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">
|
<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" />
|
<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">
|
<h2 class="text-lg font-semibold tracking-tight text-gray-950 dark:text-white">
|
||||||
{{ $dayName }}
|
{{ $dayName }}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
@foreach ($daySchedules as $schedule)
|
@foreach ($daySchedules as $schedule)
|
||||||
<div
|
<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">
|
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="p-5 space-y-4">
|
||||||
<div class="flex items-start justify-between gap-3">
|
<div class="flex items-start justify-between gap-3">
|
||||||
<div class="flex items-center gap-2">
|
<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
|
|
||||||
<span
|
<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">
|
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->mode->getLabel() }}
|
{{ $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>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($schedule->room)
|
<h3
|
||||||
<span
|
class="text-base font-semibold leading-tight text-gray-950 dark:text-white">
|
||||||
class="inline-flex items-center text-xs text-gray-500 dark:text-gray-400">
|
{{ $schedule->course->name ?? 'Mata Kuliah Tidak Diketahui' }}
|
||||||
<x-heroicon-m-map-pin class="w-4 h-4 mr-1 opacity-70" />
|
</h3>
|
||||||
{{ $schedule->room }}
|
|
||||||
|
<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>
|
</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>
|
</div>
|
||||||
|
|
||||||
<span
|
<div class="flex flex-wrap items-center gap-2 mt-1">
|
||||||
class="text-[11px] font-semibold tracking-wide text-gray-400 uppercase">
|
@if ($schedule->course?->semester)
|
||||||
{{ $schedule->course->credit ?? '-' }} SKS
|
<span
|
||||||
</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">
|
||||||
</div>
|
<x-heroicon-m-academic-cap class="w-3 h-3" />
|
||||||
|
Semester {{ $schedule->course->semester }}
|
||||||
@canAny(['Update:CourseSchedule', 'Delete:CourseSchedule'])
|
</span>
|
||||||
<div
|
@endif
|
||||||
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>
|
</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>
|
||||||
</div>
|
@endforeach
|
||||||
@endforeach
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
@endif
|
||||||
@endif
|
@endforeach
|
||||||
@endforeach
|
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endif
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($schedules->isEmpty())
|
@if ($schedules->isEmpty())
|
||||||
<x-filament::empty-state icon="heroicon-o-calendar-days" heading="Tidak ada data yang ditemukan"
|
<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">
|
description="Setelah Anda membuat data pertama, maka akan muncul disini." iconColor="gray">
|
||||||
</x-filament::empty-state>
|
</x-filament::empty-state>
|
||||||
@endif
|
@endif
|
||||||
</x-filament::section>
|
</x-filament::section>
|
||||||
|
</div>
|
||||||
</x-filament-panels::page>
|
</x-filament-panels::page>
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
{{ $session->course->name }}
|
{{ $session->course->name }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-400 mt-0.5 font-medium">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div @class([
|
<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">
|
<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" />
|
<x-heroicon-m-user class="w-4 h-4 mr-1.5 opacity-70" />
|
||||||
<span
|
<span
|
||||||
class="truncate">{{ $course->lecturer->full_name ?? 'Dosen Belum Ditentukan' }}</span>
|
class="truncate">{{ $course->lecturer ?? 'Dosen Belum Ditentukan' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class="w-4 h-4 transition-transform duration-300"
|
|||||||
</h3>
|
</h3>
|
||||||
<div class="flex items-center text-sm text-gray-500 dark:text-gray-400">
|
<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" />
|
<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>
|
</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>
|
<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">
|
<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" />
|
<x-heroicon-o-user class="w-4 h-4 opacity-50" />
|
||||||
{{ $course->lecturer->full_name }}
|
{{ $course->lecturer }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user