mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE-Storyless): enhance ProductForm schema and handling, add required fields and improve validation
This commit is contained in:
@@ -1,53 +1,83 @@
|
|||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
|
|
||||||
export const ProductFormSchema = Yup.object({
|
type ProductFormSchemaType = {
|
||||||
name: Yup.string().required('Nama wajib diisi!'),
|
name: string;
|
||||||
brand: Yup.string().required('Merek wajib diisi!'),
|
brand: string;
|
||||||
sku: Yup.string().required('SKU wajib diisi!'),
|
sku: string;
|
||||||
uom: Yup.object({
|
uom?: {
|
||||||
value: Yup.number().min(1).required(),
|
value: number;
|
||||||
label: Yup.string().required(),
|
label: string;
|
||||||
}).nullable(),
|
} | null;
|
||||||
uom_id: Yup.number().required('Satuan wajib diisi!').typeError('Satuan wajib diisi!'),
|
uom_id: number;
|
||||||
product_category: Yup.object({
|
product_category?: {
|
||||||
value: Yup.number().min(1).required(),
|
value: number;
|
||||||
label: Yup.string().required(),
|
label: string;
|
||||||
}).nullable(),
|
} | null;
|
||||||
product_category_id: Yup.number()
|
product_category_id: number;
|
||||||
|
product_price: number | string;
|
||||||
|
selling_price: number | string;
|
||||||
|
tax: number | string;
|
||||||
|
expiry_period: number | string;
|
||||||
|
supplier_ids: number[];
|
||||||
|
flags: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ProductFormSchema: Yup.ObjectSchema<ProductFormSchemaType> =
|
||||||
|
Yup.object({
|
||||||
|
name: Yup.string().required('Nama wajib diisi!'),
|
||||||
|
brand: Yup.string().required('Merek wajib diisi!'),
|
||||||
|
sku: Yup.string().required('SKU wajib diisi!'),
|
||||||
|
|
||||||
|
uom: Yup.object({
|
||||||
|
value: Yup.number().min(1).required(),
|
||||||
|
label: Yup.string().required(),
|
||||||
|
}).nullable().required('Satuan wajib diisi!'),
|
||||||
|
|
||||||
|
uom_id: Yup.number()
|
||||||
|
.required('Satuan wajib diisi!')
|
||||||
|
.typeError('Satuan wajib diisi!'),
|
||||||
|
|
||||||
|
product_category: Yup.object({
|
||||||
|
value: Yup.number().min(1).required(),
|
||||||
|
label: Yup.string().required(),
|
||||||
|
}).nullable().required('Kategori produk wajib diisi!'),
|
||||||
|
|
||||||
|
product_category_id: Yup.number()
|
||||||
.required('Kategori produk wajib diisi!')
|
.required('Kategori produk wajib diisi!')
|
||||||
.typeError('Kategori produk wajib diisi!'),
|
.typeError('Kategori produk wajib diisi!'),
|
||||||
product_price: Yup.number()
|
|
||||||
|
product_price: Yup.number()
|
||||||
.required('Harga produk wajib diisi!')
|
.required('Harga produk wajib diisi!')
|
||||||
.typeError('Harga produk wajib diisi!')
|
.typeError('Harga produk wajib diisi!')
|
||||||
.min(0, 'Harga produk tidak boleh kurang dari 0!'),
|
.min(0, 'Harga produk tidak boleh kurang dari 0!'),
|
||||||
selling_price: Yup.number()
|
|
||||||
|
selling_price: Yup.number()
|
||||||
.required('Harga jual wajib diisi!')
|
.required('Harga jual wajib diisi!')
|
||||||
.typeError('Harga jual wajib diisi!')
|
.typeError('Harga jual wajib diisi!')
|
||||||
.min(0, 'Harga jual tidak boleh kurang dari 0!'),
|
.min(0, 'Harga jual tidak boleh kurang dari 0!'),
|
||||||
tax: Yup.number()
|
|
||||||
|
tax: Yup.number()
|
||||||
.required('Pajak wajib diisi!')
|
.required('Pajak wajib diisi!')
|
||||||
.typeError('Pajak wajib diisi!')
|
.typeError('Pajak wajib diisi!')
|
||||||
.min(0, 'Pajak tidak boleh kurang dari 0!')
|
.min(0, 'Pajak tidak boleh kurang dari 0!')
|
||||||
.max(100, 'Pajak tidak boleh lebih dari 100%!'),
|
.max(100, 'Pajak tidak boleh lebih dari 100%!'),
|
||||||
expiry_period: Yup.number()
|
|
||||||
|
expiry_period: Yup.number()
|
||||||
.required('Periode kadaluarsa wajib diisi!')
|
.required('Periode kadaluarsa wajib diisi!')
|
||||||
.typeError('Periode kadaluarsa wajib diisi!')
|
.typeError('Periode kadaluarsa wajib diisi!')
|
||||||
.min(0, 'Periode kadaluarsa tidak boleh kurang dari 0!'),
|
.min(0, 'Periode kadaluarsa tidak boleh kurang dari 0!'),
|
||||||
supplier: Yup.object({
|
|
||||||
value: Yup.number().min(1).required(),
|
supplier_ids: Yup.array()
|
||||||
label: Yup.string().required(),
|
.of(Yup.number().required().typeError('Supplier tidak valid!'))
|
||||||
}).nullable(),
|
|
||||||
supplier_ids: Yup.array()
|
|
||||||
.of(Yup.number().typeError('Supplier tidak valid!'))
|
|
||||||
.min(1, 'Minimal harus ada 1 supplier!')
|
.min(1, 'Minimal harus ada 1 supplier!')
|
||||||
.required('Supplier wajib diisi!'),
|
.required('Supplier wajib diisi!'),
|
||||||
flags: Yup.array()
|
|
||||||
.of(Yup.string())
|
flags: Yup.array()
|
||||||
|
.of(Yup.string().required())
|
||||||
.min(1, 'Minimal harus ada 1 flag!')
|
.min(1, 'Minimal harus ada 1 flag!')
|
||||||
.required('Flag wajib diisi!'),
|
.required('Flag wajib diisi!'),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const UpdateProductFormSchema = ProductFormSchema;
|
export const UpdateProductFormSchema = ProductFormSchema;
|
||||||
|
|
||||||
export type ProductFormValues = Yup.InferType<typeof ProductFormSchema>;
|
export type ProductFormValues = Yup.InferType<typeof ProductFormSchema>;
|
||||||
|
|
||||||
|
|||||||
@@ -83,20 +83,19 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
sku: initialValues?.sku ?? '',
|
sku: initialValues?.sku ?? '',
|
||||||
uom: initialValues?.uom
|
uom: initialValues?.uom
|
||||||
? { value: initialValues.uom.id, label: initialValues.uom.name }
|
? { value: initialValues.uom.id, label: initialValues.uom.name }
|
||||||
: null,
|
: undefined,
|
||||||
uom_id: initialValues?.uom?.id ?? 0,
|
uom_id: initialValues?.uom?.id ?? 0,
|
||||||
product_category: initialValues?.product_category
|
product_category: initialValues?.product_category
|
||||||
? {
|
? {
|
||||||
value: initialValues.product_category.id,
|
value: initialValues.product_category.id,
|
||||||
label: initialValues.product_category.name,
|
label: initialValues.product_category.name,
|
||||||
}
|
}
|
||||||
: null,
|
: undefined,
|
||||||
product_category_id: initialValues?.product_category?.id ?? 0,
|
product_category_id: initialValues?.product_category?.id ?? 0,
|
||||||
product_price: initialValues?.product_price ?? 0,
|
product_price: initialValues?.product_price ?? '',
|
||||||
selling_price: initialValues?.selling_price ?? 0,
|
selling_price: initialValues?.selling_price ?? '',
|
||||||
tax: initialValues?.tax ?? 0,
|
tax: initialValues?.tax ?? '',
|
||||||
expiry_period: initialValues?.expiry_period ?? 0,
|
expiry_period: initialValues?.expiry_period ?? '',
|
||||||
supplier: null, // not used for payload, just for UI
|
|
||||||
supplier_ids: initialValues?.suppliers?.map((s) => s.id) ?? [],
|
supplier_ids: initialValues?.suppliers?.map((s) => s.id) ?? [],
|
||||||
flags: initialValues?.flags ?? [],
|
flags: initialValues?.flags ?? [],
|
||||||
}),
|
}),
|
||||||
@@ -119,10 +118,10 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
selling_price: parseInt(values.selling_price.toString()) || 0,
|
selling_price: parseInt(values.selling_price.toString()) || 0,
|
||||||
tax: parseInt(values.tax.toString()) || 0,
|
tax: parseInt(values.tax.toString()) || 0,
|
||||||
expiry_period: parseInt(values.expiry_period.toString()) || 0,
|
expiry_period: parseInt(values.expiry_period.toString()) || 0,
|
||||||
supplier_ids: (values.supplier_ids ?? []).filter(
|
supplier_ids: values.supplier_ids.filter(
|
||||||
(id): id is number => typeof id === 'number'
|
(id): id is number => typeof id === 'number'
|
||||||
),
|
),
|
||||||
flags: (values.flags ?? []).filter(
|
flags: values.flags.filter(
|
||||||
(f): f is string => typeof f === 'string'
|
(f): f is string => typeof f === 'string'
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -231,7 +230,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='Nama'
|
label='Nama'
|
||||||
name='name'
|
name='name'
|
||||||
placeholder='Masukkan nama produk'
|
placeholder='Masukkan nama...'
|
||||||
value={formik.values.name}
|
value={formik.values.name}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -243,7 +242,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='Merek'
|
label='Merek'
|
||||||
name='brand'
|
name='brand'
|
||||||
placeholder='Masukkan merek produk'
|
placeholder='Masukkan merek...'
|
||||||
value={formik.values.brand}
|
value={formik.values.brand}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -255,7 +254,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='SKU'
|
label='SKU'
|
||||||
name='sku'
|
name='sku'
|
||||||
placeholder='Masukkan SKU produk'
|
placeholder='Masukkan SKU...'
|
||||||
value={formik.values.sku}
|
value={formik.values.sku}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -266,6 +265,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
required
|
||||||
label='Satuan'
|
label='Satuan'
|
||||||
|
placeholder='Pilih satuan...'
|
||||||
value={formik.values.uom ?? undefined}
|
value={formik.values.uom ?? undefined}
|
||||||
onChange={uomChangeHandler}
|
onChange={uomChangeHandler}
|
||||||
options={uomOptions}
|
options={uomOptions}
|
||||||
@@ -279,6 +279,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
required
|
||||||
label='Kategori Produk'
|
label='Kategori Produk'
|
||||||
|
placeholder='Pilih kategori produk...'
|
||||||
value={formik.values.product_category ?? undefined}
|
value={formik.values.product_category ?? undefined}
|
||||||
onChange={categoryChangeHandler}
|
onChange={categoryChangeHandler}
|
||||||
options={categoryOptions}
|
options={categoryOptions}
|
||||||
@@ -296,7 +297,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='Harga Produk'
|
label='Harga Produk'
|
||||||
name='product_price'
|
name='product_price'
|
||||||
placeholder='Masukkan harga produk'
|
placeholder='Masukkan harga produk...'
|
||||||
value={formik.values.product_price}
|
value={formik.values.product_price}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -316,7 +317,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='Harga Jual'
|
label='Harga Jual'
|
||||||
name='selling_price'
|
name='selling_price'
|
||||||
placeholder='Masukkan harga jual'
|
placeholder='Masukkan harga jual...'
|
||||||
value={formik.values.selling_price}
|
value={formik.values.selling_price}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -336,7 +337,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='Pajak (%)'
|
label='Pajak (%)'
|
||||||
name='tax'
|
name='tax'
|
||||||
placeholder='Masukkan pajak'
|
placeholder='Masukkan pajak...'
|
||||||
value={formik.values.tax}
|
value={formik.values.tax}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -353,7 +354,7 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
required
|
required
|
||||||
label='Periode Kadaluarsa (hari)'
|
label='Periode Kadaluarsa (hari)'
|
||||||
name='expiry_period'
|
name='expiry_period'
|
||||||
placeholder='Masukkan periode kadaluarsa'
|
placeholder='Masukkan periode kadaluarsa...'
|
||||||
value={formik.values.expiry_period}
|
value={formik.values.expiry_period}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
@@ -372,9 +373,10 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
required
|
||||||
label='Supplier'
|
label='Supplier'
|
||||||
|
placeholder='Pilih supplier...'
|
||||||
isMulti
|
isMulti
|
||||||
value={supplierOptions.filter((opt) =>
|
value={supplierOptions.filter((opt) =>
|
||||||
formik.values.supplier_ids.includes(opt.value)
|
(formik.values.supplier_ids || []).includes(opt.value)
|
||||||
)}
|
)}
|
||||||
onChange={supplierChangeHandler}
|
onChange={supplierChangeHandler}
|
||||||
options={supplierOptions}
|
options={supplierOptions}
|
||||||
@@ -391,9 +393,10 @@ const ProductForm = ({ type = 'add', initialValues }: ProductFormProps) => {
|
|||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
required
|
||||||
label='Flags'
|
label='Flags'
|
||||||
|
placeholder='Pilih flags...'
|
||||||
isMulti
|
isMulti
|
||||||
value={PRODUCT_FLAG_OPTIONS.filter((opt) =>
|
value={PRODUCT_FLAG_OPTIONS.filter((opt) =>
|
||||||
formik.values.flags.includes(opt.value)
|
(formik.values.flags || []).includes(opt.value)
|
||||||
)}
|
)}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
const arr = Array.isArray(val) ? val : val ? [val] : [];
|
const arr = Array.isArray(val) ? val : val ? [val] : [];
|
||||||
|
|||||||
Reference in New Issue
Block a user