dstpabuaran.com/resources/js/pages/admin/hr/employee/create.tsx
Yoga Pangestu 166419134f Refactor component imports for consistency and organization
- Updated import paths for various components to align with new directory structure.
- Changed imports from 'row-actions', 'confirm-dialog', 'image-preview-button', and 'file-upload' to their respective new locations in 'data-display', 'dialogs', and 'inputs'.
- Adjusted imports in multiple pages including purchase, restock, transaction, category, customer, product, raw-material, supplier, roles, and settings.
- Ensured all relevant components are imported from their new locations to maintain functionality.
2026-08-07 13:48:46 +07:00

389 lines
22 KiB
TypeScript

import { Form, Head, Link } from '@inertiajs/react';
import { AlertCircle, ArrowLeft } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import { DatePicker } from '@/components/inputs';
import { InputError } from '@/components/ui';
import { PhoneNumberInput } from '@/components/inputs';
import { RupiahInput } from '@/components/inputs';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from '@/components/ui/combobox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import { index as employeeIndex, store } from '@/routes/admin/hr/employees';
type Role = {
id: number;
name: string;
};
type Props = {
roles: Role[];
canViewAll: boolean;
};
export default function EmployeeCreate({ roles, canViewAll }: Props) {
const [joinDate, setJoinDate] = useState<Date | undefined>(undefined);
const [resignDate, setResignDate] = useState<Date | undefined>(undefined);
const [selectedRole, setSelectedRole] = useState<Role | null>(
!canViewAll && roles.length === 1 ? roles[0] : null,
);
return (
<>
<Head title="Tambah Pegawai" />
<div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-semibold tracking-tight">
Tambah Pegawai
</h2>
</div>
<Button asChild variant="outline">
<Link href={employeeIndex.url()}>
<ArrowLeft className="h-4 w-4" />
Kembali
</Link>
</Button>
</div>
<Alert>
<AlertCircle className="h-4 w-4" />
<AlertTitle>Informasi Kata Sandi</AlertTitle>
<AlertDescription>
Kata sandi default untuk akun baru adalah Minimal8@
</AlertDescription>
</Alert>
<Form
action={store()}
onError={() => {
toast.error('Terjadi kesalahan saat menyimpan data. Silakan periksa kembali input Anda.');
}}
>
{({ errors, processing }) => (
<>
<input
type="hidden"
name="role"
value={selectedRole?.name ?? ''}
/>
<div className="grid gap-6">
<Card>
<CardHeader>
<CardTitle>Akun</CardTitle>
</CardHeader>
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-3">
<div className="grid gap-2">
<Label htmlFor="email">
Email{' '}
<span className="text-destructive">
*
</span>
</Label>
<Input
id="email"
name="email"
type="email"
placeholder="Masukkan email"
/>
<InputError
message={errors.email}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="username">
Username{' '}
<span className="text-destructive">
*
</span>
</Label>
<Input
id="username"
name="username"
placeholder="Masukkan username"
/>
<InputError
message={errors.username}
/>
</div>
{canViewAll ? (
<div className="grid gap-2">
<Label>
Role{' '}
<span className="text-destructive">
*
</span>
</Label>
<Combobox
items={roles}
itemToStringLabel={(r) =>
r.name
}
value={selectedRole}
onValueChange={(value) =>
setSelectedRole(value)
}
>
<ComboboxInput
placeholder="Cari role..."
className="w-full"
/>
<ComboboxContent>
<ComboboxEmpty>
Tidak ada role
ditemukan.
</ComboboxEmpty>
<ComboboxList>
{(role) => (
<ComboboxItem
key={
role.id
}
value={
role
}
>
{role.name}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
<InputError
message={errors.role}
/>
</div>
) : (
<div className="grid gap-2">
<Label>Role</Label>
<div className="flex h-10 w-full items-center rounded-md border border-input bg-muted px-3 py-2 text-sm">
{selectedRole?.name ?? '-'}
</div>
</div>
)}
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Profil</CardTitle>
</CardHeader>
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div className="grid gap-2">
<Label htmlFor="full_name">
Nama Lengkap{' '}
<span className="text-destructive">
*
</span>
</Label>
<Input
id="full_name"
name="full_name"
placeholder="Masukkan nama lengkap"
/>
<InputError
message={errors.full_name}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="phone_number">
No. Telepon
</Label>
<PhoneNumberInput name="phone_number" />
<InputError
message={errors.phone_number}
/>
</div>
<div className="grid gap-2">
<Label>Jenis Kelamin</Label>
<RadioGroup
name="gender"
className="flex gap-4"
>
<div className="flex items-center space-x-2">
<RadioGroupItem
value="male"
id="gender-male"
/>
<Label
htmlFor="gender-male"
className="font-normal"
>
Laki-laki
</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem
value="female"
id="gender-female"
/>
<Label
htmlFor="gender-female"
className="font-normal"
>
Perempuan
</Label>
</div>
</RadioGroup>
<InputError
message={errors.gender}
/>
</div>
<div className="grid gap-2">
<Label>Tanggal Lahir</Label>
<DatePicker
name="birth_date"
value={undefined}
onChange={() => {}}
placeholder="Pilih tanggal lahir"
/>
<InputError
message={errors.birth_date}
/>
</div>
<div className="grid gap-2 md:col-span-2">
<Label htmlFor="address">
Alamat
</Label>
<Textarea
id="address"
name="address"
placeholder="Masukkan alamat"
rows={3}
/>
<InputError
message={errors.address}
/>
</div>
</CardContent>
</Card>
{selectedRole?.name !== 'owner' && (
<Card>
<CardHeader>
<CardTitle>Pegawai</CardTitle>
</CardHeader>
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div className="grid gap-2">
<Label>
Tanggal Masuk{' '}
<span className="text-destructive">
*
</span>
</Label>
<DatePicker
name="join_date"
value={joinDate}
onChange={setJoinDate}
placeholder="Pilih tanggal masuk"
/>
<InputError
message={errors.join_date}
/>
</div>
<div className="grid gap-2">
<Label>Tanggal Keluar</Label>
<DatePicker
name="resign_date"
value={resignDate}
onChange={setResignDate}
placeholder="Pilih tanggal keluar"
/>
<InputError
message={
errors.resign_date
}
/>
</div>
<div className="grid gap-2">
<Label>
Status Kepegawaian{' '}
<span className="text-destructive">
*
</span>
</Label>
<Select
name="employment_status"
defaultValue="full_time"
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Pilih status kepegawaian" />
</SelectTrigger>
<SelectContent>
<SelectItem value="full_time">
Full Time
</SelectItem>
<SelectItem value="part_time">
Part Time
</SelectItem>
<SelectItem value="contract">
Kontrak
</SelectItem>
<SelectItem value="internship">
Magang
</SelectItem>
<SelectItem value="resigned">
Keluar
</SelectItem>
</SelectContent>
</Select>
<InputError
message={
errors.employment_status
}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="base_salary">
Gaji Pokok{' '}
<span className="text-destructive">
*
</span>
</Label>
<RupiahInput
name="base_salary"
/>
<InputError
message={
errors.base_salary
}
/>
</div>
</CardContent>
</Card>
)}
</div>
<div className="mt-6 flex items-center gap-4">
<Button type="submit" disabled={processing}>
{processing ? 'Menyimpan...' : 'Simpan'}
</Button>
</div>
</>
)}
</Form>
</div>
</>
);
}