dress/resources/js/pages/admin/master/user/edit.tsx

248 lines
14 KiB
TypeScript

import { Head, Link } from '@inertiajs/react';
import { useForm } from '@inertiajs/react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Field } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import userRoutes from '@/routes/user';
import React from 'react';
import { toast } from 'sonner';
import { Textarea } from '@/components/ui/textarea';
import { Calendar } from "@/components/ui/calendar"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { NumericFormat } from 'react-number-format';
import { ArrowLeft, Loader, Save } from 'lucide-react';
export default function UserEdit({ user }: { user: any }) {
const [isCalendarOpen, setIsCalendarOpen] = React.useState(false);
const { data, setData, post, processing, errors } = useForm({
username: user.username || '',
email: user.email || '',
nik: user.profile?.nik || '',
full_name: user.profile?.full_name || '',
phone_number: user.profile?.phone_number || '',
address: user.profile?.address || '',
birth_place: user.profile?.birth_place || '',
birth_date: user.profile?.birth_date || '',
base_salary: user.profile?.base_salary || 0,
_method: 'PATCH',
});
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
post(userRoutes.update(user.id).url, {
onSuccess: (response: any) => {
toast.success(response.props.flash.success);
},
});
};
return (
<div className="flex flex-col gap-6 p-6">
<Head title={`Ubah Pegawai: ${user.username}`} />
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold tracking-tight">Ubah Pegawai</h1>
</div>
<Link href={userRoutes.index().url}>
<Button variant='outline'>
<ArrowLeft className="size-4" />
Kembali
</Button>
</Link>
</div>
<form onSubmit={onSubmit} className="space-y-6">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2 space-y-6">
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
<CardHeader className="border-b">
<CardTitle>Informasi Profil</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Field>
<Label htmlFor="nik" required>NIK</Label>
<Input
id="nik"
name="nik"
value={data.nik}
onChange={e => setData('nik', e.target.value)}
autoComplete='off'
placeholder='Contoh: 3213051307900001'
maxLength={16}
/>
{errors.nik && <p className="text-xs text-red-500">{errors.nik}</p>}
</Field>
<Field>
<Label htmlFor="full_name" required>Nama Lengkap</Label>
<Input
id="full_name"
name="full_name"
value={data.full_name}
onChange={e => setData('full_name', e.target.value)}
autoComplete='off'
placeholder='Contoh: John Doe'
/>
{errors.full_name && <p className="text-xs text-red-500">{errors.full_name}</p>}
</Field>
<Field>
<Label htmlFor="phone_number" required>Nomor Telepon</Label>
<Input
id="phone_number"
name="phone_number"
value={data.phone_number}
onChange={e => setData('phone_number', e.target.value)}
autoComplete='off'
placeholder='Contoh: 08123456789'
/>
{errors.phone_number && <p className="text-xs text-red-500">{errors.phone_number}</p>}
</Field>
<Field>
<Label htmlFor="base_salary" required>Gaji Pokok</Label>
<NumericFormat
id="base_salary"
customInput={Input}
thousandSeparator="."
decimalSeparator=","
prefix="Rp "
value={data.base_salary}
onValueChange={(values) => {
setData('base_salary', values.floatValue || 0)
}}
placeholder="Rp 0"
autoComplete='off'
/>
{errors.base_salary && <p className="text-xs text-red-500">{errors.base_salary}</p>}
</Field>
<Field>
<Label htmlFor="birth_place" required>Tempat Lahir</Label>
<Input
id="birth_place"
name="birth_place"
value={data.birth_place}
onChange={e => setData('birth_place', e.target.value)}
autoComplete='off'
placeholder='Contoh: Jakarta'
/>
{errors.birth_place && <p className="text-xs text-red-500">{errors.birth_place}</p>}
</Field>
<Field>
<Label htmlFor="birth_date" required>Tanggal Lahir</Label>
<Popover open={isCalendarOpen} onOpenChange={setIsCalendarOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
id="birth_date"
className="w-full justify-start font-normal"
>
{data.birth_date ? (
new Intl.DateTimeFormat("id-ID", {
day: "numeric",
month: "long",
year: "numeric",
}).format(new Date(data.birth_date))
) : (
<span className="text-muted-foreground">Pilih Tanggal</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto overflow-hidden p-0" align="start">
<Calendar
mode="single"
selected={data.birth_date ? new Date(data.birth_date) : undefined}
defaultMonth={data.birth_date ? new Date(data.birth_date) : new Date(2000, 0, 1)}
captionLayout="dropdown"
onSelect={(selectedDate: Date | undefined) => {
if (selectedDate) {
setData('birth_date', selectedDate.getFullYear() + "-" + String(selectedDate.getMonth() + 1).padStart(2, '0') + "-" + String(selectedDate.getDate()).padStart(2, '0'));
} else {
setData('birth_date', '');
}
setIsCalendarOpen(false);
}}
/>
</PopoverContent>
</Popover>
{errors.birth_date && <p className="text-xs text-red-500">{errors.birth_date}</p>}
</Field>
</div>
<Field>
<Label htmlFor="address" required>Alamat</Label>
<Textarea id='address' name='address' value={data.address} onChange={e => setData('address', e.target.value)} placeholder='Contoh: Kp. Bakan Sampeu' />
{errors.address && <p className="text-xs text-red-500">{errors.address}</p>}
</Field>
</CardContent>
</Card>
</div>
<div className="space-y-6">
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
<CardHeader className="border-b">
<CardTitle>Kredensial Akun</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
<Field>
<Label htmlFor="email" required>Alamat Surel</Label>
<Input
id="email"
name="email"
type="email"
value={data.email}
onChange={e => setData('email', e.target.value)}
autoComplete='off'
placeholder='Contoh: john@example.com'
/>
{errors.email && <p className="text-xs text-red-500">{errors.email}</p>}
</Field>
<Field>
<Label htmlFor="username" required>Nama Pengguna</Label>
<Input
id="username"
name="username"
value={data.username}
onChange={e => setData('username', e.target.value)}
autoComplete='off'
placeholder='Contoh: johndoe'
/>
{errors.username && <p className="text-xs text-red-500">{errors.username}</p>}
</Field>
</CardContent>
</Card>
<div className="flex flex-col gap-4 p-4 rounded-xl bg-primary/5 border border-primary/10 shadow-sm">
<Button type="submit" className="w-full" disabled={processing}>
{processing ? <Loader className="size-4 animate-spin" /> : <Save className="size-4" />}
{processing ? 'Menyimpan...' : 'Simpan'}
</Button>
</div>
</div>
</div>
</form>
</div>
);
}
UserEdit.layout = {
breadcrumbs: [
{
title: 'Master',
},
],
};