feat(FE-169): Slicing UI Index Pengajuan Sales & Define Data Type for Marketing

This commit is contained in:
randy-ar
2025-10-31 13:57:30 +07:00
parent 7ab96fac8b
commit b6991652ac
12 changed files with 253 additions and 1 deletions
@@ -0,0 +1,166 @@
'use client';
import Button from '@/components/Button';
import { OptionType } from '@/components/input/SelectInput';
import Table from '@/components/Table';
import { TableRowSizeSelector } from '@/components/table/TableRowSizeSelector';
import { TableToolbar } from '@/components/table/TableToolbar';
import { ROWS_OPTIONS } from '@/config/constant';
import { cn } from '@/lib/helper';
import { SalesOrder } from '@/types/api/marketing/marketing';
import { Icon } from '@iconify/react';
import { CellContext } from '@tanstack/react-table';
import { useCallback, useState } from 'react';
const RowsOptionsMenu = ({
type = 'dropdown',
props,
deleteClickHandler,
}: {
type: 'dropdown' | 'collapse';
props: CellContext<SalesOrder, unknown>;
deleteClickHandler: () => void;
}) => {
return (
<div
tabIndex={type === 'dropdown' ? 0 : undefined}
className={cn(
{
'dropdown-content': type === 'dropdown',
'mt-2': type === 'collapse',
},
'p-2.5 mr-2 bg-base-100 rounded-box z-10 border border-black/10 shadow'
)}
>
<div className='flex flex-col gap-1'>
<Button
href={`recording/detail/?recordingId=${props.row.original.id}`}
variant='ghost'
color='primary'
className='justify-start text-sm'
>
<Icon icon='mdi:eye-outline' width={16} height={16} />
Detail
</Button>
<Button
href={`recording/detail/edit/?recordingId=${props.row.original.id}`}
variant='ghost'
color='warning'
className='justify-start text-sm'
>
<Icon icon='mdi:pencil-outline' width={16} height={16} />
Edit
</Button>
<Button
onClick={deleteClickHandler}
variant='ghost'
color='error'
className='text-error hover:text-inherit'
>
<Icon
icon='mdi:delete-outline'
width={16}
height={16}
className='justify-start text-sm'
/>
Delete
</Button>
</div>
</div>
);
};
const SalesOrderTable = () => {
const [search, setSearch] = useState('');
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const searchChangeHandler = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value);
setPage(1);
},
[]
);
const pageSizeChangeHandler = useCallback(
(val: OptionType | OptionType[] | null) => {
const newVal = val as OptionType;
setPageSize(newVal.value as number);
setPage(1);
},
[]
);
return (
<div className='flex flex-col gap-4'>
<div className='flex flex-col gap-2 mb-4'>
<TableToolbar
addButton={{
href: 'recording/add',
label: 'Tambah Sales Order',
}}
search={{
value: search,
onChange: searchChangeHandler,
placeholder: 'Cari Sales Order',
}}
/>
<TableRowSizeSelector
value={pageSize}
onChange={pageSizeChangeHandler}
options={ROWS_OPTIONS}
/>
</div>
<Table
data={[]}
columns={[
{
header: '#',
cell: (props) => pageSize * (page - 1) + props.row.index + 1,
},
{
accessorKey: 'so_number',
header: 'No. Order',
},
{
accessorKey: 'tanggal',
header: 'Tanggal',
},
{
accessorKey: 'approval.step_name',
header: 'Status',
},
{
accessorKey: 'customer',
header: 'Customer',
},
{
accessorKey: 'grand_total',
header: 'Grand Total',
},
{
accessorKey: 'product_details',
header: 'Product Details',
},
{
header: 'Aksi',
cell: (props) => {},
},
]}
pageSize={pageSize}
page={page}
onPageChange={setPage}
className={{
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',
}}
/>
</div>
);
};
export default SalesOrderTable;