153 lines
7.1 KiB
TypeScript
153 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/inputs';
|
|
import { InputError } from '@/components/ui';
|
|
import { RupiahInput } from '@/components/inputs';
|
|
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(String(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: parseFloat(String(stock)) || 0,
|
|
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('Ada data yang belum sesuai, 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>
|
|
<Input
|
|
type="text"
|
|
inputMode="decimal"
|
|
value={stock}
|
|
onChange={(e) => setStock(e.target.value)}
|
|
/>
|
|
<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>
|
|
</>
|
|
);
|
|
}
|