feat: add GenderBadge and StudentStatusBadge components; update user columns to utilize new badges
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
5c0cadcebf
commit
1012127196
25
resources/js/components/gender-badge.tsx
Normal file
25
resources/js/components/gender-badge.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
|
||||||
|
type GenderBadgeProps = {
|
||||||
|
gender: string | null | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function GenderBadge({ gender }: GenderBadgeProps) {
|
||||||
|
if (gender === 'male') {
|
||||||
|
return (
|
||||||
|
<Badge className="bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300">
|
||||||
|
Laki-laki
|
||||||
|
</Badge>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gender === 'female') {
|
||||||
|
return (
|
||||||
|
<Badge className="bg-pink-100 text-pink-700 dark:bg-pink-500/20 dark:text-pink-300">
|
||||||
|
Perempuan
|
||||||
|
</Badge>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <span className="text-muted-foreground">-</span>;
|
||||||
|
}
|
||||||
34
resources/js/components/student-status-badge.tsx
Normal file
34
resources/js/components/student-status-badge.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
|
||||||
|
type StudentStatusBadgeProps = {
|
||||||
|
status: string | null | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StudentStatusLabels: Record<string, string> = {
|
||||||
|
active: 'Aktif',
|
||||||
|
on_leave: 'Cuti',
|
||||||
|
graduated: 'Lulus',
|
||||||
|
dropped_out: 'Drop Out',
|
||||||
|
};
|
||||||
|
|
||||||
|
const StudentStatusVariants: Record<
|
||||||
|
string,
|
||||||
|
'default' | 'secondary' | 'destructive' | 'outline'
|
||||||
|
> = {
|
||||||
|
active: 'default',
|
||||||
|
on_leave: 'secondary',
|
||||||
|
graduated: 'outline',
|
||||||
|
dropped_out: 'destructive',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function StudentStatusBadge({ status }: StudentStatusBadgeProps) {
|
||||||
|
if (!status) {
|
||||||
|
return <span className="text-muted-foreground">-</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Badge variant={StudentStatusVariants[status] ?? 'outline'}>
|
||||||
|
{StudentStatusLabels[status] ?? status}
|
||||||
|
</Badge>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import { RowActions } from '@/components/row-actions';
|
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { Key, Pencil, Trash2 } from 'lucide-react';
|
import { Key, Pencil, Trash2 } from 'lucide-react';
|
||||||
|
import { GenderBadge } from '@/components/gender-badge';
|
||||||
|
import { RowActions } from '@/components/row-actions';
|
||||||
|
|
||||||
export type Administrator = {
|
export type Administrator = {
|
||||||
id: number;
|
id: number;
|
||||||
@ -33,7 +34,9 @@ export function createAdministratorColumns(
|
|||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span>{row.original.username}</span>
|
<span>{row.original.username}</span>
|
||||||
<span className="text-sm text-muted-foreground">{row.original.email}</span>
|
<span className="text-sm text-muted-foreground">
|
||||||
|
{row.original.email}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -50,10 +53,9 @@ export function createAdministratorColumns(
|
|||||||
{
|
{
|
||||||
accessorKey: 'profile.gender',
|
accessorKey: 'profile.gender',
|
||||||
header: () => <span>Jenis Kelamin</span>,
|
header: () => <span>Jenis Kelamin</span>,
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => (
|
||||||
const gender = row.original.profile?.gender;
|
<GenderBadge gender={row.original.profile?.gender} />
|
||||||
return gender === 'male' ? 'Laki-laki' : gender === 'female' ? 'Perempuan' : '-';
|
),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
@ -80,7 +82,9 @@ export function createAdministratorColumns(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Hapus',
|
label: 'Hapus',
|
||||||
icon: <Trash2 className="h-4 w-4 text-destructive" />,
|
icon: (
|
||||||
|
<Trash2 className="h-4 w-4 text-destructive" />
|
||||||
|
),
|
||||||
onClick: () => handleDeleteClick(admin),
|
onClick: () => handleDeleteClick(admin),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import { RowActions } from '@/components/row-actions';
|
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { Key, Pencil, Trash2 } from 'lucide-react';
|
import { Key, Pencil, Trash2 } from 'lucide-react';
|
||||||
|
import { GenderBadge } from '@/components/gender-badge';
|
||||||
|
import { RowActions } from '@/components/row-actions';
|
||||||
|
|
||||||
export type Lecturer = {
|
export type Lecturer = {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
email: string;
|
email: string;
|
||||||
profile: { full_name: string } | null;
|
profile: { full_name: string; phone_number: string; gender: string } | null;
|
||||||
lecturer: { lecturer_number: string; department: { name: string } | null } | null;
|
lecturer: {
|
||||||
|
lecturer_number: string;
|
||||||
|
department: { name: string } | null;
|
||||||
|
} | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CreateColumnsParams = {
|
type CreateColumnsParams = {
|
||||||
@ -23,14 +27,16 @@ export function createLecturerColumns(
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
accessorKey: 'lecturer.lecturer_number',
|
id: 'identity',
|
||||||
header: () => <span>NIDN</span>,
|
header: () => <span>NIDN</span>,
|
||||||
cell: ({ row }) => row.original.lecturer?.lecturer_number ?? '-',
|
cell: ({ row }) => (
|
||||||
},
|
<div className="flex flex-col">
|
||||||
{
|
<span>{row.original.lecturer?.lecturer_number ?? '-'}</span>
|
||||||
accessorKey: 'profile.full_name',
|
<span className="text-sm text-muted-foreground">
|
||||||
header: () => <span>Nama Lengkap</span>,
|
{row.original.profile?.full_name ?? '-'}
|
||||||
cell: ({ row }) => row.original.profile?.full_name ?? '-',
|
</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'account',
|
id: 'account',
|
||||||
@ -38,7 +44,9 @@ export function createLecturerColumns(
|
|||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span>{row.original.username}</span>
|
<span>{row.original.username}</span>
|
||||||
<span className="text-sm text-muted-foreground">{row.original.email}</span>
|
<span className="text-sm text-muted-foreground">
|
||||||
|
{row.original.email}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -47,6 +55,18 @@ export function createLecturerColumns(
|
|||||||
header: () => <span>Jurusan</span>,
|
header: () => <span>Jurusan</span>,
|
||||||
cell: ({ row }) => row.original.lecturer?.department?.name ?? '-',
|
cell: ({ row }) => row.original.lecturer?.department?.name ?? '-',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'profile.phone_number',
|
||||||
|
header: () => <span>Nomor Telepon</span>,
|
||||||
|
cell: ({ row }) => row.original.profile?.phone_number ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'profile.gender',
|
||||||
|
header: () => <span>Jenis Kelamin</span>,
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<GenderBadge gender={row.original.profile?.gender} />
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
header: () => <span className="block text-center">Aksi</span>,
|
header: () => <span className="block text-center">Aksi</span>,
|
||||||
@ -72,7 +92,9 @@ export function createLecturerColumns(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Hapus',
|
label: 'Hapus',
|
||||||
icon: <Trash2 className="h-4 w-4 text-destructive" />,
|
icon: (
|
||||||
|
<Trash2 className="h-4 w-4 text-destructive" />
|
||||||
|
),
|
||||||
onClick: () => handleDeleteClick(lecturer),
|
onClick: () => handleDeleteClick(lecturer),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -1,13 +1,20 @@
|
|||||||
import { RowActions } from '@/components/row-actions';
|
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { Key, Pencil, Trash2 } from 'lucide-react';
|
import { Key, Pencil, Trash2 } from 'lucide-react';
|
||||||
|
import { GenderBadge } from '@/components/gender-badge';
|
||||||
|
import { RowActions } from '@/components/row-actions';
|
||||||
|
import { StudentStatusBadge } from '@/components/student-status-badge';
|
||||||
|
|
||||||
export type Student = {
|
export type Student = {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
email: string;
|
email: string;
|
||||||
profile: { full_name: string } | null;
|
profile: { full_name: string; phone_number: string; gender: string } | null;
|
||||||
student: { student_number: string; department: { name: string } | null; enrollment_year: number; status: string | null } | null;
|
student: {
|
||||||
|
student_number: string;
|
||||||
|
department: { name: string } | null;
|
||||||
|
enrollment_year: number;
|
||||||
|
status: string | null;
|
||||||
|
} | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CreateColumnsParams = {
|
type CreateColumnsParams = {
|
||||||
@ -23,14 +30,16 @@ export function createStudentColumns(
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
accessorKey: 'student.student_number',
|
id: 'identity',
|
||||||
header: () => <span>NIM</span>,
|
header: () => <span>NIM</span>,
|
||||||
cell: ({ row }) => row.original.student?.student_number ?? '-',
|
cell: ({ row }) => (
|
||||||
},
|
<div className="flex flex-col">
|
||||||
{
|
<span>{row.original.student?.student_number ?? '-'}</span>
|
||||||
accessorKey: 'profile.full_name',
|
<span className="text-sm text-muted-foreground">
|
||||||
header: () => <span>Nama Lengkap</span>,
|
{row.original.profile?.full_name ?? '-'}
|
||||||
cell: ({ row }) => row.original.profile?.full_name ?? '-',
|
</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'account',
|
id: 'account',
|
||||||
@ -38,7 +47,9 @@ export function createStudentColumns(
|
|||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span>{row.original.username}</span>
|
<span>{row.original.username}</span>
|
||||||
<span className="text-sm text-muted-foreground">{row.original.email}</span>
|
<span className="text-sm text-muted-foreground">
|
||||||
|
{row.original.email}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -55,7 +66,21 @@ export function createStudentColumns(
|
|||||||
{
|
{
|
||||||
accessorKey: 'student.status',
|
accessorKey: 'student.status',
|
||||||
header: () => <span>Status</span>,
|
header: () => <span>Status</span>,
|
||||||
cell: ({ row }) => row.original.student?.status ?? '-',
|
cell: ({ row }) => (
|
||||||
|
<StudentStatusBadge status={row.original.student?.status} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'profile.phone_number',
|
||||||
|
header: () => <span>Nomor Telepon</span>,
|
||||||
|
cell: ({ row }) => row.original.profile?.phone_number ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'profile.gender',
|
||||||
|
header: () => <span>Jenis Kelamin</span>,
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<GenderBadge gender={row.original.profile?.gender} />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
@ -82,7 +107,9 @@ export function createStudentColumns(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Hapus',
|
label: 'Hapus',
|
||||||
icon: <Trash2 className="h-4 w-4 text-destructive" />,
|
icon: (
|
||||||
|
<Trash2 className="h-4 w-4 text-destructive" />
|
||||||
|
),
|
||||||
onClick: () => handleDeleteClick(student),
|
onClick: () => handleDeleteClick(student),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user