feat: Add course schedule model, migration, seeder, and Filament CRUD for managing schedules.
This commit is contained in:
parent
1c51ccd5b5
commit
7a9cb7fed9
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages\Information\CourseSchedule\Actions;
|
||||||
|
|
||||||
|
use App\Filament\Actions\Cheerful\CreateAction;
|
||||||
|
use App\Models\CourseSchedule;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
|
|
||||||
|
class CreateScheduleAction extends CreateAction
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'createSchedule';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->model(CourseSchedule::class)
|
||||||
|
->label('Tambah')
|
||||||
|
->modalHeading('Tambah Jadwal Kuliah')
|
||||||
|
->modalSubmitActionLabel('Simpan')
|
||||||
|
->modalCancelActionLabel('Batal')
|
||||||
|
->extraModalFooterActions(fn (CreateAction $action): array => [
|
||||||
|
$action->makeModalSubmitAction('createAnother', arguments: ['another' => true])
|
||||||
|
->label('Simpan dan Tambah Lagi'),
|
||||||
|
])
|
||||||
|
->modalWidth(Width::Large)
|
||||||
|
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages\Information\CourseSchedule\Actions;
|
||||||
|
|
||||||
|
use App\Filament\Actions\Cheerful\DeleteAction;
|
||||||
|
use App\Models\CourseSchedule;
|
||||||
|
|
||||||
|
class DeleteScheduleAction extends DeleteAction
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'deleteSchedule';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->record(function (array $arguments): CourseSchedule {
|
||||||
|
return CourseSchedule::findOrFail($arguments['schedule']);
|
||||||
|
})
|
||||||
|
->modalHeading('Hapus Jadwal Kuliah')
|
||||||
|
->modalDescription('Apakah Anda yakin ingin menghapus jadwal ini? Tindakan ini tidak dapat dibatalkan.')
|
||||||
|
->modalSubmitActionLabel('Hapus')
|
||||||
|
->modalCancelActionLabel('Batal');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages\Information\CourseSchedule\Actions;
|
||||||
|
|
||||||
|
use App\Filament\Actions\Cheerful\EditAction;
|
||||||
|
use App\Models\CourseSchedule;
|
||||||
|
use Filament\Support\Enums\Width;
|
||||||
|
|
||||||
|
class EditScheduleAction extends EditAction
|
||||||
|
{
|
||||||
|
public static function getDefaultName(): ?string
|
||||||
|
{
|
||||||
|
return 'editSchedule';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->record(function (array $arguments): CourseSchedule {
|
||||||
|
return CourseSchedule::findOrFail($arguments['schedule']);
|
||||||
|
})
|
||||||
|
->modalHeading('Ubah Jadwal Kuliah')
|
||||||
|
->modalSubmitActionLabel('Simpan')
|
||||||
|
->modalCancelActionLabel('Batal')
|
||||||
|
->modalWidth(Width::Large)
|
||||||
|
->schema(fn ($livewire) => $livewire->scheduleFormSchema());
|
||||||
|
}
|
||||||
|
}
|
||||||
217
app/Filament/Pages/Information/CourseSchedule/Index.php
Normal file
217
app/Filament/Pages/Information/CourseSchedule/Index.php
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages\Information\CourseSchedule;
|
||||||
|
|
||||||
|
use App\Filament\Pages\Information\CourseSchedule\Actions\CreateScheduleAction;
|
||||||
|
use App\Filament\Pages\Information\CourseSchedule\Actions\DeleteScheduleAction;
|
||||||
|
use App\Filament\Pages\Information\CourseSchedule\Actions\EditScheduleAction;
|
||||||
|
use App\Models\Course;
|
||||||
|
use App\Models\CourseSchedule;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Actions\Concerns\InteractsWithActions;
|
||||||
|
use Filament\Actions\Contracts\HasActions;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\TimePicker;
|
||||||
|
use Filament\Forms\Concerns\InteractsWithForms;
|
||||||
|
use Filament\Forms\Contracts\HasForms;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Schemas\Components\Grid;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use UnitEnum;
|
||||||
|
|
||||||
|
class Index extends Page implements HasActions, HasForms
|
||||||
|
{
|
||||||
|
use InteractsWithActions, InteractsWithForms;
|
||||||
|
|
||||||
|
protected static ?string $model = CourseSchedule::class;
|
||||||
|
|
||||||
|
protected static string|UnitEnum|null $navigationGroup = 'Informasi';
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCalendarDays;
|
||||||
|
|
||||||
|
protected static ?string $title = 'Jadwal Kuliah';
|
||||||
|
|
||||||
|
protected static ?int $navigationSort = 1;
|
||||||
|
|
||||||
|
protected static ?string $recordTitleAttribute = 'day_of_week';
|
||||||
|
|
||||||
|
protected static ?string $slug = 'information/course-schedules';
|
||||||
|
|
||||||
|
protected string $view = 'filament.pages.information.list-course-schedules';
|
||||||
|
|
||||||
|
public ?int $course_semester = null;
|
||||||
|
|
||||||
|
public ?string $search = '';
|
||||||
|
|
||||||
|
public static function getPagePermission(): string
|
||||||
|
{
|
||||||
|
return 'View:CourseSchedule';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->course_semester = null;
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'course_semester' => $this->course_semester,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->schema([
|
||||||
|
Select::make('course_semester')
|
||||||
|
->label('Semester')
|
||||||
|
->options(array_combine(range(1, 8), array_map(fn ($i) => "Semester $i", range(1, 8))))
|
||||||
|
->native(false)
|
||||||
|
->live()
|
||||||
|
->afterStateUpdated(fn ($state) => $this->course_semester = $state),
|
||||||
|
|
||||||
|
TextInput::make('search')
|
||||||
|
->label('Cari')
|
||||||
|
->placeholder('Cari Mata Kuliah atau Dosen...')
|
||||||
|
->autocomplete(false)
|
||||||
|
->live(debounce: 500)
|
||||||
|
->afterStateUpdated(fn ($state) => $this->search = $state),
|
||||||
|
])
|
||||||
|
->columns([
|
||||||
|
'sm' => 1,
|
||||||
|
'md' => 3,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
CreateScheduleAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function editScheduleAction(): Action
|
||||||
|
{
|
||||||
|
return EditScheduleAction::make();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function deleteScheduleAction(): Action
|
||||||
|
{
|
||||||
|
return DeleteScheduleAction::make();
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->course_semester) {
|
||||||
|
$query->whereHas('course', fn ($q) => $q->where('semester', $this->course_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}%"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->get()
|
||||||
|
->sortBy([
|
||||||
|
['day_of_week', 'asc'],
|
||||||
|
['start_time', 'asc'],
|
||||||
|
])
|
||||||
|
->groupBy('day_of_week');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getViewData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'schedules' => $this->getSchedules(),
|
||||||
|
'days' => [
|
||||||
|
1 => 'Senin',
|
||||||
|
2 => 'Selasa',
|
||||||
|
3 => 'Rabu',
|
||||||
|
4 => 'Kamis',
|
||||||
|
5 => 'Jumat',
|
||||||
|
6 => 'Sabtu',
|
||||||
|
7 => 'Minggu',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scheduleFormSchema(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Grid::make(2)
|
||||||
|
->schema([
|
||||||
|
Select::make('course_id')
|
||||||
|
->label('Mata Kuliah')
|
||||||
|
->options(function () {
|
||||||
|
$user = auth()->user();
|
||||||
|
$lecturer = $user->lecturer;
|
||||||
|
|
||||||
|
if ($lecturer) {
|
||||||
|
$courses = Course::getOptionsForLecturer($lecturer);
|
||||||
|
} else {
|
||||||
|
$courses = Course::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $courses
|
||||||
|
->groupBy('semester')
|
||||||
|
->mapWithKeys(function ($courses, $semester) {
|
||||||
|
return [
|
||||||
|
"Semester $semester" => $courses->pluck('name', 'id')->toArray(),
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
})
|
||||||
|
->searchable()
|
||||||
|
->live()
|
||||||
|
->required()
|
||||||
|
->columnSpanFull(),
|
||||||
|
|
||||||
|
Grid::make(3)
|
||||||
|
->schema([
|
||||||
|
Select::make('day_of_week')
|
||||||
|
->label('Hari')
|
||||||
|
->placeholder('Pilih Hari')
|
||||||
|
->options([
|
||||||
|
1 => 'Senin',
|
||||||
|
2 => 'Selasa',
|
||||||
|
3 => 'Rabu',
|
||||||
|
4 => 'Kamis',
|
||||||
|
5 => 'Jumat',
|
||||||
|
6 => 'Sabtu',
|
||||||
|
7 => 'Minggu',
|
||||||
|
])
|
||||||
|
->native(false)
|
||||||
|
->required(),
|
||||||
|
|
||||||
|
TimePicker::make('start_time')
|
||||||
|
->label('Jam Mulai')
|
||||||
|
->placeholder('08:00')
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->seconds(false),
|
||||||
|
|
||||||
|
TimePicker::make('end_time')
|
||||||
|
->label('Jam Selesai')
|
||||||
|
->placeholder('10:00')
|
||||||
|
->required()
|
||||||
|
->native(false)
|
||||||
|
->seconds(false),
|
||||||
|
])
|
||||||
|
->columnSpanFull(),
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
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\BelongsTo;
|
||||||
@ -17,4 +18,11 @@ public function lecturer(): BelongsTo
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Lecturer::class);
|
return $this->belongsTo(Lecturer::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getOptionsForLecturer(Lecturer $lecturer): Collection
|
||||||
|
{
|
||||||
|
return static::query()
|
||||||
|
->where('lecturer_id', $lecturer->id)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
app/Models/CourseSchedule.php
Normal file
28
app/Models/CourseSchedule.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class CourseSchedule extends Model
|
||||||
|
{
|
||||||
|
use HasFactory, SoftDeletes;
|
||||||
|
|
||||||
|
protected $guarded = ['id'];
|
||||||
|
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'end_time' => 'datetime:H:i',
|
||||||
|
'start_time' => 'datetime:H:i',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function course(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Course::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
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('course_schedules', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('course_id')->constrained()->cascadeOnDelete();
|
||||||
|
$table->integer('day_of_week');
|
||||||
|
$table->time('start_time');
|
||||||
|
$table->time('end_time');
|
||||||
|
$table->timestamp('created_at')->useCurrent();
|
||||||
|
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->index('course_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('course_schedules');
|
||||||
|
}
|
||||||
|
};
|
||||||
34
database/seeders/CourseScheduleSeeder.php
Normal file
34
database/seeders/CourseScheduleSeeder.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\Course;
|
||||||
|
use App\Models\CourseSchedule;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class CourseScheduleSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$courses = Course::all();
|
||||||
|
|
||||||
|
$timeSlots = [
|
||||||
|
['08:00:00', '10:00:00'],
|
||||||
|
['10:00:00', '12:00:00'],
|
||||||
|
['13:00:00', '15:00:00'],
|
||||||
|
['15:00:00', '17:00:00'],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($courses as $course) {
|
||||||
|
|
||||||
|
$slot = $timeSlots[array_rand($timeSlots)];
|
||||||
|
|
||||||
|
CourseSchedule::create([
|
||||||
|
'course_id' => $course->id,
|
||||||
|
'day_of_week' => rand(1, 6),
|
||||||
|
'start_time' => $slot[0],
|
||||||
|
'end_time' => $slot[1],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
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
|
||||||
@ -83,6 +84,33 @@ 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();
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ public function run(): void
|
|||||||
UserSeeder::class,
|
UserSeeder::class,
|
||||||
LecturerSeeder::class,
|
LecturerSeeder::class,
|
||||||
CourseSeeder::class,
|
CourseSeeder::class,
|
||||||
|
CourseScheduleSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,140 @@
|
|||||||
|
<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 class="text-sm text-info-800 dark:text-info-200">
|
||||||
|
Geser ke samping untuk melihat hari lainnya.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between gap-4 mb-6">
|
||||||
|
<div class="w-full">
|
||||||
|
{{ $this->form }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
@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="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
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-end gap-1 pt-3 border-t border-gray-100 dark:border-gray-800">
|
||||||
|
<x-filament::button size="xs" color="warning" tooltip="Ubah"
|
||||||
|
variant="primary"
|
||||||
|
wire:click="mountAction('editSchedule', { schedule: {{ $schedule->id }} })">
|
||||||
|
<x-heroicon-m-pencil-square class="w-4 h-4" />
|
||||||
|
</x-filament::button>
|
||||||
|
|
||||||
|
<x-filament::button size="xs" color="danger" tooltip="Hapus"
|
||||||
|
wire:click="mountAction('deleteSchedule', { schedule: {{ $schedule->id }} })">
|
||||||
|
<x-heroicon-m-trash class="w-4 h-4" />
|
||||||
|
</x-filament::button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@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>
|
||||||
|
</x-filament-panels::page>
|
||||||
Loading…
Reference in New Issue
Block a user