feat: add Course management functionality with CRUD operations and UI integration
Some checks failed
tests / ci (pull_request) Has been cancelled
Some checks failed
tests / ci (pull_request) Has been cancelled
This commit is contained in:
parent
1fe2b30156
commit
a6d1fa2cf7
@ -7,8 +7,8 @@
|
||||
use App\Http\Requests\PaginatedRequest;
|
||||
use App\Models\CourseClass;
|
||||
use App\Services\Admin\Manage\CourseClassService;
|
||||
use App\Services\Admin\Manage\CourseService;
|
||||
use App\Services\Admin\Master\AcademicTermService;
|
||||
use App\Services\Admin\Master\CourseService;
|
||||
use App\Services\Admin\Users\LecturerService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Manage;
|
||||
namespace App\Http\Controllers\Admin\Master;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Manage\CourseRequest;
|
||||
use App\Http\Requests\Admin\Master\CourseRequest;
|
||||
use App\Http\Requests\PaginatedRequest;
|
||||
use App\Models\Course;
|
||||
use App\Services\Admin\Manage\CourseService;
|
||||
use App\Services\Admin\Master\CourseService;
|
||||
use App\Services\Admin\Master\DepartmentService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
@ -21,13 +21,15 @@ public function __construct(
|
||||
|
||||
public function index(PaginatedRequest $request): Response
|
||||
{
|
||||
return Inertia::render('admin/manage/courses/index', [
|
||||
return Inertia::render('admin/master/courses/index', [
|
||||
'courses' => $this->service->paginated(
|
||||
...$request->validatedWithDefaults(),
|
||||
departmentId: $request->validated('department_id'),
|
||||
semesterNumber: $request->validated('semester_number'),
|
||||
),
|
||||
'departments' => $this->departmentService->getAllForSelect(),
|
||||
'filters' => $request->only(['department_id']),
|
||||
'semesterNumbers' => $this->service->getSemesterNumbers(),
|
||||
'filters' => $request->only(['department_id', 'semester_number']),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -37,7 +39,7 @@ public function store(CourseRequest $request): RedirectResponse
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Mata kuliah berhasil ditambahkan.']);
|
||||
|
||||
return to_route('admin.manage.courses.index');
|
||||
return to_route('admin.master.courses.index');
|
||||
}
|
||||
|
||||
public function update(CourseRequest $request, Course $course): RedirectResponse
|
||||
@ -46,7 +48,7 @@ public function update(CourseRequest $request, Course $course): RedirectResponse
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Mata kuliah berhasil diperbarui.']);
|
||||
|
||||
return to_route('admin.manage.courses.index');
|
||||
return to_route('admin.master.courses.index');
|
||||
}
|
||||
|
||||
public function destroy(Course $course): RedirectResponse
|
||||
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin\Manage;
|
||||
namespace App\Http\Requests\Admin\Master;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
@ -25,6 +25,7 @@ public function rules(): array
|
||||
'department_id' => ['nullable', 'integer'],
|
||||
'status' => ['nullable', 'string'],
|
||||
'enrollment_year' => ['nullable', 'integer'],
|
||||
'semester_number' => ['nullable', 'integer'],
|
||||
'semester' => ['nullable', 'string', Rule::in(Semester::values())],
|
||||
'is_active' => ['nullable', Rule::in(['true', 'false'])],
|
||||
'academic_term_id' => ['nullable', 'integer'],
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Admin\Manage;
|
||||
namespace App\Services\Admin\Master;
|
||||
|
||||
use App\Models\Course;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
@ -13,13 +13,25 @@ public function getAllForSelect(): Collection
|
||||
return Course::select(['id', 'code', 'name', 'department_id'])->get();
|
||||
}
|
||||
|
||||
public function paginated(int $perPage = 25, string $search = '', ?int $departmentId = null): LengthAwarePaginator
|
||||
public function getSemesterNumbers(): array
|
||||
{
|
||||
return Course::query()
|
||||
->select('semester_number')
|
||||
->whereNotNull('semester_number')
|
||||
->distinct()
|
||||
->orderBy('semester_number')
|
||||
->pluck('semester_number')
|
||||
->all();
|
||||
}
|
||||
|
||||
public function paginated(int $perPage = 25, string $search = '', ?int $departmentId = null, ?int $semesterNumber = null): LengthAwarePaginator
|
||||
{
|
||||
return Course::query()
|
||||
->select(['id', 'code', 'name', 'credits', 'department_id', 'semester_number'])
|
||||
->with('department:id,name')
|
||||
->when($search, fn ($q) => $q->where('name', 'like', "%{$search}%")->orWhere('code', 'like', "%{$search}%"))
|
||||
->when($departmentId, fn ($q) => $q->where('department_id', $departmentId))
|
||||
->when($semesterNumber, fn ($q) => $q->where('semester_number', $semesterNumber))
|
||||
->latest()
|
||||
->paginate($perPage);
|
||||
}
|
||||
@ -1,10 +1,6 @@
|
||||
import { usePage } from '@inertiajs/react';
|
||||
import type { Icon } from '@tabler/icons-react';
|
||||
import {
|
||||
IconGridDots,
|
||||
IconHelp,
|
||||
IconMessageDots
|
||||
} from '@tabler/icons-react';
|
||||
import { IconGridDots, IconHelp, IconMessageDots } from '@tabler/icons-react';
|
||||
import {
|
||||
BookOpen,
|
||||
Building2,
|
||||
@ -49,8 +45,8 @@ import { index as announcementsRoute } from '@/routes/admin/announcements';
|
||||
import { index as feedbackRoute } from '@/routes/admin/feedback';
|
||||
import { index as tuitionInvoicesRoute } from '@/routes/admin/finances/tuition-invoices';
|
||||
import { index as courseClassesRoute } from '@/routes/admin/manage/course-classes';
|
||||
import { index as coursesRoute } from '@/routes/admin/manage/courses';
|
||||
import { index as academicTerm } from '@/routes/admin/master/academic-terms';
|
||||
import { index as coursesRoute } from '@/routes/admin/master/courses';
|
||||
import { index as departmentsRoute } from '@/routes/admin/master/departments';
|
||||
import { index as academicAdvisingLogsRoute } from '@/routes/admin/services/academic-advising-logs';
|
||||
import { index as letterRequestsRoute } from '@/routes/admin/services/letter-requests';
|
||||
@ -104,6 +100,11 @@ const data: {
|
||||
url: departmentsRoute.url(),
|
||||
icon: Building2,
|
||||
},
|
||||
{
|
||||
name: 'Mata Kuliah',
|
||||
url: coursesRoute.url(),
|
||||
icon: BookOpen,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -139,11 +140,6 @@ const data: {
|
||||
{
|
||||
label: 'Kelola',
|
||||
items: [
|
||||
{
|
||||
name: 'Mata Kuliah',
|
||||
url: coursesRoute.url(),
|
||||
icon: BookOpen,
|
||||
},
|
||||
{
|
||||
name: 'Kelas Mata Kuliah',
|
||||
url: courseClassesRoute.url(),
|
||||
|
||||
@ -25,7 +25,7 @@ import {
|
||||
destroy,
|
||||
store,
|
||||
update,
|
||||
} from '@/routes/admin/manage/courses';
|
||||
} from '@/routes/admin/master/courses';
|
||||
import type { Course } from '@/types/course';
|
||||
import { formatDepartmentLabel } from '@/types/department';
|
||||
import { createCourseColumns } from './columns';
|
||||
@ -41,15 +41,18 @@ type Props = {
|
||||
total: number;
|
||||
};
|
||||
departments: Department[];
|
||||
semesterNumbers: number[];
|
||||
highlight?: number;
|
||||
filters: {
|
||||
department_id?: string;
|
||||
semester_number?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export default function CourseIndex({
|
||||
courses,
|
||||
departments,
|
||||
semesterNumbers,
|
||||
highlight,
|
||||
filters,
|
||||
}: Props) {
|
||||
@ -66,6 +69,14 @@ export default function CourseIndex({
|
||||
label: formatDepartmentLabel(department),
|
||||
})),
|
||||
},
|
||||
{
|
||||
key: 'semester_number',
|
||||
label: 'Semester',
|
||||
options: semesterNumbers.map((semester) => ({
|
||||
value: String(semester),
|
||||
label: String(semester),
|
||||
})),
|
||||
},
|
||||
];
|
||||
|
||||
const pagination: PaginationState = {
|
||||
@ -12,8 +12,8 @@
|
||||
use App\Http\Controllers\Admin\Finances\TuitionPaymentController;
|
||||
use App\Http\Controllers\Admin\Manage\ClassEnrollmentController;
|
||||
use App\Http\Controllers\Admin\Manage\CourseClassController;
|
||||
use App\Http\Controllers\Admin\Manage\CourseController;
|
||||
use App\Http\Controllers\Admin\Master\AcademicTermController;
|
||||
use App\Http\Controllers\Admin\Master\CourseController;
|
||||
use App\Http\Controllers\Admin\Master\DepartmentController;
|
||||
use App\Http\Controllers\Admin\Services\AcademicAdvisingLogController;
|
||||
use App\Http\Controllers\Admin\Services\LetterRequestController;
|
||||
@ -29,6 +29,7 @@
|
||||
Route::resource('academic-terms', AcademicTermController::class)->except(['create', 'edit', 'show']);
|
||||
Route::patch('academic-terms/{academic_term}/status', [AcademicTermController::class, 'updateStatus'])->name('academic-terms.update_status');
|
||||
Route::resource('departments', DepartmentController::class)->except(['create', 'edit', 'show']);
|
||||
Route::resource('courses', CourseController::class)->except(['create', 'edit', 'show']);
|
||||
});
|
||||
|
||||
Route::prefix('admin/academic-classes')->name('admin.academic-classes.')->group(function () {
|
||||
@ -62,7 +63,6 @@
|
||||
});
|
||||
|
||||
Route::prefix('admin/manage')->name('admin.manage.')->group(function () {
|
||||
Route::resource('courses', CourseController::class)->except(['create', 'edit', 'show']);
|
||||
Route::resource('course-classes', CourseClassController::class)->except(['create', 'edit', 'show']);
|
||||
|
||||
Route::prefix('course-classes/{course_class}/enrollments')->name('course-classes.enrollments.')->group(function () {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user