- 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.
152 lines
7.1 KiB
TypeScript
152 lines
7.1 KiB
TypeScript
import { Form, Head, Link } from '@inertiajs/react';
|
|
import { ArrowLeft } from 'lucide-react';
|
|
import { useState } from 'react';
|
|
import { toast } from 'sonner';
|
|
import { FileUpload } from '@/components/file-upload';
|
|
import InputError from '@/components/input-error';
|
|
import { NumberInput } from '@/components/number-input';
|
|
import { RupiahInput } from '@/components/rupiah-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 { getTemporaryUrl } from '@/lib/upload';
|
|
import { index as rawMaterialIndex } from '@/routes/admin/master/raw-materials';
|
|
|
|
type Props = {
|
|
variant: {
|
|
id: number;
|
|
raw_material_id: number;
|
|
variant: string;
|
|
price: number;
|
|
stock: number;
|
|
photo_key: string | null;
|
|
photo_url: string | null;
|
|
};
|
|
};
|
|
|
|
export default function RawMaterialVariantEdit({ variant }: Props) {
|
|
const [variantName, setVariantName] = useState(variant.variant);
|
|
const [price, setPrice] = useState(variant.price);
|
|
const [stock, setStock] = useState(Number(variant.stock) || 0);
|
|
const [photo, setPhoto] = useState<string | null>(variant.photo_key);
|
|
const [photoUrl, setPhotoUrl] = useState<string | null>(variant.photo_url);
|
|
const [uploading, setUploading] = useState(false);
|
|
|
|
function getPayload() {
|
|
return {
|
|
variant: variantName,
|
|
price: Number(price),
|
|
stock: Number(stock),
|
|
photo_key: photo,
|
|
};
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Head title="Edit Varian" />
|
|
|
|
<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">
|
|
<h2 className="text-2xl font-semibold tracking-tight">
|
|
Edit Varian
|
|
</h2>
|
|
<Button asChild variant="outline">
|
|
<Link href={rawMaterialIndex.url()}>
|
|
<ArrowLeft className="h-4 w-4" />
|
|
Kembali
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
|
|
<Form
|
|
action={`/admin/master/raw-materials/${variant.raw_material_id}/variants/${variant.id}`}
|
|
method="put"
|
|
transform={() => getPayload()}
|
|
onError={() => {
|
|
toast.error('Terjadi kesalahan saat menyimpan data. Silakan periksa kembali input Anda.');
|
|
}}
|
|
>
|
|
{({ errors, processing }) => (
|
|
<>
|
|
<div className="grid gap-6">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Informasi Varian</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
<div className="grid gap-2">
|
|
<Label>
|
|
Nama Varian{' '}
|
|
<span className="text-destructive">*</span>
|
|
</Label>
|
|
<Input
|
|
value={variantName}
|
|
onChange={(e) => setVariantName(e.target.value)}
|
|
placeholder="Contoh: Ukuran L, Warna Merah"
|
|
/>
|
|
<InputError message={errors.variant} />
|
|
</div>
|
|
<div className="grid gap-2">
|
|
<Label>
|
|
Harga <span className="text-destructive">*</span>
|
|
</Label>
|
|
<RupiahInput
|
|
value={price}
|
|
onValueChange={setPrice}
|
|
/>
|
|
<InputError message={errors.price} />
|
|
</div>
|
|
<div className="grid gap-2">
|
|
<Label>
|
|
Stok <span className="text-destructive">*</span>
|
|
</Label>
|
|
<NumberInput
|
|
value={stock}
|
|
onValueChange={setStock}
|
|
/>
|
|
<InputError message={errors.stock} />
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Foto Varian <span className="text-destructive">*</span></CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<FileUpload
|
|
value={photo}
|
|
onChange={(key) => {
|
|
setPhoto(key);
|
|
setPhotoUrl(key ? getTemporaryUrl(key) : null);
|
|
}}
|
|
folder="raw-material-variant"
|
|
existingUrl={photoUrl}
|
|
onUploadingChange={setUploading}
|
|
/>
|
|
<InputError message={errors.photo_key} />
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
<div className="mt-6 flex items-center gap-4">
|
|
<Button
|
|
type="submit"
|
|
disabled={processing || uploading}
|
|
>
|
|
{processing
|
|
? 'Menyimpan...'
|
|
: uploading
|
|
? 'Mengunggah...'
|
|
: 'Simpan'}
|
|
</Button>
|
|
</div>
|
|
</>
|
|
)}
|
|
</Form>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|