From 6dab533b2165c65955f5831723bc48bbb09cfe06 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Tue, 10 Mar 2026 12:24:31 +0700 Subject: [PATCH] feat: Create Course resource with CRUD functionality, including management pages, form schema, migration, and seeder for handling course data in the admin panel. --- .../Master/Courses/CourseResource.php | 153 ++++++++++++++++++ .../Master/Courses/Pages/ManageCourses.php | 31 ++++ app/Models/Course.php | 14 ++ ...2026_02_25_024503_create_courses_table.php | 33 ++++ database/seeders/CourseSeeder.php | 88 ++++++++++ database/seeders/DatabaseSeeder.php | 1 + 6 files changed, 320 insertions(+) create mode 100644 app/Filament/Resources/Master/Courses/CourseResource.php create mode 100644 app/Filament/Resources/Master/Courses/Pages/ManageCourses.php create mode 100644 app/Models/Course.php create mode 100644 database/migrations/2026_02_25_024503_create_courses_table.php create mode 100644 database/seeders/CourseSeeder.php diff --git a/app/Filament/Resources/Master/Courses/CourseResource.php b/app/Filament/Resources/Master/Courses/CourseResource.php new file mode 100644 index 0000000..c8ce288 --- /dev/null +++ b/app/Filament/Resources/Master/Courses/CourseResource.php @@ -0,0 +1,153 @@ +components([ + TextInput::make('code') + ->label('Kode') + ->placeholder('FSI419') + ->autocomplete(false) + ->autofocus() + ->required() + ->maxLength(20) + ->unique(ignoreRecord: true), + + TextInput::make('name') + ->label('Nama') + ->placeholder('Sistem Pendukung Keputusan') + ->autocomplete(false) + ->required() + ->maxLength(100), + + TextInput::make('credit') + ->label('SKS') + ->placeholder('2') + ->autocomplete(false) + ->required() + ->numeric() + ->minValue(1) + ->maxValue(6), + + TextInput::make('semester') + ->label('Semester') + ->placeholder('3') + ->autocomplete(false) + ->required() + ->numeric() + ->minValue(1) + ->maxValue(8) + ->helperText('Semester ke berapa mata kuliah ini diajarkan (1-8).'), + + ]) + ->columns(1); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + TextColumn::make('name') + ->label('Nama') + ->searchable(query: function (Builder $query, string $search) { + $query->where('name', 'like', "%{$search}%") + ->orWhere('code', 'like', "%{$search}%"); + }) + ->sortable() + ->description(fn (Course $course) => $course->code), + + TextColumn::make('credit') + ->label('SKS') + ->sortable(), + + ...TimestampColumns::make(), + ]) + ->filters([ + TrashedFilter::make() + ->native(false), + ]) + ->recordActions([ + EditAction::make() + ->modalWidth(Width::Large), + + DeleteAction::make(), + + ForceDeleteAction::make(), + + RestoreAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + ...DefaultBulkActions::make('Mata Kuliah'), + ]), + ]) + ->emptyStateIcon(Heroicon::OutlinedRectangleStack) + ->emptyStateDescription('Setelah Anda membuat data pertama, maka akan muncul disini.') + ->defaultSort('code', 'desc') + ->defaultGroup('semester') + ->groups([ + Group::make('semester') + ->label('Semester') + ->getTitleFromRecordUsing(fn (Course $record): string => 'Semester '.$record->semester) + ->collapsible(), + ]) + ->deferFilters(false) + ->paginated(false); + } + + public static function getPages(): array + { + return [ + 'index' => ManageCourses::route('/'), + ]; + } + + public static function getRecordRouteBindingEloquentQuery(): Builder + { + return parent::getRecordRouteBindingEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/Master/Courses/Pages/ManageCourses.php b/app/Filament/Resources/Master/Courses/Pages/ManageCourses.php new file mode 100644 index 0000000..c811bcd --- /dev/null +++ b/app/Filament/Resources/Master/Courses/Pages/ManageCourses.php @@ -0,0 +1,31 @@ +label('Tambah') + ->modalHeading('Tambah Mata Kuliah') + ->modalSubmitActionLabel('Simpan') + ->modalCancelActionLabel('Batal') + ->extraModalFooterActions(fn (CreateAction $action): array => [ + $action->makeModalSubmitAction('createAnother', arguments: ['another' => true]) + ->label('Simpan dan Tambah Lagi'), + ]) + ->modalWidth(Width::Large), + ]; + } +} diff --git a/app/Models/Course.php b/app/Models/Course.php new file mode 100644 index 0000000..be95d7c --- /dev/null +++ b/app/Models/Course.php @@ -0,0 +1,14 @@ +id(); + $table->string('code', 20)->unique(); + $table->string('name', 100); + $table->integer('credit')->default(3); + $table->unsignedInteger('semester')->default(1); + $table->timestamp('created_at')->useCurrent(); + $table->timestamp('updated_at')->nullable()->useCurrentOnUpdate(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('courses'); + } +}; diff --git a/database/seeders/CourseSeeder.php b/database/seeders/CourseSeeder.php new file mode 100644 index 0000000..714d9d4 --- /dev/null +++ b/database/seeders/CourseSeeder.php @@ -0,0 +1,88 @@ + 'SIU101', 'name' => 'Ilmu Amaliah, Sosial, dan Budaya Dasar', 'credit' => 2, 'semester' => 1], + ['code' => 'SIM101', 'name' => 'Keaswajaan', 'credit' => 2, 'semester' => 1], + ['code' => 'SIM102', 'name' => 'Ilmu Fiqih I', 'credit' => 2, 'semester' => 1], + ['code' => 'SIU102', 'name' => 'Pendidikan Anti Korupsi', 'credit' => 2, 'semester' => 1], + ['code' => 'SIU103', 'name' => 'Bahasa Inggris I', 'credit' => 2, 'semester' => 1], + ['code' => 'SIU104', 'name' => 'Bahasa Indonesia', 'credit' => 2, 'semester' => 1], + ['code' => 'SIU105', 'name' => 'Kewarganegaraan', 'credit' => 2, 'semester' => 1], + ['code' => 'FSI101', 'name' => 'Konsep Basis Data', 'credit' => 2, 'semester' => 1], + ['code' => 'FSI102', 'name' => 'Konsep Sistem Informasi', 'credit' => 2, 'semester' => 1], + ['code' => 'FSI103', 'name' => 'Dasar Pemrograman', 'credit' => 2, 'semester' => 1], + + // Semester 2 + ['code' => 'SIM203', 'name' => 'Ilmu Fiqih II', 'credit' => 2, 'semester' => 2], + ['code' => 'FSI204', 'name' => 'Statistika dan Probabilitas', 'credit' => 2, 'semester' => 2], + ['code' => 'SIU206', 'name' => 'Bahasa Inggris II', 'credit' => 2, 'semester' => 2], + ['code' => 'SIU207', 'name' => 'Pendidikan Agama', 'credit' => 2, 'semester' => 2], + ['code' => 'SIU208', 'name' => 'Pendidikan Pancasila', 'credit' => 2, 'semester' => 2], + ['code' => 'FSI205', 'name' => 'Financial Technology', 'credit' => 3, 'semester' => 2], + ['code' => 'FSI206', 'name' => 'Sistem Basis Data', 'credit' => 2, 'semester' => 2], + ['code' => 'FSI207', 'name' => 'Computational Thinking', 'credit' => 2, 'semester' => 2], + ['code' => 'FSI208', 'name' => 'Pemrograman Berbasis Web', 'credit' => 3, 'semester' => 2], + ['code' => 'FSI209', 'name' => 'Pengantar Teknologi Informasi', 'credit' => 2, 'semester' => 2], + + // Semester 3 + ['code' => 'FSI310', 'name' => 'Transformasi Digital', 'credit' => 2, 'semester' => 3], + ['code' => 'FSI311', 'name' => 'Analisis dan Perancangan Sistem Informasi', 'credit' => 3, 'semester' => 3], + ['code' => 'FSI312', 'name' => 'Sistem Informasi Manajemen', 'credit' => 3, 'semester' => 3], + ['code' => 'FSI313', 'name' => 'Business Intelligence', 'credit' => 2, 'semester' => 3], + ['code' => 'FSI314', 'name' => 'Technopreneurship', 'credit' => 3, 'semester' => 3], + ['code' => 'FSI315', 'name' => 'Matematika Diskrit', 'credit' => 3, 'semester' => 3], + ['code' => 'FSI316', 'name' => 'Interaksi Manusia Komputer', 'credit' => 2, 'semester' => 3], + ['code' => 'FSI317', 'name' => 'Communication Skill', 'credit' => 2, 'semester' => 3], + ['code' => 'FSI318', 'name' => 'Tata Kelola Teknologi Informasi', 'credit' => 2, 'semester' => 3], + + // Semester 4 + ['code' => 'FSI419', 'name' => 'Sistem Pendukung Keputusan', 'credit' => 2, 'semester' => 4], + ['code' => 'FSI420', 'name' => 'Pemrograman Berorientasi Object', 'credit' => 3, 'semester' => 4], + ['code' => 'FSI421', 'name' => 'Manajemen Projek Sistem Informasi', 'credit' => 3, 'semester' => 4], + ['code' => 'FSI422', 'name' => 'Sistem Operasi', 'credit' => 3, 'semester' => 4], + ['code' => 'FSI423', 'name' => 'UI/UX', 'credit' => 3, 'semester' => 4], + ['code' => 'FSI424', 'name' => 'Etika Profesi dan Profesional', 'credit' => 2, 'semester' => 4], + ['code' => 'FSI425', 'name' => 'Jaringan Komputer', 'credit' => 3, 'semester' => 4], + ['code' => 'FSI426', 'name' => 'Arsitektur Enterprise', 'credit' => 2, 'semester' => 4], + + // Semester 5 + ['code' => 'FSI527', 'name' => 'Software Testing dan Quality Assurance', 'credit' => 2, 'semester' => 5], + ['code' => 'FSI528', 'name' => 'Proyek Perangkat Lunak', 'credit' => 3, 'semester' => 5], + ['code' => 'FSI529', 'name' => 'Metodologi Penelitian dan Penulisan Ilmiah', 'credit' => 3, 'semester' => 5], + ['code' => 'FSI530', 'name' => 'Pemrograman Aplikasi Bergerak', 'credit' => 3, 'semester' => 5], + ['code' => 'FSI531', 'name' => 'Big Data', 'credit' => 3, 'semester' => 5], + ['code' => 'FSI532', 'name' => 'Pemrograman IoT', 'credit' => 3, 'semester' => 5], + + // Semester 6 + ['code' => 'FSI633', 'name' => 'Manajemen Proses Bisnis', 'credit' => 2, 'semester' => 6], + ['code' => 'FSI634', 'name' => 'Pemrograman Aplikasi Bergerak 2', 'credit' => 3, 'semester' => 6], + ['code' => 'FSI635', 'name' => 'Fundamental ERP', 'credit' => 3, 'semester' => 6], + ['code' => 'FSI636', 'name' => 'Audit Sistem Informasi', 'credit' => 3, 'semester' => 6], + ['code' => 'FSI637', 'name' => 'Keamanan Jaringan', 'credit' => 2, 'semester' => 6], + ['code' => 'FSI638', 'name' => 'Keamanan Sistem Informasi', 'credit' => 3, 'semester' => 6], + + // Semester 7 + ['code' => 'MBKM701', 'name' => 'Pertukaran Pelajar', 'credit' => 20, 'semester' => 7], + ['code' => 'SIU709', 'name' => 'Skripsi I', 'credit' => 2, 'semester' => 7], + + // Semester 8 + ['code' => 'SIU810', 'name' => 'Skripsi II', 'credit' => 4, 'semester' => 8], + ['code' => 'FSI839', 'name' => 'Startup Digital', 'credit' => 2, 'semester' => 8], + ]; + + Course::insert($courses); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index b9c7377..8df0f25 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -16,6 +16,7 @@ public function run(): void { $this->call([ UserSeeder::class, + CourseSeeder::class, ]); } }