132 lines
7.1 KiB
TypeScript
132 lines
7.1 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import { Head, Link, usePage } from '@inertiajs/react';
|
|
import React from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Separator } from '@/components/ui/separator';
|
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
|
import AppLayout from '@/layouts/app-layout';
|
|
|
|
interface Position {
|
|
id: number;
|
|
name: string;
|
|
employees_count: number;
|
|
}
|
|
|
|
interface PageProps {
|
|
positions: Position[];
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
interface SharedData {
|
|
flash: {
|
|
success?: string;
|
|
error?: string;
|
|
};
|
|
}
|
|
|
|
export default function Index({ positions }: PageProps) {
|
|
const { flash } = usePage<any>().props as SharedData;
|
|
|
|
return (
|
|
<AppLayout>
|
|
<Head title="Manajemen Jabatan" />
|
|
|
|
<div className="p-4 md:p-8 w-full space-y-4">
|
|
|
|
{/* Page Header */}
|
|
<div className="space-y-1">
|
|
<h2 className="text-2xl font-bold tracking-tight">Data Jabatan</h2>
|
|
<p className="text-muted-foreground">Kelola level dan posisi pekerjaan.</p>
|
|
</div>
|
|
|
|
{/* Flash Messages */}
|
|
{flash?.success && (
|
|
<div className="p-4 bg-green-50 text-green-700 border border-green-200 rounded-md text-sm">
|
|
{flash.success}
|
|
</div>
|
|
)}
|
|
{flash?.error && (
|
|
<div className="p-4 bg-red-50 text-red-700 border border-red-200 rounded-md text-sm">
|
|
{flash.error}
|
|
</div>
|
|
)}
|
|
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between pb-4">
|
|
<CardTitle>Daftar Jabatan</CardTitle>
|
|
<Button asChild>
|
|
<Link href="/admin/positions/create">+ Tambah Jabatan</Link>
|
|
</Button>
|
|
</CardHeader>
|
|
<Separator />
|
|
<CardContent className="pt-0">
|
|
<div className="relative w-full overflow-auto">
|
|
<table className="w-full text-sm text-left">
|
|
<thead className="text-muted-foreground bg-zinc-50/50">
|
|
<tr className="border-b">
|
|
<th className="h-12 px-4 font-medium">Nama Jabatan</th>
|
|
<th className="h-12 px-4 font-medium text-center">Total Karyawan</th>
|
|
<th className="h-12 px-4 font-medium text-right">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{positions.length > 0 ? (
|
|
positions.map((pos) => (
|
|
<tr key={pos.id} className="border-b hover:bg-zinc-50">
|
|
<td className="p-4 font-bold text-gray-900">
|
|
{pos.name}
|
|
</td>
|
|
<td className="p-4 text-center">
|
|
<span className={`inline-flex items-center justify-center px-2.5 py-0.5 rounded-full text-xs font-medium ${pos.employees_count > 0 ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 text-gray-600'}`}>
|
|
{pos.employees_count}
|
|
</span>
|
|
</td>
|
|
<td className="p-4 text-right space-x-2">
|
|
<Button variant="ghost" size="sm" asChild>
|
|
<Link href={`/admin/positions/${pos.id}/edit`}>Edit</Link>
|
|
</Button>
|
|
|
|
{pos.employees_count > 0 ? (
|
|
<TooltipProvider>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<span tabIndex={0} className="cursor-not-allowed inline-block">
|
|
<Button variant="ghost" size="sm" disabled className="text-red-300 opacity-50">Hapus</Button>
|
|
</span>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="bg-red-50 text-red-700 border-red-200">
|
|
<p>Tidak bisa dihapus: Digunakan oleh {pos.employees_count} karyawan.</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
) : (
|
|
<Link
|
|
href={`/admin/positions/${pos.id}`}
|
|
method="delete"
|
|
as="button"
|
|
onClick={(e) => { if (!confirm('Hapus jabatan ini?')) e.preventDefault(); }}
|
|
className="inline-flex items-center justify-center rounded-md text-sm font-medium h-9 px-3 text-red-600 hover:bg-red-50"
|
|
>
|
|
Hapus
|
|
</Link>
|
|
)}
|
|
</td>
|
|
</tr>
|
|
))
|
|
) : (
|
|
<tr>
|
|
<td colSpan={3} className="p-8 text-center text-muted-foreground">
|
|
Belum ada data jabatan.
|
|
</td>
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</AppLayout>
|
|
);
|
|
} |