feat: enhance user management by including roles and additional profile information in the user list
This commit is contained in:
parent
29ca4f8ec4
commit
665394d511
@ -18,7 +18,7 @@ class UserController extends Controller
|
|||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('admin/master/user/index', [
|
return Inertia::render('admin/master/user/index', [
|
||||||
'users' => User::with('profile')->latest()->get(),
|
'users' => User::with(['profile', 'roles'])->latest()->get(),
|
||||||
'defaultPassword' => config('auth.password_default', 'password'),
|
'defaultPassword' => config('auth.password_default', 'password'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,8 @@ import type { User } from '@/types';
|
|||||||
import { Link } from '@inertiajs/react';
|
import { Link } from '@inertiajs/react';
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { KeyRound, Pencil, Trash2 } from 'lucide-react';
|
import { KeyRound, Pencil, Trash2 } from 'lucide-react';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
import { formatCurrency, formatDate } from '@/lib/formatters';
|
||||||
|
|
||||||
interface ColumnProps {
|
interface ColumnProps {
|
||||||
onResetPassword: (user: User) => void;
|
onResetPassword: (user: User) => void;
|
||||||
@ -40,6 +42,42 @@ export const getColumns = ({ onResetPassword, onDelete, onToggleStatus }: Column
|
|||||||
),
|
),
|
||||||
meta: { title: "Nama Pengguna" },
|
meta: { title: "Nama Pengguna" },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorFn: (row) => row.roles?.map(role => role.name).join(', '),
|
||||||
|
id: "roles",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="Peran" />
|
||||||
|
),
|
||||||
|
meta: { title: "Peran" },
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const roles = row.original.roles;
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
{roles?.map((role) => (
|
||||||
|
<Badge key={role.id} variant="outline" className="capitalize">
|
||||||
|
{role.name}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorFn: (row) => row.profile?.nik,
|
||||||
|
id: "nik",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="NIK" />
|
||||||
|
),
|
||||||
|
meta: { title: "NIK" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorFn: (row) => row.profile?.full_name,
|
||||||
|
id: "full_name",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="Nama Lengkap" />
|
||||||
|
),
|
||||||
|
meta: { title: "Nama Lengkap" },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorFn: (row) => row.profile?.phone_number,
|
accessorFn: (row) => row.profile?.phone_number,
|
||||||
id: "phone_number",
|
id: "phone_number",
|
||||||
@ -48,6 +86,45 @@ export const getColumns = ({ onResetPassword, onDelete, onToggleStatus }: Column
|
|||||||
),
|
),
|
||||||
meta: { title: "Nomor Telepon" },
|
meta: { title: "Nomor Telepon" },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorFn: (row) => row.profile?.address,
|
||||||
|
id: "address",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="Alamat" />
|
||||||
|
),
|
||||||
|
meta: { title: "Alamat" },
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="max-w-[200px] truncate" title={row.original.profile?.address}>
|
||||||
|
{row.original.profile?.address || '-'}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorFn: (row) => `${row.profile?.birth_place}, ${row.profile?.birth_date}`,
|
||||||
|
id: "birth_info",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="Tempat, Tgl Lahir" />
|
||||||
|
),
|
||||||
|
meta: { title: "Tempat, Tgl Lahir" },
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const profile = row.original.profile;
|
||||||
|
if (!profile?.birth_place && !profile?.birth_date) return '-';
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{profile.birth_place || '-'}, {formatDate(profile.birth_date)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorFn: (row) => row.profile?.base_salary,
|
||||||
|
id: "base_salary",
|
||||||
|
header: ({ column }) => (
|
||||||
|
<DataTableColumnHeader column={column} title="Gaji Pokok" />
|
||||||
|
),
|
||||||
|
meta: { title: "Gaji Pokok" },
|
||||||
|
cell: ({ row }) => formatCurrency(row.original.profile?.base_salary || 0)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "is_active",
|
accessorKey: "is_active",
|
||||||
header: "Status",
|
header: "Status",
|
||||||
|
|||||||
@ -7,6 +7,7 @@ export type UserProfile = {
|
|||||||
address: string;
|
address: string;
|
||||||
birth_place: string;
|
birth_place: string;
|
||||||
birth_date: string;
|
birth_date: string;
|
||||||
|
base_salary: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
};
|
};
|
||||||
@ -23,6 +24,7 @@ export type User = {
|
|||||||
updated_at: string;
|
updated_at: string;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
profile?: UserProfile;
|
profile?: UserProfile;
|
||||||
|
roles?: import('./role').Role[];
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user