feat: enhance department handling by adding degree level and formatting labels
Some checks failed
tests / ci (pull_request) Has been cancelled

This commit is contained in:
Yoga Pangestu 2026-08-30 12:35:22 +07:00
parent 71439aab4d
commit 8e2f2da5fc
12 changed files with 69 additions and 35 deletions

View File

@ -10,7 +10,7 @@ class DepartmentService
{ {
public function getAllForSelect(): Collection public function getAllForSelect(): Collection
{ {
return Department::select(['id', 'code', 'name'])->get(); return Department::select(['id', 'code', 'name', 'degree_level'])->get();
} }
public function paginated(int $perPage = 25, string $search = ''): LengthAwarePaginator public function paginated(int $perPage = 25, string $search = ''): LengthAwarePaginator

View File

@ -11,21 +11,21 @@ public function run(): void
{ {
Department::insert([ Department::insert([
[ [
'code' => 'SI', 'code' => 'SI-S1',
'name' => 'Sistem Informasi', 'name' => 'Sistem Informasi',
'degree_level' => 'S1', 'degree_level' => 'S1',
'created_at' => now(), 'created_at' => now(),
'updated_at' => now(), 'updated_at' => now(),
], ],
[ [
'code' => 'TI', 'code' => 'TI-S1',
'name' => 'Teknik Industri', 'name' => 'Teknik Industri',
'degree_level' => 'S1', 'degree_level' => 'S1',
'created_at' => now(), 'created_at' => now(),
'updated_at' => now(), 'updated_at' => now(),
], ],
[ [
'code' => 'BD', 'code' => 'BD-S1',
'name' => 'Bisnis Digital', 'name' => 'Bisnis Digital',
'degree_level' => 'S1', 'degree_level' => 'S1',
'created_at' => now(), 'created_at' => now(),

View File

@ -31,6 +31,7 @@ import type {
Announcement, Announcement,
AnnouncementDepartment, AnnouncementDepartment,
} from '@/types/announcement'; } from '@/types/announcement';
import { formatDepartmentLabel } from '@/types/department';
import { createAnnouncementColumns } from './columns'; import { createAnnouncementColumns } from './columns';
type Props = { type Props = {
@ -64,7 +65,7 @@ export default function AnnouncementIndex({
label: 'Jurusan', label: 'Jurusan',
options: departments.map((department) => ({ options: departments.map((department) => ({
value: String(department.id), value: String(department.id),
label: department.name, label: formatDepartmentLabel(department),
})), })),
}, },
]; ];
@ -255,7 +256,7 @@ function AnnouncementFields({
key={department.id} key={department.id}
value={String(department.id)} value={String(department.id)}
> >
{department.name} {formatDepartmentLabel(department)}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@ -27,9 +27,10 @@ import {
update, update,
} from '@/routes/admin/manage/courses'; } from '@/routes/admin/manage/courses';
import type { Course } from '@/types/course'; import type { Course } from '@/types/course';
import { formatDepartmentLabel } from '@/types/department';
import { createCourseColumns } from './columns'; import { createCourseColumns } from './columns';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type Props = { type Props = {
courses: { courses: {
@ -62,7 +63,7 @@ export default function CourseIndex({
label: 'Jurusan', label: 'Jurusan',
options: departments.map((department) => ({ options: departments.map((department) => ({
value: String(department.id), value: String(department.id),
label: department.name, label: formatDepartmentLabel(department),
})), })),
}, },
]; ];
@ -256,7 +257,7 @@ function CreateForm({
key={dept.id} key={dept.id}
value={String(dept.id)} value={String(dept.id)}
> >
{dept.name} {formatDepartmentLabel(dept)}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>
@ -362,7 +363,7 @@ function EditForm({
key={dept.id} key={dept.id}
value={String(dept.id)} value={String(dept.id)}
> >
{dept.name} {formatDepartmentLabel(dept)}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@ -24,8 +24,9 @@ import { PhoneInput } from '@/components/ui/phone-input';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { index, store } from '@/routes/admin/users/lecturers'; import { index, store } from '@/routes/admin/users/lecturers';
import { formatDepartmentLabel } from '@/types/department';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type Props = { type Props = {
departments: Department[]; departments: Department[];
@ -283,8 +284,8 @@ export default function LecturerCreate({ departments }: Props) {
onValueChange={ onValueChange={
setSelectedDepartments setSelectedDepartments
} }
itemToStringLabel={(dept) => itemToStringLabel={
dept.name formatDepartmentLabel
} }
isItemEqualToValue={(a, b) => isItemEqualToValue={(a, b) =>
a.id === b.id a.id === b.id
@ -297,11 +298,13 @@ export default function LecturerCreate({ departments }: Props) {
(dept) => ( (dept) => (
<ComboboxChip <ComboboxChip
key={dept.id} key={dept.id}
aria-label={ aria-label={formatDepartmentLabel(
dept.name dept,
} )}
> >
{dept.name} {formatDepartmentLabel(
dept,
)}
</ComboboxChip> </ComboboxChip>
), ),
)} )}
@ -326,7 +329,9 @@ export default function LecturerCreate({ departments }: Props) {
key={dept.id} key={dept.id}
value={dept} value={dept}
> >
{dept.name} {formatDepartmentLabel(
dept,
)}
</ComboboxItem> </ComboboxItem>
))} ))}
</ComboboxList> </ComboboxList>

View File

@ -24,8 +24,9 @@ import { PhoneInput } from '@/components/ui/phone-input';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { index, update } from '@/routes/admin/users/lecturers'; import { index, update } from '@/routes/admin/users/lecturers';
import { formatDepartmentLabel } from '@/types/department';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type User = { type User = {
id: number; id: number;
@ -41,7 +42,11 @@ type User = {
} | null; } | null;
lecturer: { lecturer: {
lecturer_number: string; lecturer_number: string;
departments: { id: number; name: string }[]; departments: {
id: number;
name: string;
degree_level: string | null;
}[];
} | null; } | null;
}; };
@ -318,8 +323,8 @@ export default function LecturerEdit({ user, departments }: Props) {
onValueChange={ onValueChange={
setSelectedDepartments setSelectedDepartments
} }
itemToStringLabel={(dept) => itemToStringLabel={
dept.name formatDepartmentLabel
} }
isItemEqualToValue={(a, b) => isItemEqualToValue={(a, b) =>
a.id === b.id a.id === b.id
@ -332,11 +337,13 @@ export default function LecturerEdit({ user, departments }: Props) {
(dept) => ( (dept) => (
<ComboboxChip <ComboboxChip
key={dept.id} key={dept.id}
aria-label={ aria-label={formatDepartmentLabel(
dept.name dept,
} )}
> >
{dept.name} {formatDepartmentLabel(
dept,
)}
</ComboboxChip> </ComboboxChip>
), ),
)} )}
@ -361,7 +368,9 @@ export default function LecturerEdit({ user, departments }: Props) {
key={dept.id} key={dept.id}
value={dept} value={dept}
> >
{dept.name} {formatDepartmentLabel(
dept,
)}
</ComboboxItem> </ComboboxItem>
))} ))}
</ComboboxList> </ComboboxList>

View File

@ -19,10 +19,11 @@ import {
update_user_status, update_user_status,
exportMethod as exportLecturers, exportMethod as exportLecturers,
} from '@/routes/admin/users/lecturers'; } from '@/routes/admin/users/lecturers';
import { formatDepartmentLabel } from '@/types/department';
import type { Lecturer } from './columns'; import type { Lecturer } from './columns';
import { createLecturerColumns } from './columns'; import { createLecturerColumns } from './columns';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type Props = { type Props = {
lecturers: { lecturers: {
@ -61,7 +62,7 @@ export default function LecturerIndex({
label: 'Jurusan', label: 'Jurusan',
options: departments.map((department) => ({ options: departments.map((department) => ({
value: String(department.id), value: String(department.id),
label: department.name, label: formatDepartmentLabel(department),
})), })),
}, },
]; ];

View File

@ -28,8 +28,9 @@ import {
} from '@/components/ui/select'; } from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { index, store } from '@/routes/admin/users/students'; import { index, store } from '@/routes/admin/users/students';
import { formatDepartmentLabel } from '@/types/department';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type Lecturer = { type Lecturer = {
id: number; id: number;
lecturer_number: string; lecturer_number: string;
@ -289,7 +290,9 @@ export default function StudentCreate({ departments, lecturers }: Props) {
key={dept.id} key={dept.id}
value={String(dept.id)} value={String(dept.id)}
> >
{dept.name} {formatDepartmentLabel(
dept,
)}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@ -28,8 +28,9 @@ import {
} from '@/components/ui/select'; } from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { index, update } from '@/routes/admin/users/students'; import { index, update } from '@/routes/admin/users/students';
import { formatDepartmentLabel } from '@/types/department';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type Lecturer = { type Lecturer = {
id: number; id: number;
lecturer_number: string; lecturer_number: string;
@ -336,7 +337,9 @@ export default function StudentEdit({ user, departments, lecturers }: Props) {
key={dept.id} key={dept.id}
value={String(dept.id)} value={String(dept.id)}
> >
{dept.name} {formatDepartmentLabel(
dept,
)}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@ -21,10 +21,11 @@ import {
exportMethod as exportStudents, exportMethod as exportStudents,
index as studentsIndex, index as studentsIndex,
} from '@/routes/admin/users/students'; } from '@/routes/admin/users/students';
import { formatDepartmentLabel } from '@/types/department';
import { createStudentColumns } from './columns'; import { createStudentColumns } from './columns';
import type { Student } from './columns'; import type { Student } from './columns';
type Department = { id: number; name: string }; type Department = { id: number; name: string; degree_level: string | null };
type StatusOption = { value: string; label: string }; type StatusOption = { value: string; label: string };
type Props = { type Props = {
@ -70,7 +71,7 @@ export default function StudentIndex({
label: 'Jurusan', label: 'Jurusan',
options: departments.map((department) => ({ options: departments.map((department) => ({
value: String(department.id), value: String(department.id),
label: department.name, label: formatDepartmentLabel(department),
})), })),
}, },
{ {

View File

@ -2,6 +2,7 @@ export type AnnouncementDepartment = {
id: number; id: number;
code: string; code: string;
name: string; name: string;
degree_level: string | null;
}; };
export type AnnouncementCreator = { export type AnnouncementCreator = {

View File

@ -10,3 +10,12 @@ export type Department = {
created_at: string; created_at: string;
updated_at: string; updated_at: string;
}; };
export function formatDepartmentLabel(department: {
name: string;
degree_level?: string | null;
}): string {
return department.degree_level
? `${department.name} (${department.degree_level})`
: department.name;
}