add filter order

This commit is contained in:
efrilm 2026-01-30 17:22:18 +07:00
parent f4783236d2
commit 3c13aa897c
2 changed files with 107 additions and 27 deletions

View File

@ -6,6 +6,8 @@ interface OrdersQueryParams {
page?: number
limit?: number
search?: string
date_from?: string
date_to?: string
}
export function useOrders(params: OrdersQueryParams = {}) {

View File

@ -13,8 +13,10 @@ import Checkbox from '@mui/material/Checkbox'
import Chip from '@mui/material/Chip'
import MenuItem from '@mui/material/MenuItem'
import TablePagination from '@mui/material/TablePagination'
import TextField from '@mui/material/TextField'
import type { TextFieldProps } from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { Box, CircularProgress, useTheme } from '@mui/material'
// Third-party Imports
import type { RankingInfo } from '@tanstack/match-sorter-utils'
@ -40,11 +42,10 @@ import { getLocalizedUrl } from '@/utils/i18n'
// Style Imports
import tableStyles from '@core/styles/table.module.css'
import { Box, CircularProgress } from '@mui/material'
import Loading from '../../../../../components/layout/shared/Loading'
import { useOrders } from '../../../../../services/queries/orders'
import { Order } from '../../../../../types/services/order'
import { formatCurrency } from '../../../../../utils/transform'
import { formatCurrency, formatDateDDMMYYYY, formatForInputDate } from '../../../../../utils/transform'
declare module '@tanstack/table-core' {
interface FilterFns {
@ -105,15 +106,28 @@ const DebouncedInput = ({
const columnHelper = createColumnHelper<ECommerceOrderTypeWithAction>()
const OrderListTable = () => {
const theme = useTheme()
// States
const [rowSelection, setRowSelection] = useState({})
const [currentPage, setCurrentPage] = useState(1)
const [pageSize, setPageSize] = useState(10)
const [search, setSearch] = useState('')
// Set default date range to current month
const today = new Date()
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1)
const [filter, setFilter] = useState({
date_from: formatForInputDate(firstDayOfMonth),
date_to: formatForInputDate(today)
})
const { data, isLoading, error, isFetching } = useOrders({
page: currentPage,
limit: pageSize,
date_from: formatDateDDMMYYYY(new Date(filter.date_from)),
date_to: formatDateDDMMYYYY(new Date(filter.date_to)),
search
})
@ -203,6 +217,10 @@ const OrderListTable = () => {
header: 'Discount',
cell: ({ row }) => <Typography>{formatCurrency(row.original.discount_amount)}</Typography>
}),
columnHelper.accessor('created_at', {
header: 'Created At',
cell: ({ row }) => <Typography>{formatDateDDMMYYYY(new Date(row.original.created_at))}</Typography>
}),
columnHelper.accessor('action', {
header: 'Action',
cell: ({ row }) => (
@ -245,21 +263,74 @@ const OrderListTable = () => {
state: {
rowSelection,
pagination: {
pageIndex: currentPage, // <= penting!
pageIndex: currentPage,
pageSize
}
},
enableRowSelection: true, //enable row selection for all rows
enableRowSelection: true,
onRowSelectionChange: setRowSelection,
getCoreRowModel: getCoreRowModel(),
// Disable client-side pagination since we're handling it server-side
manualPagination: true,
pageCount: Math.ceil(totalCount / pageSize)
})
return (
<Card>
<CardContent className='flex justify-between max-sm:flex-col sm:items-center gap-4'>
<CardContent className='flex flex-col gap-4'>
{/* Date Range Filter */}
<div className='flex items-center gap-4 max-sm:flex-col'>
<Typography variant='body2' className='min-w-fit'>
Filter by Date:
</Typography>
<TextField
type='date'
value={filter.date_from}
onChange={e => {
setFilter({
...filter,
date_from: e.target.value
})
setCurrentPage(1)
}}
size='small'
sx={{
'& .MuiOutlinedInput-root': {
'&.Mui-focused fieldset': {
borderColor: 'primary.main'
},
'& fieldset': {
borderColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.22)' : theme.palette.divider
}
}
}}
/>
<Typography>-</Typography>
<TextField
type='date'
value={filter.date_to}
onChange={e => {
setFilter({
...filter,
date_to: e.target.value
})
setCurrentPage(1)
}}
size='small'
sx={{
'& .MuiOutlinedInput-root': {
'&.Mui-focused fieldset': {
borderColor: 'primary.main'
},
'& fieldset': {
borderColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.22)' : theme.palette.divider
}
}
}}
/>
</div>
{/* Search and Actions */}
<div className='flex justify-between max-sm:flex-col sm:items-center gap-4'>
<DebouncedInput
value={search}
onChange={value => setSearch(value as string)}
@ -267,7 +338,12 @@ const OrderListTable = () => {
className='sm:is-auto'
/>
<div className='flex items-center max-sm:flex-col gap-4 max-sm:is-full is-auto'>
<CustomTextField select value={pageSize} onChange={handlePageSizeChange} className='is-[70px] max-sm:is-full'>
<CustomTextField
select
value={pageSize}
onChange={handlePageSizeChange}
className='is-[70px] max-sm:is-full'
>
<MenuItem value='10'>10</MenuItem>
<MenuItem value='25'>25</MenuItem>
<MenuItem value='50'>50</MenuItem>
@ -282,7 +358,9 @@ const OrderListTable = () => {
Export
</Button>
</div>
</div>
</CardContent>
<div className='overflow-x-auto'>
{isLoading ? (
<Loading />