From 7ceb25ea71dc421b68bcc24a7d006a16e23c52ee Mon Sep 17 00:00:00 2001 From: rstubryan Date: Wed, 8 Oct 2025 15:26:45 +0700 Subject: [PATCH 1/3] feat(FE-62,65): add inventory movement management with API and form validation --- .../movement/form/MovementForm.schema.ts | 67 +++++ src/config/constant.ts | 241 ++++++++++-------- src/services/api/inventory.ts | 12 + src/types/api/inventory/movement.d.ts | 51 ++++ 4 files changed, 262 insertions(+), 109 deletions(-) create mode 100644 src/components/pages/inventory/movement/form/MovementForm.schema.ts create mode 100644 src/services/api/inventory.ts create mode 100644 src/types/api/inventory/movement.d.ts diff --git a/src/components/pages/inventory/movement/form/MovementForm.schema.ts b/src/components/pages/inventory/movement/form/MovementForm.schema.ts new file mode 100644 index 00000000..cdabe355 --- /dev/null +++ b/src/components/pages/inventory/movement/form/MovementForm.schema.ts @@ -0,0 +1,67 @@ +import * as Yup from 'yup'; + +export const MovementFormSchema = Yup.object({ + alasan_transfer: Yup.string() + .required('Alasan Transfer wajib diisi!'), + tanggal_transfer: Yup.date() + .required('Tanggal Transfer wajib diisi!') + .typeError('Tanggal Transfer tidak valid!'), + warehouse_asal: Yup.object({ + value: Yup.number().min(1).required(), + label: Yup.string().required(), + }).nullable(), + warehouse_asal_id: Yup.number() + .required('Gudang Asal wajib diisi!'), + warehouse_tujuan: Yup.object({ + value: Yup.number().min(1).required(), + label: Yup.string().required(), + }).nullable(), + warehouse_tujuan_id: Yup.number() + .required('Gudang Tujuan wajib diisi!'), + alasan: Yup.string() + .required('Alasan wajib diisi!'), + product: Yup.object({ + value: Yup.number().min(1).required(), + label: Yup.string().required(), + }).nullable(), + product_id: Yup.array() + .of(Yup.number()).min(1, 'Pilih minimal 1 produk') + .required('Produk wajib diisi!'), + qty_product: Yup.array() + .of(Yup.number().min(1, 'Kuantitas minimal 1')) + .min(1, 'Pilih minimal 1 produk') + .required('Kuantitas wajib diisi!'), + ekspedisi: Yup.array().of( + Yup.object({ + product: Yup.object({ + value: Yup.number().min(1).required(), + label: Yup.string().required(), + }).nullable(), + product_id: Yup.number() + .required('Produk wajib diisi!'), + qty: Yup.number().min(1, 'Kuantitas minimal 1') + .required('Kuantitas wajib diisi!'), + supplier: Yup.object({ + value: Yup.number().min(1).required(), + label: Yup.string().required(), + }).nullable(), + supplier_id: Yup.number() + .required('Supplier wajib diisi!'), + plat_nomor: Yup.string() + .required('Plat Nomor wajib diisi!'), + no_surat_jalan: Yup.string() + .required('No Surat Jalan wajib diisi!'), + dokumen: Yup.mixed() + .required('Dokumen wajib diisi!'), + biaya_ekspedisi: Yup.number() + .min(0, 'Biaya Ekspedisi minimal 0') + .required('Biaya Ekspedisi wajib diisi!'), + nama_sopir: Yup.string() + .required('Nama Sopir wajib diisi!'), + }) + ).min(1, 'Pilih minimal 1 ekspedisi').required('Ekspedisi wajib diisi!'), +}); + +export const UpdateMovementFormSchema = MovementFormSchema; + +export type MovementFormValues = Yup.InferType; \ No newline at end of file diff --git a/src/config/constant.ts b/src/config/constant.ts index 1fbef81f..870002bf 100644 --- a/src/config/constant.ts +++ b/src/config/constant.ts @@ -1,122 +1,145 @@ export const MAIN_DRAWER_LINKS = [ - { - title: 'Dashboard', - link: '/dashboard', - icon: 'gg:chart', - }, + { + title: 'Dashboard', + link: '/dashboard', + icon: 'gg:chart', + }, - { - title: 'Master Data', - link: '/master-data', - icon: 'majesticons:data-line', - submenu: [ - { - title: 'Product', - link: '/master-data/product', - icon: 'fluent-mdl2:product-variant', - }, - { - title: 'Product Category', - link: '/master-data/product-category', - icon: 'carbon:categories', - }, - { - title: 'Bank', - link: '/master-data/bank', - icon: 'mdi:bank-outline', - }, - { - title: 'Area', - link: '/master-data/area', - icon: 'majesticons:map-marker-area-line', - }, - { - title: 'Location', - link: '/master-data/location', - icon: 'mingcute:location-line', - }, - { - title: 'Kandang', - link: '/master-data/kandang', - icon: 'mdi:farm-home-outline', - }, - { - title: 'Warehouse', - link: '/master-data/warehouse', - icon: 'hugeicons:warehouse', - }, - { - title: 'Customer', - link: '/master-data/customer', - icon: 'ix:customer', - }, - { - title: 'UOM', - link: '/master-data/uom', - icon: 'lsicon:measure-outline', - }, - { - title: 'Non-Stock', - link: '/master-data/nonstock', - icon: 'fluent:box-32-regular', - }, - { - title: 'FCR', - link: '/master-data/FCR', - icon: 'fluent:food-chicken-leg-16-regular', - }, - { - title: 'Supplier', - link: '/master-data/supplier', - icon: 'material-symbols:add-business-outline-rounded', - }, - ], - }, + { + title: 'Persediaan', + link: '/inventory', + icon: 'mdi:warehouse', + submenu: [ + { + title: 'Product', + link: '/inventory/product', + icon: 'mdi:package-variant-closed', + }, + { + title: 'Penyesuaian Stok', + link: '/inventory/adjustment', + icon: 'mdi:database-edit', + }, + { + title: 'Transfer Stok', + link: '/inventory/movement', + icon: 'mdi:swap-horizontal', + }, + ], + }, + + { + title: 'Master Data', + link: '/master-data', + icon: 'majesticons:data-line', + submenu: [ + { + title: 'Product', + link: '/master-data/product', + icon: 'fluent-mdl2:product-variant', + }, + { + title: 'Product Category', + link: '/master-data/product-category', + icon: 'carbon:categories', + }, + { + title: 'Bank', + link: '/master-data/bank', + icon: 'mdi:bank-outline', + }, + { + title: 'Area', + link: '/master-data/area', + icon: 'majesticons:map-marker-area-line', + }, + { + title: 'Location', + link: '/master-data/location', + icon: 'mingcute:location-line', + }, + { + title: 'Kandang', + link: '/master-data/kandang', + icon: 'mdi:farm-home-outline', + }, + { + title: 'Warehouse', + link: '/master-data/warehouse', + icon: 'hugeicons:warehouse', + }, + { + title: 'Customer', + link: '/master-data/customer', + icon: 'ix:customer', + }, + { + title: 'UOM', + link: '/master-data/uom', + icon: 'lsicon:measure-outline', + }, + { + title: 'Non-Stock', + link: '/master-data/nonstock', + icon: 'fluent:box-32-regular', + }, + { + title: 'FCR', + link: '/master-data/FCR', + icon: 'fluent:food-chicken-leg-16-regular', + }, + { + title: 'Supplier', + link: '/master-data/supplier', + icon: 'material-symbols:add-business-outline-rounded', + }, + ], + }, ] as const; export const ROWS_OPTIONS = [ - { - label: '10', - value: 10, - }, - { - label: '20', - value: 20, - }, - { - label: '50', - value: 50, - }, - { - label: '100', - value: 100, - }, + { + label: '10', + value: 10, + }, + { + label: '20', + value: 20, + }, + { + label: '50', + value: 50, + }, + { + label: '100', + value: 100, + }, ]; export const WAREHOUSE_TYPE_OPTIONS = [ - { - label: 'AREA', - value: 'AREA', - }, - { - label: 'LOKASI', - value: 'LOKASI', - }, - { - label: 'KANDANG', - value: 'KANDANG', - }, + { + label: 'AREA', + value: 'AREA', + }, + { + label: 'LOKASI', + value: 'LOKASI', + }, + { + label: 'KANDANG', + value: 'KANDANG', + }, ]; export const PRODUCT_FLAG_OPTIONS = [ - { label: 'DOC', value: 'DOC' }, - { label: 'PAKAN', value: 'PAKAN' }, - { label: 'PRE-STARTER', value: 'PRE-STARTER' }, - { label: 'STARTER', value: 'STARTER' }, - { label: 'FINISHER', value: 'FINISHER' }, - { label: 'OVK', value: 'OVK' }, - { label: 'OBAT', value: 'OBAT' }, - { label: 'VITAMIN', value: 'VITAMIN' }, - { label: 'KIMIA', value: 'KIMIA' }, + {label: 'DOC', value: 'DOC'}, + {label: 'PAKAN', value: 'PAKAN'}, + {label: 'PRE-STARTER', value: 'PRE-STARTER'}, + {label: 'STARTER', value: 'STARTER'}, + {label: 'FINISHER', value: 'FINISHER'}, + {label: 'OVK', value: 'OVK'}, + {label: 'OBAT', value: 'OBAT'}, + {label: 'VITAMIN', value: 'VITAMIN'}, + {label: 'KIMIA', value: 'KIMIA'}, ]; diff --git a/src/services/api/inventory.ts b/src/services/api/inventory.ts new file mode 100644 index 00000000..3e3115e2 --- /dev/null +++ b/src/services/api/inventory.ts @@ -0,0 +1,12 @@ +import { + CreateMovementPayload, + Movement, + UpdateMovementPayload, +} from "@/types/api/inventory/movement"; +import {BaseApiService} from "@/services/api/base"; + +export const MovementApi = new BaseApiService< + Movement, + CreateMovementPayload, + UpdateMovementPayload +>('/inventory/movements'); \ No newline at end of file diff --git a/src/types/api/inventory/movement.d.ts b/src/types/api/inventory/movement.d.ts new file mode 100644 index 00000000..fe2996ba --- /dev/null +++ b/src/types/api/inventory/movement.d.ts @@ -0,0 +1,51 @@ +import {BaseMetadata} from '@/types/api/api-general'; +import {Product} from "@/types/api/master-data/product"; +import {Supplier} from "@/types/api/master-data/supplier"; +import {Warehouse} from "@/types/api/master-data/warehouse"; + +export type BaseMovement = { + id: number; + alasan_transfer: string; + tanggal_transfer: string; + warehouse_asal: Warehouse; + warehouse_tujuan: Warehouse; + product: Array<{ + product: Product; + qty_product: number; + }>; + ekspedisi: Array<{ + product_id: number; + qty: number; + supplier: Supplier; + plat_nomor: string; + no_surat_jalan: string; + dokumen: string; + biaya_ekspedisi: number; + nama_sopir: string; + }>; + name: string; +}; + +export type Movement = BaseMetadata & BaseMovement; + +export type CreateMovementPayload = { + alasan: string; + warehouse_asal_id: number; + warehouse_tujuan_id: number; + product: Array<{ + product_id: number; + qty_product: number; + }>; + ekspedisi: Array<{ + product_id: number; + qty: number; + supplier_id: number; + plat_nomor: string; + no_surat_jalan: string; + dokumen: string; + biaya_ekspedisi: number; + nama_sopir: string; + }>; +} + +export type UpdateMovementPayload = CreateMovementPayload; \ No newline at end of file From 3f97ec45f8b14d8c77347ad5104540c647b4d926 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Wed, 8 Oct 2025 16:02:52 +0700 Subject: [PATCH 2/3] feat(FE-64): add MovementTable component for inventory movement management --- src/app/inventory/movement/page.tsx | 11 + .../inventory/movement/MovementTable.tsx | 651 ++++++++++++++++++ 2 files changed, 662 insertions(+) create mode 100644 src/app/inventory/movement/page.tsx create mode 100644 src/components/pages/inventory/movement/MovementTable.tsx diff --git a/src/app/inventory/movement/page.tsx b/src/app/inventory/movement/page.tsx new file mode 100644 index 00000000..12fe795b --- /dev/null +++ b/src/app/inventory/movement/page.tsx @@ -0,0 +1,11 @@ +import MovementTable from '@/components/pages/inventory/movement/MovementTable'; + +const Product = () => { + return ( +
+ +
+ ); +}; + +export default Product; diff --git a/src/components/pages/inventory/movement/MovementTable.tsx b/src/components/pages/inventory/movement/MovementTable.tsx new file mode 100644 index 00000000..288cb2a6 --- /dev/null +++ b/src/components/pages/inventory/movement/MovementTable.tsx @@ -0,0 +1,651 @@ +'use client'; + +import { useState, useMemo } from 'react'; +import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table'; +import { Icon } from '@iconify/react'; +import Table from '@/components/Table'; +import DebouncedTextInput from '@/components/input/DebouncedTextInput'; +import Button from '@/components/Button'; +import { useModal } from '@/components/Modal'; +import ConfirmationModal from '@/components/modal/ConfirmationModal'; +import SelectInput, { OptionType } from '@/components/input/SelectInput'; +import RowDropdownOptions from '@/components/table/RowDropdownOptions'; +import RowCollapseOptions from '@/components/table/RowCollapseOptions'; +import { cn } from '@/lib/helper'; +import { ROWS_OPTIONS } from '@/config/constant'; +import { Movement } from '@/types/api/inventory/movement'; +import { BaseMetadata } from '@/types/api/api-general'; + +// Dummy data +const baseMetadata: BaseMetadata = { + created_user: { + id: 1, + id_user: 1, + email: 'user@example.com', + name: 'User', + }, + created_at: '2024-06-01T00:00:00Z', + updated_at: '2024-06-01T00:00:00Z', +}; + +const dummyMovements: Movement[] = [ + { + ...baseMetadata, + id: 1, + alasan_transfer: 'Restock', + tanggal_transfer: '2024-06-01', + warehouse_asal: { + ...baseMetadata, + id: 1, + name: 'Warehouse A', + type: 'AREA', + area: { id: 1, name: 'Area 1' }, + }, + warehouse_tujuan: { + ...baseMetadata, + id: 2, + name: 'Warehouse B', + type: 'AREA', + area: { id: 2, name: 'Area 2' }, + }, + product: [ + { + product: { + ...baseMetadata, + id: 1, + name: 'Product X', + brand: 'Brand X', + sku: 'SKU-X', + product_price: 10000, + selling_price: 12000, + tax: 10, + expiry_period: 365, + uom: { + ...baseMetadata, + id: 1, + name: 'PCS', + }, + product_category: { + ...baseMetadata, + id: 1, + code: 'CAT-1', + name: 'Category 1', + }, + suppliers: [], + flags: [], + }, + qty_product: 10, + }, + ], + ekspedisi: [ + { + product_id: 1, + qty: 10, + supplier: { + ...baseMetadata, + id: 1, + name: 'Supplier 1', + alias: 'S1', + category: 'General', + pic: 'PIC 1', + type: 'Type 1', + phone: '08123456789', + email: 'supplier1@example.com', + address: 'Address 1', + account_number: '1234567890', + balance: 0, + due_date: 30, + }, + plat_nomor: 'B 1234 CD', + no_surat_jalan: 'SJ-001', + dokumen: 'doc1.pdf', + biaya_ekspedisi: 50000, + nama_sopir: 'Andi', + }, + ], + name: 'Movement 1', + }, + { + ...baseMetadata, + id: 2, + alasan_transfer: 'Mutasi Stok', + tanggal_transfer: '2024-06-02', + warehouse_asal: { + ...baseMetadata, + id: 2, + name: 'Warehouse B', + type: 'AREA', + area: { id: 2, name: 'Area 2' }, + }, + warehouse_tujuan: { + ...baseMetadata, + id: 3, + name: 'Warehouse C', + type: 'AREA', + area: { id: 3, name: 'Area 3' }, + }, + product: [ + { + product: { + ...baseMetadata, + id: 2, + name: 'Product Y', + brand: 'Brand Y', + sku: 'SKU-Y', + product_price: 20000, + selling_price: 25000, + tax: 5, + expiry_period: 180, + uom: { + ...baseMetadata, + id: 2, + name: 'BOX', + }, + product_category: { + ...baseMetadata, + id: 2, + code: 'CAT-2', + name: 'Category 2', + }, + suppliers: [], + flags: [], + }, + qty_product: 5, + }, + ], + ekspedisi: [ + { + product_id: 2, + qty: 5, + supplier: { + ...baseMetadata, + id: 2, + name: 'Supplier 2', + alias: 'S2', + category: 'Special', + pic: 'PIC 2', + type: 'Type 2', + phone: '08123456780', + email: 'supplier2@example.com', + address: 'Address 2', + account_number: '1234567891', + balance: 1000, + due_date: 15, + }, + plat_nomor: 'D 5678 EF', + no_surat_jalan: 'SJ-002', + dokumen: 'doc2.pdf', + biaya_ekspedisi: 60000, + nama_sopir: 'Budi', + }, + ], + name: 'Movement 2', + }, + { + ...baseMetadata, + id: 3, + alasan_transfer: 'Pengembalian', + tanggal_transfer: '2024-06-03', + warehouse_asal: { + ...baseMetadata, + id: 3, + name: 'Warehouse C', + type: 'AREA', + area: { id: 3, name: 'Area 3' }, + }, + warehouse_tujuan: { + ...baseMetadata, + id: 1, + name: 'Warehouse A', + type: 'AREA', + area: { id: 1, name: 'Area 1' }, + }, + product: [ + { + product: { + ...baseMetadata, + id: 3, + name: 'Product Z', + brand: 'Brand Z', + sku: 'SKU-Z', + product_price: 15000, + selling_price: 18000, + tax: 8, + expiry_period: 90, + uom: { + ...baseMetadata, + id: 3, + name: 'KG', + }, + product_category: { + ...baseMetadata, + id: 3, + code: 'CAT-3', + name: 'Category 3', + }, + suppliers: [], + flags: [], + }, + qty_product: 8, + }, + ], + ekspedisi: [ + { + product_id: 3, + qty: 8, + supplier: { + ...baseMetadata, + id: 3, + name: 'Supplier 3', + alias: 'S3', + category: 'Return', + pic: 'PIC 3', + type: 'Type 3', + phone: '08123456781', + email: 'supplier3@example.com', + address: 'Address 3', + account_number: '1234567892', + balance: 500, + due_date: 10, + }, + plat_nomor: 'F 9101 GH', + no_surat_jalan: 'SJ-003', + dokumen: 'doc3.pdf', + biaya_ekspedisi: 40000, + nama_sopir: 'Cici', + }, + ], + name: 'Movement 3', + }, + { + ...baseMetadata, + id: 4, + alasan_transfer: 'Transfer Internal', + tanggal_transfer: '2024-06-04', + warehouse_asal: { + ...baseMetadata, + id: 4, + name: 'Warehouse D', + type: 'AREA', + area: { id: 4, name: 'Area 4' }, + }, + warehouse_tujuan: { + ...baseMetadata, + id: 5, + name: 'Warehouse E', + type: 'AREA', + area: { id: 5, name: 'Area 5' }, + }, + product: [ + { + product: { + ...baseMetadata, + id: 4, + name: 'Product A', + brand: 'Brand A', + sku: 'SKU-A', + product_price: 5000, + selling_price: 7000, + tax: 0, + expiry_period: 60, + uom: { + ...baseMetadata, + id: 4, + name: 'LITER', + }, + product_category: { + ...baseMetadata, + id: 4, + code: 'CAT-4', + name: 'Category 4', + }, + suppliers: [], + flags: [], + }, + qty_product: 20, + }, + ], + ekspedisi: [ + { + product_id: 4, + qty: 20, + supplier: { + ...baseMetadata, + id: 4, + name: 'Supplier 4', + alias: 'S4', + category: 'Internal', + pic: 'PIC 4', + type: 'Type 4', + phone: '08123456782', + email: 'supplier4@example.com', + address: 'Address 4', + account_number: '1234567893', + balance: 200, + due_date: 20, + }, + plat_nomor: 'H 2345 IJ', + no_surat_jalan: 'SJ-004', + dokumen: 'doc4.pdf', + biaya_ekspedisi: 30000, + nama_sopir: 'Dedi', + }, + ], + name: 'Movement 4', + }, + { + ...baseMetadata, + id: 5, + alasan_transfer: 'Distribusi', + tanggal_transfer: '2024-06-05', + warehouse_asal: { + ...baseMetadata, + id: 5, + name: 'Warehouse E', + type: 'AREA', + area: { id: 5, name: 'Area 5' }, + }, + warehouse_tujuan: { + ...baseMetadata, + id: 1, + name: 'Warehouse A', + type: 'AREA', + area: { id: 1, name: 'Area 1' }, + }, + product: [ + { + product: { + ...baseMetadata, + id: 5, + name: 'Product B', + brand: 'Brand B', + sku: 'SKU-B', + product_price: 8000, + selling_price: 9500, + tax: 2, + expiry_period: 120, + uom: { + ...baseMetadata, + id: 5, + name: 'PAK', + }, + product_category: { + ...baseMetadata, + id: 5, + code: 'CAT-5', + name: 'Category 5', + }, + suppliers: [], + flags: [], + }, + qty_product: 15, + }, + ], + ekspedisi: [ + { + product_id: 5, + qty: 15, + supplier: { + ...baseMetadata, + id: 5, + name: 'Supplier 5', + alias: 'S5', + category: 'Distribusi', + pic: 'PIC 5', + type: 'Type 5', + phone: '08123456783', + email: 'supplier5@example.com', + address: 'Address 5', + account_number: '1234567894', + balance: 300, + due_date: 25, + }, + plat_nomor: 'K 6789 KL', + no_surat_jalan: 'SJ-005', + dokumen: 'doc5.pdf', + biaya_ekspedisi: 70000, + nama_sopir: 'Eka', + }, + ], + name: 'Movement 5', + }, +]; + +const RowOptionsMenu = ({ + type = 'dropdown', + props, + deleteClickHandler, +}: { + type: 'dropdown' | 'collapse'; + props: CellContext; + deleteClickHandler: () => void; +}) => ( +
+ + + +
+); + +const MovementTable = () => { + const [search, setSearch] = useState(''); + const [page, setPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [sorting, setSorting] = useState([]); + const [selectedMovement, setSelectedMovement] = useState< + Movement | undefined + >(undefined); + const [isDeleteLoading, setIsDeleteLoading] = useState(false); + + const paginatedData = useMemo(() => { + const start = (page - 1) * pageSize; + return dummyMovements.slice(start, start + pageSize); + }, [page, pageSize]); + + const movementsColumns: ColumnDef[] = [ + { + header: '#', + cell: (props) => pageSize * (page - 1) + props.row.index + 1, + }, + { + accessorKey: 'warehouse_asal', + header: 'Gudang Asal', + cell: (props) => props.row.original.warehouse_asal.name, + }, + { + accessorKey: 'warehouse_tujuan', + header: 'Gudang Tujuan', + cell: (props) => props.row.original.warehouse_tujuan.name, + }, + { + accessorKey: 'product', + header: 'Nama Produk', + cell: (props) => props.row.original.product.map((p) => p.product.name), + }, + { + accessorKey: 'alasan_transfer', + header: 'Catatan', + }, + { + accessorKey: 'biaya_ekspedisi', + header: 'Biaya Ekspedisi', + cell: (props) => + props.row.original.ekspedisi.map((e) => e.biaya_ekspedisi), + }, + { + 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; + + const deleteClickHandler = () => { + setSelectedMovement(props.row.original); + deleteModal.openModal(); + }; + + return ( + <> + {currentPageSize > 2 && ( + + + + )} + {currentPageSize <= 2 && ( + + + + )} + + ); + }, + }, + ]; + + const deleteModal = useModal(); + const confirmationModalDeleteClickHandler = async () => { + setIsDeleteLoading(true); + setTimeout(() => { + setIsDeleteLoading(false); + deleteModal.closeModal(); + }, 1000); + }; + + const searchChangeHandler: React.ChangeEventHandler = ( + e + ) => { + setSearch(e.target.value); + setPage(1); + }; + + const pageSizeChangeHandler = (val: OptionType | OptionType[] | null) => { + const newVal = val as OptionType; + setPageSize(newVal.value as number); + setPage(1); + }; + + return ( + <> +
+
+
+
+ +
+ +
+
+ +
+
+ + data={paginatedData} + columns={movementsColumns} + pageSize={pageSize} + page={page} + totalItems={dummyMovements.length} + onPageChange={setPage} + isLoading={false} + sorting={sorting} + setSorting={setSorting} + className={{ + containerClassName: cn({ + 'mb-20': paginatedData.length === 0, + }), + tableWrapperClassName: 'overflow-x-auto min-h-full!', + tableClassName: 'font-inter w-full table-auto min-h-full!', + headerRowClassName: 'border-b border-b-gray-200', + headerColumnClassName: + 'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end', + bodyRowClassName: 'border-b border-b-gray-200', + bodyColumnClassName: + 'px-6 py-3 last:flex last:flex-row last:justify-end', + }} + /> +
+ + + ); +}; + +export default MovementTable; From ddbf8b0896618e5810108f4dde360ceaa69f7707 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Wed, 8 Oct 2025 16:16:12 +0700 Subject: [PATCH 3/3] refactor(FE-62): rename Product component to Movement for clarity --- src/app/inventory/movement/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/inventory/movement/page.tsx b/src/app/inventory/movement/page.tsx index 12fe795b..a2c25612 100644 --- a/src/app/inventory/movement/page.tsx +++ b/src/app/inventory/movement/page.tsx @@ -1,6 +1,6 @@ import MovementTable from '@/components/pages/inventory/movement/MovementTable'; -const Product = () => { +const Movement = () => { return (
@@ -8,4 +8,4 @@ const Product = () => { ); }; -export default Product; +export default Movement;