feat: update product create and edit forms to include detailed pricing fields and improved layout structure
This commit is contained in:
parent
2e1aebae97
commit
e8ae633509
@ -1,5 +1,5 @@
|
|||||||
import { Head, useForm, Link } from '@inertiajs/react';
|
import { Head, useForm, Link } from '@inertiajs/react';
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Field, FieldGroup } from "@/components/ui/field"
|
import { Field, FieldGroup } from "@/components/ui/field"
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input"
|
||||||
@ -58,29 +58,154 @@ export default function ProductCreate({ categories }: { categories: Category[] }
|
|||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">Tambah Produk</h1>
|
<h1 className="text-3xl font-bold tracking-tight">Tambah Produk</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<Link href={productRoutes.index().url}>
|
||||||
|
<Button variant='outline'>
|
||||||
|
Kembali
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm p-5">
|
<form onSubmit={onSubmit} className="space-y-6">
|
||||||
<CardContent className="p-0">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
<form onSubmit={onSubmit} className="space-y-6 mt-4">
|
<div className="lg:col-span-2 space-y-6">
|
||||||
<FieldGroup>
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
<Field>
|
<CardHeader className="border-b">
|
||||||
<Label htmlFor="name">Nama</Label>
|
<CardTitle>Informasi Produk</CardTitle>
|
||||||
<Input
|
</CardHeader>
|
||||||
id="name"
|
<CardContent className="space-y-6">
|
||||||
name="name"
|
<Field>
|
||||||
value={data.name}
|
<Label htmlFor="name">Nama</Label>
|
||||||
onChange={e => setData('name', e.target.value)}
|
<Input
|
||||||
autoComplete='off'
|
id="name"
|
||||||
placeholder='Contoh: Gamis Wanita'
|
name="name"
|
||||||
maxLength={100}
|
value={data.name}
|
||||||
/>
|
onChange={e => setData('name', e.target.value)}
|
||||||
{errors.name && <p className="text-xs text-red-500">{errors.name}</p>}
|
autoComplete='off'
|
||||||
</Field>
|
placeholder='Contoh: Gamis Wanita'
|
||||||
|
maxLength={100}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
/>
|
||||||
|
{errors.name && <p className="text-xs text-red-500">{errors.name}</p>}
|
||||||
|
</Field>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
|
<CardHeader className="border-b">
|
||||||
|
<CardTitle>Harga Produk</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_purchase">Harga Beli</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_purchase"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.purchase}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
purchase: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.purchase'] && <p className="text-xs text-red-500">{errors['prices.purchase']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_distributor">Harga Distributor</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_distributor"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.distributor}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
distributor: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.distributor'] && <p className="text-xs text-red-500">{errors['prices.distributor']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_agent">Harga Agen</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_agent"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.agent}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
agent: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.agent'] && <p className="text-xs text-red-500">{errors['prices.agent']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_reseller">Harga Reseller</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_reseller"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.reseller}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
reseller: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.reseller'] && <p className="text-xs text-red-500">{errors['prices.reseller']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field className="md:col-span-2">
|
||||||
|
<Label htmlFor="price_retail">Harga Retail</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_retail"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.retail}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
retail: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.retail'] && <p className="text-xs text-red-500">{errors['prices.retail']}</p>}
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
</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>Kategori</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
<Field>
|
<Field>
|
||||||
<Label>Kategori</Label>
|
|
||||||
<Combobox
|
<Combobox
|
||||||
multiple
|
multiple
|
||||||
autoHighlight
|
autoHighlight
|
||||||
@ -118,131 +243,34 @@ export default function ProductCreate({ categories }: { categories: Category[] }
|
|||||||
</ComboboxList>
|
</ComboboxList>
|
||||||
</ComboboxContent>
|
</ComboboxContent>
|
||||||
</Combobox>
|
</Combobox>
|
||||||
{errors.category_ids && <p className="text-xs text-red-500">{errors.category_ids}</p>}
|
{errors.category_ids && <p className="text-xs text-red-500 mt-1">{errors.category_ids}</p>}
|
||||||
</Field>
|
</Field>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
|
<CardHeader className="border-b">
|
||||||
|
<CardTitle>Deskripsi</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
<Field>
|
<Field>
|
||||||
<Label htmlFor="price_purchase">Harga Beli</Label>
|
<SimpleEditor
|
||||||
<NumericFormat
|
value={data.description}
|
||||||
id="price_purchase"
|
onChange={(val) => setData('description', val)}
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.purchase}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
purchase: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
/>
|
||||||
{errors['prices.purchase'] && <p className="text-xs text-red-500">{errors['prices.purchase']}</p>}
|
{errors.description && <p className="text-xs text-red-500 mt-1">{errors.description}</p>}
|
||||||
</Field>
|
</Field>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
<Field>
|
<div className="flex flex-col gap-4 p-4 rounded-xl bg-primary/5 border border-primary/10 shadow-sm">
|
||||||
<Label htmlFor="price_distributor">Harga Distributor</Label>
|
<Button type="submit" className="w-full" disabled={processing}>
|
||||||
<NumericFormat
|
|
||||||
id="price_distributor"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.distributor}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
distributor: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.distributor'] && <p className="text-xs text-red-500">{errors['prices.distributor']}</p>}
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="price_agent">Harga Agen</Label>
|
|
||||||
<NumericFormat
|
|
||||||
id="price_agent"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.agent}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
agent: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.agent'] && <p className="text-xs text-red-500">{errors['prices.agent']}</p>}
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="price_reseller">Harga Reseller</Label>
|
|
||||||
<NumericFormat
|
|
||||||
id="price_reseller"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.reseller}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
reseller: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.reseller'] && <p className="text-xs text-red-500">{errors['prices.reseller']}</p>}
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="price_retail">Harga Retail</Label>
|
|
||||||
<NumericFormat
|
|
||||||
id="price_retail"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.retail}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
retail: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.retail'] && <p className="text-xs text-red-500">{errors['prices.retail']}</p>}
|
|
||||||
</Field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="description">Deskripsi</Label>
|
|
||||||
<SimpleEditor
|
|
||||||
value={data.description}
|
|
||||||
onChange={(val) => setData('description', val)}
|
|
||||||
/>
|
|
||||||
{errors.description && <p className="text-xs text-red-500">{errors.description}</p>}
|
|
||||||
</Field>
|
|
||||||
</FieldGroup>
|
|
||||||
|
|
||||||
<div className="flex gap-4 p-4 mt-6 rounded-lg justify-end">
|
|
||||||
<Link href={productRoutes.index().url}>
|
|
||||||
<Button type="button" variant="outline">Kembali</Button>
|
|
||||||
</Link>
|
|
||||||
<Button type="submit" disabled={processing}>
|
|
||||||
{processing ? 'Menyimpan...' : 'Simpan'}
|
{processing ? 'Menyimpan...' : 'Simpan'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Head, useForm, Link } from '@inertiajs/react';
|
import { Head, useForm, Link } from '@inertiajs/react';
|
||||||
import type { Product, ProductPrice } from '@/types';
|
import type { Product, ProductPrice } from '@/types';
|
||||||
import { Category } from '@/types/category';
|
import { Category } from '@/types/category';
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Field, FieldGroup } from "@/components/ui/field"
|
import { Field, FieldGroup } from "@/components/ui/field"
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input"
|
||||||
@ -66,29 +66,155 @@ export default function ProductEdit({ product, categories }: { product: Product,
|
|||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">Ubah Produk</h1>
|
<h1 className="text-3xl font-bold tracking-tight">Ubah Produk</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<Link href={productRoutes.index().url}>
|
||||||
|
<Button variant='outline'>
|
||||||
|
Kembali
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm p-5">
|
<form onSubmit={onSubmit} className="space-y-6">
|
||||||
<CardContent className="p-0">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
<form onSubmit={onSubmit} className="space-y-6 mt-4">
|
<div className="lg:col-span-2 space-y-6">
|
||||||
<FieldGroup>
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
<Field>
|
<CardHeader className="border-b">
|
||||||
<Label htmlFor="name">Nama</Label>
|
<CardTitle>Informasi Produk</CardTitle>
|
||||||
<Input
|
</CardHeader>
|
||||||
id="name"
|
<CardContent className="space-y-6">
|
||||||
name="name"
|
<Field>
|
||||||
value={data.name}
|
<Label htmlFor="name">Nama</Label>
|
||||||
onChange={e => setData('name', e.target.value)}
|
<Input
|
||||||
autoComplete='off'
|
id="name"
|
||||||
placeholder='Contoh: Gamis Wanita'
|
name="name"
|
||||||
maxLength={100}
|
value={data.name}
|
||||||
/>
|
onChange={e => setData('name', e.target.value)}
|
||||||
{errors.name && <p className="text-xs text-red-500">{errors.name}</p>}
|
autoComplete='off'
|
||||||
</Field>
|
placeholder='Contoh: Gamis Wanita'
|
||||||
|
maxLength={100}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
/>
|
||||||
|
{errors.name && <p className="text-xs text-red-500">{errors.name}</p>}
|
||||||
|
</Field>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
|
<CardHeader className="border-b">
|
||||||
|
<CardTitle>Harga Produk</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_purchase">Harga Beli</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_purchase"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.purchase}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
purchase: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.purchase'] && <p className="text-xs text-red-500">{errors['prices.purchase']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_distributor">Harga Distributor</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_distributor"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.distributor}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
distributor: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.distributor'] && <p className="text-xs text-red-500">{errors['prices.distributor']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_agent">Harga Agen</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_agent"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.agent}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
agent: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.agent'] && <p className="text-xs text-red-500">{errors['prices.agent']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
<Label htmlFor="price_reseller">Harga Reseller</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_reseller"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.reseller}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
reseller: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.reseller'] && <p className="text-xs text-red-500">{errors['prices.reseller']}</p>}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
<Field className="md:col-span-2">
|
||||||
|
<Label htmlFor="price_retail">Harga Retail</Label>
|
||||||
|
<NumericFormat
|
||||||
|
id="price_retail"
|
||||||
|
customInput={Input}
|
||||||
|
thousandSeparator="."
|
||||||
|
decimalSeparator=","
|
||||||
|
prefix="Rp "
|
||||||
|
value={data.prices.retail}
|
||||||
|
onValueChange={(values) => {
|
||||||
|
setData('prices', {
|
||||||
|
...data.prices,
|
||||||
|
retail: values.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
placeholder="Rp 0"
|
||||||
|
/>
|
||||||
|
{errors['prices.retail'] && <p className="text-xs text-red-500">{errors['prices.retail']}</p>}
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Column - 1/3 width */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
|
<CardHeader className="border-b">
|
||||||
|
<CardTitle>Kategori</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
<Field>
|
<Field>
|
||||||
<Label>Kategori</Label>
|
|
||||||
<Combobox
|
<Combobox
|
||||||
multiple
|
multiple
|
||||||
autoHighlight
|
autoHighlight
|
||||||
@ -126,131 +252,36 @@ export default function ProductEdit({ product, categories }: { product: Product,
|
|||||||
</ComboboxList>
|
</ComboboxList>
|
||||||
</ComboboxContent>
|
</ComboboxContent>
|
||||||
</Combobox>
|
</Combobox>
|
||||||
{errors.category_ids && <p className="text-xs text-red-500">{errors.category_ids}</p>}
|
{errors.category_ids && <p className="text-xs text-red-500 mt-1">{errors.category_ids}</p>}
|
||||||
</Field>
|
</Field>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm">
|
||||||
|
<CardHeader className="border-b">
|
||||||
|
<CardTitle>Deskripsi</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
<Field>
|
<Field>
|
||||||
<Label htmlFor="price_purchase">Harga Beli</Label>
|
<SimpleEditor
|
||||||
<NumericFormat
|
value={data.description}
|
||||||
id="price_purchase"
|
onChange={(val) => setData('description', val)}
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.purchase}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
purchase: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
/>
|
||||||
{errors['prices.purchase'] && <p className="text-xs text-red-500">{errors['prices.purchase']}</p>}
|
{errors.description && <p className="text-xs text-red-500 mt-1">{errors.description}</p>}
|
||||||
</Field>
|
</Field>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
<Field>
|
<div className="flex flex-col gap-4 p-4 rounded-xl bg-primary/5 border border-primary/10 shadow-sm">
|
||||||
<Label htmlFor="price_distributor">Harga Distributor</Label>
|
<div className="flex flex-col gap-2">
|
||||||
<NumericFormat
|
<Button type="submit" className="w-full" disabled={processing}>
|
||||||
id="price_distributor"
|
{processing ? 'Menyimpan...' : 'Simpan'}
|
||||||
customInput={Input}
|
</Button>
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.distributor}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
distributor: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.distributor'] && <p className="text-xs text-red-500">{errors['prices.distributor']}</p>}
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="price_agent">Harga Agen</Label>
|
|
||||||
<NumericFormat
|
|
||||||
id="price_agent"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.agent}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
agent: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.agent'] && <p className="text-xs text-red-500">{errors['prices.agent']}</p>}
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="price_reseller">Harga Reseller</Label>
|
|
||||||
<NumericFormat
|
|
||||||
id="price_reseller"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.reseller}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
reseller: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.reseller'] && <p className="text-xs text-red-500">{errors['prices.reseller']}</p>}
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="price_retail">Harga Retail</Label>
|
|
||||||
<NumericFormat
|
|
||||||
id="price_retail"
|
|
||||||
customInput={Input}
|
|
||||||
thousandSeparator="."
|
|
||||||
decimalSeparator=","
|
|
||||||
prefix="Rp "
|
|
||||||
value={data.prices.retail}
|
|
||||||
onValueChange={(values) => {
|
|
||||||
setData('prices', {
|
|
||||||
...data.prices,
|
|
||||||
retail: values.value
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
placeholder="Rp 0"
|
|
||||||
/>
|
|
||||||
{errors['prices.retail'] && <p className="text-xs text-red-500">{errors['prices.retail']}</p>}
|
|
||||||
</Field>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Field>
|
|
||||||
<Label htmlFor="description">Deskripsi</Label>
|
|
||||||
<SimpleEditor
|
|
||||||
value={data.description}
|
|
||||||
onChange={(val) => setData('description', val)}
|
|
||||||
/>
|
|
||||||
{errors.description && <p className="text-xs text-red-500">{errors.description}</p>}
|
|
||||||
</Field>
|
|
||||||
</FieldGroup>
|
|
||||||
|
|
||||||
<div className="flex gap-4 p-4 mt-6 rounded-lg justify-end">
|
|
||||||
<Link href={productRoutes.index().url}>
|
|
||||||
<Button type="button" variant="outline">Kembali</Button>
|
|
||||||
</Link>
|
|
||||||
<Button type="submit" disabled={processing}>
|
|
||||||
{processing ? 'Menyimpan...' : 'Simpan'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user