feat: integrate react-number-format for price inputs in product create and edit forms
This commit is contained in:
parent
4b5d5af316
commit
bfee01153c
1799
package-lock.json
generated
1799
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -82,6 +82,7 @@
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-hotkeys-hook": "^5.2.4",
|
||||
"react-number-format": "^5.4.5",
|
||||
"shadcn": "^4.2.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
|
||||
@ -21,6 +21,7 @@ import {
|
||||
ComboboxValue,
|
||||
useComboboxAnchor,
|
||||
} from "@/components/ui/combobox"
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
|
||||
export default function ProductCreate({ categories }: { categories: Category[] }) {
|
||||
const { data, setData, post, processing, errors } = useForm({
|
||||
@ -122,65 +123,100 @@ export default function ProductCreate({ categories }: { categories: Category[] }
|
||||
|
||||
<Field>
|
||||
<Label htmlFor="price_purchase">Harga Beli</Label>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_purchase"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.purchase}
|
||||
onChange={e => setData('prices', { ...data.prices, purchase: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_distributor"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.distributor}
|
||||
onChange={e => setData('prices', { ...data.prices, distributor: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_agent"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.agent}
|
||||
onChange={e => setData('prices', { ...data.prices, agent: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_reseller"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.reseller}
|
||||
onChange={e => setData('prices', { ...data.prices, reseller: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_retail"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.retail}
|
||||
onChange={e => setData('prices', { ...data.prices, retail: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
|
||||
@ -22,6 +22,7 @@ import {
|
||||
ComboboxValue,
|
||||
useComboboxAnchor,
|
||||
} from "@/components/ui/combobox"
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
|
||||
export default function ProductEdit({ product, categories }: { product: Product, categories: Category[] }) {
|
||||
const getPrice = (type: string) => {
|
||||
@ -130,65 +131,100 @@ export default function ProductEdit({ product, categories }: { product: Product,
|
||||
|
||||
<Field>
|
||||
<Label htmlFor="price_purchase">Harga Beli</Label>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_purchase"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.purchase}
|
||||
onChange={e => setData('prices', { ...data.prices, purchase: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_distributor"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.distributor}
|
||||
onChange={e => setData('prices', { ...data.prices, distributor: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_agent"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.agent}
|
||||
onChange={e => setData('prices', { ...data.prices, agent: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_reseller"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.reseller}
|
||||
onChange={e => setData('prices', { ...data.prices, reseller: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
<Input
|
||||
<NumericFormat
|
||||
id="price_retail"
|
||||
type="number"
|
||||
min="0"
|
||||
customInput={Input}
|
||||
thousandSeparator="."
|
||||
decimalSeparator=","
|
||||
prefix="Rp "
|
||||
value={data.prices.retail}
|
||||
onChange={e => setData('prices', { ...data.prices, retail: e.target.value })}
|
||||
placeholder='0'
|
||||
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>
|
||||
|
||||
@ -4,6 +4,11 @@ import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
import { defineConfig } from 'vite';
|
||||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
@ -13,13 +18,24 @@ export default defineConfig({
|
||||
}),
|
||||
inertia(),
|
||||
react({
|
||||
babel: {
|
||||
plugins: ['babel-plugin-react-compiler'],
|
||||
},
|
||||
// Babel compiler can sometimes cause issues with third-party hooks in React 19
|
||||
// babel: {
|
||||
// plugins: ['babel-plugin-react-compiler'],
|
||||
// },
|
||||
}),
|
||||
tailwindcss(),
|
||||
wayfinder({
|
||||
formVariants: true,
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'react': path.resolve(__dirname, 'node_modules/react'),
|
||||
'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),
|
||||
'@': path.resolve(__dirname, 'resources/js'),
|
||||
},
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ['react-number-format'],
|
||||
},
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user