fix(FE-51-54): fixing bug and layout form adjustment

This commit is contained in:
randy-ar
2025-10-11 23:26:30 +07:00
parent 1fd4b2aba5
commit f662f2951e
10 changed files with 70 additions and 167 deletions
@@ -2,9 +2,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import useSWR from 'swr';
import InventoryAdjustmentForm from '@/components/pages/inventory/adjustment/form/InventoryAdjustmentForm'; import InventoryAdjustmentForm from '@/components/pages/inventory/adjustment/form/InventoryAdjustmentForm';
import { inventoryAdjustmentApi } from '@/services/api/inventory';
import type { InventoryAdjustment } from '@/types/api/inventory/adjustment'; import type { InventoryAdjustment } from '@/types/api/inventory/adjustment';
const DetailInventoryAdjustment = () => { const DetailInventoryAdjustment = () => {
-1
View File
@@ -1,4 +1,3 @@
import InventoryAdjustmentForm from '@/components/pages/inventory/adjustment/form/InventoryAdjustmentForm';
import InventoryAdjustmentTable from '@/components/pages/inventory/adjustment/InventoryAdjustmentTable'; import InventoryAdjustmentTable from '@/components/pages/inventory/adjustment/InventoryAdjustmentTable';
const InventoryAdjustment = () => { const InventoryAdjustment = () => {
+1 -2
View File
@@ -14,7 +14,7 @@ export interface RadioInputProps {
name: string; name: string;
value?: string; value?: string;
options: RadioOption[]; options: RadioOption[];
variant?: string; // contoh: 'radio-primary', 'radio-secondary', dll variant?: string;
className?: { className?: {
wrapper?: string; wrapper?: string;
label?: string; label?: string;
@@ -41,7 +41,6 @@ const RadioInput = ({
variant = 'radio-primary', variant = 'radio-primary',
className, className,
isError, isError,
isValid,
errorMessage, errorMessage,
required = false, required = false,
disabled = false, disabled = false,
@@ -1,11 +1,8 @@
'use client'; 'use client';
import Button from '@/components/Button'; import Button from '@/components/Button';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput'; import SelectInput, { OptionType } from '@/components/input/SelectInput';
import Table from '@/components/Table'; import Table from '@/components/Table';
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
import { ROWS_OPTIONS } from '@/config/constant'; import { ROWS_OPTIONS } from '@/config/constant';
import { isResponseSuccess } from '@/lib/api-helper'; import { isResponseSuccess } from '@/lib/api-helper';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
@@ -14,45 +11,13 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
import { InventoryAdjustment } from '@/types/api/inventory/adjustment'; import { InventoryAdjustment } from '@/types/api/inventory/adjustment';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { import {
CellContext,
ColumnDef, ColumnDef,
ColumnSort, ColumnSort,
SortingState, SortingState,
} from '@tanstack/react-table'; } from '@tanstack/react-table';
import { ChangeEventHandler, useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import useSWR from 'swr'; import useSWR from 'swr';
const RowOptionsMenu = ({
type = 'dropdown',
props,
}: {
type: 'dropdown' | 'collapse';
props: CellContext<InventoryAdjustment, unknown>;
}) => {
return (
<div
tabIndex={type === 'dropdown' ? 0 : undefined}
className={cn(
{
'dropdown-content': type === 'dropdown',
'mt-2': type === 'collapse',
},
'p-2.5 mr-2 flex flex-col gap-1 bg-base-100 rounded-box z-10 border border-black/10 shadow'
)}
>
<Button
href={`/inventory/adjustment/detail?inventoryAdjustmentId=${props.row.original.id}`}
variant='ghost'
color='primary'
className='justify-start text-sm'
>
<Icon icon='mdi:eye-outline' width={16} height={16} />
Detail
</Button>
</div>
);
};
const InventoryAdjustmentTable = () => { const InventoryAdjustmentTable = () => {
const { const {
state: tableFilterState, state: tableFilterState,
@@ -82,15 +47,12 @@ const InventoryAdjustmentTable = () => {
const { const {
data: inventoryAdjustments, data: inventoryAdjustments,
isLoading, isLoading,
mutate: refreshInventoryAdjustments,
} = useSWR( } = useSWR(
`${inventoryAdjustmentApi.basePath}${getTableFilterQueryString()}`, `${inventoryAdjustmentApi.basePath}${getTableFilterQueryString()}`,
inventoryAdjustmentApi.getAllFetcher inventoryAdjustmentApi.getAllFetcher
); );
// State // State
const [selectedInventoryAdjustment, setSelectedInventoryAdjustment] =
useState<InventoryAdjustment | undefined>(undefined);
const [sorting, setSorting] = useState<SortingState>([]); const [sorting, setSorting] = useState<SortingState>([]);
// Columns // Columns
@@ -170,40 +132,9 @@ const InventoryAdjustmentTable = () => {
header: 'Oleh', header: 'Oleh',
accessorFn: (row) => row.created_user?.name ?? '-', accessorFn: (row) => row.created_user?.name ?? '-',
}, },
// {
// id: 'actions',
// header: 'Aksi',
// cell: (props) => {
// const currentPageSize = props.table.getPaginationRowModel().rows.length;
// const currentPageRows = props.table.getPaginationRowModel().flatRows;
// const currentRowRelativeIndex =
// currentPageRows.findIndex((r) => r.id === props.row.id) + 1;
// const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2;
// return (
// <>
// {currentPageSize > 2 && (
// <RowDropdownOptions isLast2Rows={isLast2Rows}>
// <RowOptionsMenu type='dropdown' props={props} />
// </RowDropdownOptions>
// )}
// {currentPageSize <= 2 && (
// <RowCollapseOptions>
// <RowOptionsMenu type='dropdown' props={props} />
// </RowCollapseOptions>
// )}
// </>
// );
// },
// },
]; ];
// Handler // Handler
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
updateFilter('search', e.target.value);
};
const pageSizeChangeHandler = (val: OptionType | OptionType[] | null) => { const pageSizeChangeHandler = (val: OptionType | OptionType[] | null) => {
const newVal = val as OptionType; const newVal = val as OptionType;
setPageSize(newVal.value as number); setPageSize(newVal.value as number);
@@ -240,7 +171,7 @@ const InventoryAdjustmentTable = () => {
updateSortingFilter('productSort', productSortFilter); updateSortingFilter('productSort', productSortFilter);
updateSortingFilter('warehouseSort', warehouseSortFilter); updateSortingFilter('warehouseSort', warehouseSortFilter);
updateSortingFilter('stockSort', stockSortFilter); updateSortingFilter('stockSort', stockSortFilter);
}, [sorting]); }, [sorting, updateSortingFilter]);
// Utils Function // Utils Function
const formatNumber = (value: string) => { const formatNumber = (value: string) => {
@@ -259,7 +190,7 @@ const InventoryAdjustmentTable = () => {
<div className='flex flex-row'> <div className='flex flex-row'>
<Button href='/inventory/adjustment/add' color='primary'> <Button href='/inventory/adjustment/add' color='primary'>
<Icon icon='ic:round-plus' width={24} height={24} /> <Icon icon='ic:round-plus' width={24} height={24} />
Tambah Stock Adjustment Tambah
</Button> </Button>
{/* <DebouncedTextInput {/* <DebouncedTextInput
@@ -4,28 +4,36 @@ export const InventoryAdjustmentFormSchema = Yup.object({
product_category: Yup.object({ product_category: Yup.object({
value: Yup.number().required('ID Kategori Produk wajib diisi!'), value: Yup.number().required('ID Kategori Produk wajib diisi!'),
label: Yup.string().required('Nama Kategori Produk wajib diisi!'), label: Yup.string().required('Nama Kategori Produk wajib diisi!'),
}).nullable(), })
.nullable(),
product_category_id: Yup.number().nullable(), product_category_id: Yup.number().nullable(),
product: Yup.object({ product: Yup.object({
value: Yup.number().required('ID Produk wajib diisi!'), value: Yup.number().required('ID Produk wajib diisi!'),
label: Yup.string().required('Nama Produk wajib diisi!'), label: Yup.string().required('Nama Produk wajib diisi!'),
}).required('Produk wajib diisi!'), })
product_id: Yup.number().required('ID Produk wajib diisi!'), .nullable(),
product_id: Yup.number().nullable(),
warehouse: Yup.object({ warehouse: Yup.object({
value: Yup.number().required('ID Gudang wajib diisi!'), value: Yup.number().required('ID Gudang wajib diisi!'),
label: Yup.string().required('Nama Gudang wajib diisi!'), label: Yup.string().required('Nama Gudang wajib diisi!'),
}).required('Gudang wajib diisi!'), })
warehouse_id: Yup.number().required('ID Gudang wajib diisi!'), .nullable(),
warehouse_id: Yup.number().nullable(),
transaction_type: Yup.string() transaction_type: Yup.string()
.oneOf(['increase', 'decrease'], 'Tipe transaksi tidak valid') .oneOf(['increase', 'decrease'], 'Tipe transaksi tidak valid')
.required('Tipe transaksi wajib diisi'), .required('Tipe transaksi wajib diisi'),
quantity: Yup.number() quantity: Yup.number()
.typeError('Kuantitas harus berupa angka') .typeError('Kuantitas harus berupa angka')
.min(1, 'Minimal kuantitas adalah 1') .min(1, 'Minimal kuantitas adalah 1')
.required('Kuantitas wajib diisi'), .required('Kuantitas wajib diisi'),
note: Yup.string().required('Catatan wajib diisi!'), note: Yup.string().required('Catatan wajib diisi!'),
}); });
@@ -8,7 +8,7 @@ import {
} from '@/types/api/inventory/adjustment'; } from '@/types/api/inventory/adjustment';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { use, useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import { import {
InventoryAdjustmentFormSchema, InventoryAdjustmentFormSchema,
@@ -31,37 +31,7 @@ interface InventoryAdjustmentFormProps {
type?: 'add' | 'edit' | 'detail'; type?: 'add' | 'edit' | 'detail';
initialValues?: InventoryAdjustment; initialValues?: InventoryAdjustment;
} }
// type = 'detail',
// initialValues = {
// id: 1,
// product_warehouse: {
// product: {
// id: 1,
// name: 'Product 1',
// },
// warehouse: {
// id: 1,
// name: 'Warehouse 1',
// },
// quantity: 100,
// product_id: 1,
// warehouse_id: 1,
// id: 1,
// },
// before_quantity: 100,
// after_quantity: 100,
// quantity: 10,
// transaction_type: 'INCREASE',
// note: 'Note',
// created_user: {
// id: 1,
// id_user: 1,
// name: 'User 1',
// email: 'user1@example.com',
// },
// created_at: '2025-10-10T18:51:40.9383Z',
// updated_at: '2025-10-10T18:51:40.9383Z',
// },
const InventoryAdjustmentForm = ({ const InventoryAdjustmentForm = ({
type = 'add', type = 'add',
initialValues, initialValues,
@@ -77,7 +47,6 @@ const InventoryAdjustmentForm = ({
const [disabledProduct, setDisabledProduct] = useState(true); const [disabledProduct, setDisabledProduct] = useState(true);
const [optionsProduct, setOptionsProduct] = useState<OptionType[]>([]); const [optionsProduct, setOptionsProduct] = useState<OptionType[]>([]);
const [quantityLabel, setQuantityLabel] = useState('Tambah Stok'); const [quantityLabel, setQuantityLabel] = useState('Tambah Stok');
const [transactionType, setTransactionType] = useState('increment');
// Submit Handler // Submit Handler
const createInventoryAdjustmentHandler = useCallback( const createInventoryAdjustmentHandler = useCallback(
@@ -99,23 +68,14 @@ const InventoryAdjustmentForm = ({
[router] [router]
); );
const formikInitialValues = useMemo<InventoryAdjustmentFormValues>(() => { const formikInitialValues = useMemo<Partial<InventoryAdjustmentFormValues>>(() => {
return { return {
product_category_id: initialValues?.product_category?.id ?? 0, product_category_id: initialValues?.product_category?.id ?? 0,
product_id: initialValues?.product?.id ?? 0, product_id: initialValues?.product?.id ?? 0,
warehouse_id: initialValues?.warehouse?.id ?? 0, warehouse_id: initialValues?.warehouse?.id ?? 0,
product_category: { product_category: undefined,
value: initialValues?.product_category?.id ?? 0, product: undefined,
label: initialValues?.product_category?.name ?? '', warehouse: undefined,
},
product: {
value: initialValues?.product?.id ?? 0,
label: initialValues?.product?.name ?? '',
},
warehouse: {
value: initialValues?.warehouse?.id ?? 0,
label: initialValues?.warehouse?.name ?? '',
},
quantity: initialValues?.quantity ?? 0, quantity: initialValues?.quantity ?? 0,
transaction_type: initialValues?.transaction_type ?? 'increase', transaction_type: initialValues?.transaction_type ?? 'increase',
note: initialValues?.note ?? '', note: initialValues?.note ?? '',
@@ -125,7 +85,7 @@ const InventoryAdjustmentForm = ({
// Formik // Formik
const formik = useFormik<InventoryAdjustmentFormValues>({ const formik = useFormik<InventoryAdjustmentFormValues>({
enableReinitialize: true, enableReinitialize: true,
initialValues: formikInitialValues, initialValues: formikInitialValues as InventoryAdjustmentFormValues,
validationSchema: InventoryAdjustmentFormSchema, validationSchema: InventoryAdjustmentFormSchema,
onSubmit: async (values) => { onSubmit: async (values) => {
setInventoryAdjustmentFormErrorMessage(''); setInventoryAdjustmentFormErrorMessage('');
@@ -198,10 +158,7 @@ const InventoryAdjustmentForm = ({
setDisabledProduct(disabled); setDisabledProduct(disabled);
if (disabled) { if (disabled) {
formik.setFieldValue('product_id', 0); formik.setFieldValue('product_id', 0);
formik.setFieldValue('product', { formik.setFieldValue('product', null);
value: 0,
label: '',
});
} }
}; };
@@ -219,6 +176,15 @@ const InventoryAdjustmentForm = ({
formik.setFieldValue('warehouse_id', (val as OptionType)?.value); formik.setFieldValue('warehouse_id', (val as OptionType)?.value);
}; };
const resetHandler = () => {
formik.resetForm();
setQuantityLabel('Tambah Stok');
productCategoryChangeHandler(null);
productChangeHandler(null);
warehouseChangeHandler(null);
};
const { setValues: formikSetValues } = formik; const { setValues: formikSetValues } = formik;
// Effect // Effect
@@ -228,28 +194,39 @@ const InventoryAdjustmentForm = ({
String(initialValues.product_warehouse.product.id) String(initialValues.product_warehouse.product.id)
); );
setDisabledProduct(false); setDisabledProduct(false);
formik.setFieldValue('product_id', initialValues.product_warehouse.product.id); formik.setFieldValue(
'product_id',
initialValues.product_warehouse.product.id
);
formik.setFieldValue('product', { formik.setFieldValue('product', {
value: initialValues.product_warehouse.product.id, value: initialValues.product_warehouse.product.id,
label: initialValues.product_warehouse.product.name, label: initialValues.product_warehouse.product.name,
}); });
formik.setFieldValue('warehouse_id', initialValues.product_warehouse.warehouse.id); formik.setFieldValue(
'warehouse_id',
initialValues.product_warehouse.warehouse.id
);
formik.setFieldValue('warehouse', { formik.setFieldValue('warehouse', {
value: initialValues.product_warehouse.warehouse.id, value: initialValues.product_warehouse.warehouse.id,
label: initialValues.product_warehouse.warehouse.name, label: initialValues.product_warehouse.warehouse.name,
}); });
formik.setFieldValue('quantity', initialValues.product_warehouse.quantity); formik.setFieldValue(
formik.setFieldValue('transaction_type', initialValues.transaction_type.toLowerCase()); 'quantity',
initialValues.product_warehouse.quantity
);
formik.setFieldValue(
'transaction_type',
initialValues.transaction_type.toLowerCase()
);
formik.setFieldValue('note', initialValues.note); formik.setFieldValue('note', initialValues.note);
} }
if (initialValues?.transaction_type) { if (initialValues?.transaction_type) {
const type = initialValues.transaction_type.toLowerCase(); const type = initialValues.transaction_type.toLowerCase();
setTransactionType(type);
setQuantityLabel(type === 'increase' ? 'Tambah Stok' : 'Kurangi Stok'); setQuantityLabel(type === 'increase' ? 'Tambah Stok' : 'Kurangi Stok');
} }
}, []); }, [formik, initialValues, setQuantityLabel, setDisabledProduct, setSelectedProductCategories]);
useEffect(() => { useEffect(() => {
// formikSetValues(formikInitialValues); formikSetValues(formikInitialValues as InventoryAdjustmentFormValues);
}, [formikSetValues, formikInitialValues]); }, [formikSetValues, formikInitialValues]);
useEffect(() => { useEffect(() => {
if (isResponseSuccess(products)) { if (isResponseSuccess(products)) {
@@ -284,8 +261,8 @@ const InventoryAdjustmentForm = ({
</Button> </Button>
<h1 className='text-2xl font-bold text-center'> <h1 className='text-2xl font-bold text-center'>
{type === 'add' && 'Tambah Stock Adjustment'} {type === 'add' && 'Tambah Penyesuaian Persediaan'}
{type === 'detail' && 'Detail Stock Adjustment'} {type === 'detail' && 'Detail Penyesuaian Persediaan'}
</h1> </h1>
</header> </header>
@@ -386,6 +363,7 @@ const InventoryAdjustmentForm = ({
errorMessage={formik.errors.quantity as string} errorMessage={formik.errors.quantity as string}
readOnly={type === 'detail'} readOnly={type === 'detail'}
/> />
{/* Radio Button Flag Stock */} {/* Radio Button Flag Stock */}
<RadioInput <RadioInput
name='transaction_type' name='transaction_type'
@@ -397,7 +375,6 @@ const InventoryAdjustmentForm = ({
value={formik.values.transaction_type} value={formik.values.transaction_type}
onChange={(e) => { onChange={(e) => {
formik.handleChange(e); formik.handleChange(e);
// kamu juga bisa menambahkan efek tambahan
setQuantityLabel( setQuantityLabel(
e.target.value === 'increase' ? 'Tambah Stok' : 'Kurangi Stok' e.target.value === 'increase' ? 'Tambah Stok' : 'Kurangi Stok'
); );
@@ -430,31 +407,31 @@ const InventoryAdjustmentForm = ({
<div className='flex flex-row justify-between gap-2 flex-wrap'> <div className='flex flex-row justify-between gap-2 flex-wrap'>
{type !== 'detail' && ( {type !== 'detail' && (
<div className='flex flex-row justify-end gap-2'> <div className='flex flex-row justify-end gap-2'>
<Button type='reset' color='warning' className='px-4'> <Button type='button' color='warning' className='px-4' onClick={resetHandler}>
Reset Reset
</Button> </Button>
<Button <Button
type='submit' type='submit'
color='primary' color='primary'
isLoading={formik.isSubmitting} isLoading={formik.isSubmitting}
disabled={!formik.isValid || formik.isSubmitting} disabled={!formik.isValid || formik.isSubmitting || formik.values.product == undefined}
className='px-4' className='px-4'
> >
Submit Submit
</Button> </Button>
</div> </div>
)} )}
{InventoryAdjustmentFormErrorMessage && (
<div role='alert' className='alert alert-error'>
<Icon
icon='material-symbols:error-outline'
width={24}
height={24}
/>
<span>{InventoryAdjustmentFormErrorMessage}</span>
</div>
)}
</div> </div>
{InventoryAdjustmentFormErrorMessage && (
<div role='alert' className='alert alert-error'>
<Icon
icon='material-symbols:error-outline'
width={24}
height={24}
/>
<span>{InventoryAdjustmentFormErrorMessage}</span>
</div>
)}
</form> </form>
</section> </section>
</> </>
@@ -41,7 +41,6 @@ const CustomerForm = ({
const [customerFormErrorMessage, setCustomerFormErrorMessage] = useState(''); const [customerFormErrorMessage, setCustomerFormErrorMessage] = useState('');
const [isDeleteLoading, setIsDeleteLoading] = useState(false); const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [picSelectInputValue, setPicSelectInputValue] = useState(''); const [picSelectInputValue, setPicSelectInputValue] = useState('');
const [typeSelectInputValue, setTypeSelectInputValue] = useState('');
// Fetch Data // Fetch Data
const picUrl = `${UserApi.basePath}?${new URLSearchParams({ const picUrl = `${UserApi.basePath}?${new URLSearchParams({
@@ -252,7 +251,6 @@ const CustomerForm = ({
} }
onChange={typeChangeHandler} onChange={typeChangeHandler}
options={typeOptions} options={typeOptions}
onInputChange={setTypeSelectInputValue}
isError={formik.touched.type && Boolean(formik.errors.type)} isError={formik.touched.type && Boolean(formik.errors.type)}
errorMessage={formik.errors.type as string} errorMessage={formik.errors.type as string}
isDisabled={formType === 'detail'} isDisabled={formType === 'detail'}
@@ -42,8 +42,6 @@ const SupplierForm = ({
// Setup State // Setup State
const [supplierFormErrorMessage, setSupplierFormErrorMessage] = useState(''); const [supplierFormErrorMessage, setSupplierFormErrorMessage] = useState('');
const [isDeleteLoading, setIsDeleteLoading] = useState(false); const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [typeSelectInputValue, setTypeSelectInputValue] = useState('');
const [categorySelectInputValue, setCategorySelectInputValue] = useState('');
const [hatcheryTagInputValue, setHatcheryTagInputValue] = useState(''); const [hatcheryTagInputValue, setHatcheryTagInputValue] = useState('');
// -- Options data mapping // -- Options data mapping
@@ -108,8 +106,6 @@ const SupplierForm = ({
}; };
// Memo // Memo
console.log('Memo');
console.log(initialValues);
const formikInitialValues = useMemo<SupplierFormValues>(() => { const formikInitialValues = useMemo<SupplierFormValues>(() => {
return { return {
name: initialValues?.name ?? '', name: initialValues?.name ?? '',
@@ -125,7 +121,7 @@ const SupplierForm = ({
account_number: initialValues?.account_number ?? '', account_number: initialValues?.account_number ?? '',
due_date: initialValues?.due_date ?? 1, due_date: initialValues?.due_date ?? 1,
}; };
}, [initialValues]); }, [initialValues, typeOptions, categoryOptions]);
// Formik // Formik
const formik = useFormik<SupplierFormValues>({ const formik = useFormik<SupplierFormValues>({
@@ -260,7 +256,6 @@ const SupplierForm = ({
} }
onChange={typeChangeHandler} onChange={typeChangeHandler}
options={typeOptions} options={typeOptions}
onInputChange={setTypeSelectInputValue}
isError={formik.touched.type && Boolean(formik.errors.type)} isError={formik.touched.type && Boolean(formik.errors.type)}
errorMessage={formik.errors.type as string} errorMessage={formik.errors.type as string}
isDisabled={formType === 'detail'} isDisabled={formType === 'detail'}
@@ -278,7 +273,6 @@ const SupplierForm = ({
} }
onChange={categoryChangeHandler} onChange={categoryChangeHandler}
options={categoryOptions} options={categoryOptions}
onInputChange={setCategorySelectInputValue}
isError={ isError={
formik.touched.category && Boolean(formik.errors.category) formik.touched.category && Boolean(formik.errors.category)
} }
+1 -1
View File
@@ -85,7 +85,7 @@ export const MAIN_DRAWER_LINKS: MAIN_DRAWER_MENU[] = [
icon: 'material-symbols:box-outline-rounded', icon: 'material-symbols:box-outline-rounded',
submenu: [ submenu: [
{ {
title: 'Penyesuaian Stok', title: 'Penyesuaian Persediaan',
link: '/inventory/adjustment', link: '/inventory/adjustment',
icon: 'material-symbols:box-edit-outline-rounded', icon: 'material-symbols:box-edit-outline-rounded',
} }
-1
View File
@@ -1,4 +1,3 @@
import { ProductCategory } from '@/types/api/master-data/product-category';
import { Product } from '@/types/api/master-data/product'; import { Product } from '@/types/api/master-data/product';
import { Warehouse } from '../master-data/warehouse'; import { Warehouse } from '../master-data/warehouse';