- Integrated toast notifications to display error messages when form submissions fail across various components, enhancing user feedback and experience. - Updated components including DeleteUser, FormDialog, ManageTwoFactor, TwoFactorRecoveryCodes, TwoFactorSetupModal, PayrollPeriodShow, EmployeeCreate, EmployeeEdit, CuttingCreate, CuttingEdit, PurchaseCreate, PurchaseEdit, RestockCreate, RestockEdit, TransactionCreate, TransactionEdit, Category management, Product management, Raw Material management, Role management, Settings, and Authentication pages.
213 lines
11 KiB
TypeScript
213 lines
11 KiB
TypeScript
import { Form, Head } from '@inertiajs/react';
|
|
import { useState } from 'react';
|
|
import { toast } from 'sonner';
|
|
import ProfileController from '@/actions/App/Http/Controllers/Settings/ProfileController';
|
|
import { DatePicker } from '@/components/date-picker';
|
|
import InputError from '@/components/input-error';
|
|
import { PhoneNumberInput } from '@/components/phone-number-input';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
import { edit } from '@/routes/profile';
|
|
|
|
type UserData = {
|
|
id: number;
|
|
email: string;
|
|
username: string;
|
|
userProfile: {
|
|
full_name: string;
|
|
phone_number: string | null;
|
|
gender: string | null;
|
|
birth_date: string | null;
|
|
address: string | null;
|
|
} | null;
|
|
};
|
|
|
|
type Props = {
|
|
user: UserData;
|
|
mustVerifyEmail: boolean;
|
|
status?: string;
|
|
};
|
|
|
|
export default function Profile({ user }: Props) {
|
|
const [birthDate, setBirthDate] = useState<Date | undefined>(
|
|
user.userProfile?.birth_date
|
|
? new Date(user.userProfile.birth_date)
|
|
: undefined,
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<Head title="Profil" />
|
|
|
|
<div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto px-4 md:px-6">
|
|
<Form
|
|
{...ProfileController.update.form()}
|
|
options={{
|
|
preserveScroll: true,
|
|
}}
|
|
onError={() => {
|
|
toast.error('Terjadi kesalahan saat menyimpan data. Silakan periksa kembali input Anda.');
|
|
}}
|
|
>
|
|
{({ processing, errors }) => (
|
|
<div className="grid gap-6">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Akun</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<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"
|
|
defaultValue={user.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"
|
|
defaultValue={user.username}
|
|
/>
|
|
<InputError message={errors.username} />
|
|
</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"
|
|
defaultValue={
|
|
user.userProfile?.full_name ??
|
|
''
|
|
}
|
|
/>
|
|
<InputError
|
|
message={errors.full_name}
|
|
/>
|
|
</div>
|
|
<div className="grid gap-2">
|
|
<Label htmlFor="phone_number">
|
|
No. Telepon
|
|
</Label>
|
|
<PhoneNumberInput
|
|
name="phone_number"
|
|
defaultValue={
|
|
user.userProfile
|
|
?.phone_number ?? ''
|
|
}
|
|
/>
|
|
<InputError
|
|
message={errors.phone_number}
|
|
/>
|
|
</div>
|
|
<div className="grid gap-2">
|
|
<Label>Jenis Kelamin</Label>
|
|
<RadioGroup
|
|
name="gender"
|
|
defaultValue={
|
|
user.userProfile?.gender ?? ''
|
|
}
|
|
className="flex gap-4"
|
|
>
|
|
<div className="flex items-center space-x-2">
|
|
<RadioGroupItem
|
|
value="male"
|
|
id="settings-gender-male"
|
|
/>
|
|
<Label
|
|
htmlFor="settings-gender-male"
|
|
className="font-normal"
|
|
>
|
|
Laki-laki
|
|
</Label>
|
|
</div>
|
|
<div className="flex items-center space-x-2">
|
|
<RadioGroupItem
|
|
value="female"
|
|
id="settings-gender-female"
|
|
/>
|
|
<Label
|
|
htmlFor="settings-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={birthDate}
|
|
onChange={setBirthDate}
|
|
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}
|
|
defaultValue={
|
|
user.userProfile?.address ?? ''
|
|
}
|
|
/>
|
|
<InputError message={errors.address} />
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<div className="flex items-center gap-4">
|
|
<Button type="submit" disabled={processing}>
|
|
{processing ? 'Menyimpan...' : 'Simpan'}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</Form>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|