add filter order
This commit is contained in:
parent
f4783236d2
commit
3c13aa897c
@ -6,6 +6,8 @@ interface OrdersQueryParams {
|
|||||||
page?: number
|
page?: number
|
||||||
limit?: number
|
limit?: number
|
||||||
search?: string
|
search?: string
|
||||||
|
date_from?: string
|
||||||
|
date_to?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useOrders(params: OrdersQueryParams = {}) {
|
export function useOrders(params: OrdersQueryParams = {}) {
|
||||||
|
|||||||
@ -13,8 +13,10 @@ import Checkbox from '@mui/material/Checkbox'
|
|||||||
import Chip from '@mui/material/Chip'
|
import Chip from '@mui/material/Chip'
|
||||||
import MenuItem from '@mui/material/MenuItem'
|
import MenuItem from '@mui/material/MenuItem'
|
||||||
import TablePagination from '@mui/material/TablePagination'
|
import TablePagination from '@mui/material/TablePagination'
|
||||||
|
import TextField from '@mui/material/TextField'
|
||||||
import type { TextFieldProps } from '@mui/material/TextField'
|
import type { TextFieldProps } from '@mui/material/TextField'
|
||||||
import Typography from '@mui/material/Typography'
|
import Typography from '@mui/material/Typography'
|
||||||
|
import { Box, CircularProgress, useTheme } from '@mui/material'
|
||||||
|
|
||||||
// Third-party Imports
|
// Third-party Imports
|
||||||
import type { RankingInfo } from '@tanstack/match-sorter-utils'
|
import type { RankingInfo } from '@tanstack/match-sorter-utils'
|
||||||
@ -40,11 +42,10 @@ import { getLocalizedUrl } from '@/utils/i18n'
|
|||||||
|
|
||||||
// Style Imports
|
// Style Imports
|
||||||
import tableStyles from '@core/styles/table.module.css'
|
import tableStyles from '@core/styles/table.module.css'
|
||||||
import { Box, CircularProgress } from '@mui/material'
|
|
||||||
import Loading from '../../../../../components/layout/shared/Loading'
|
import Loading from '../../../../../components/layout/shared/Loading'
|
||||||
import { useOrders } from '../../../../../services/queries/orders'
|
import { useOrders } from '../../../../../services/queries/orders'
|
||||||
import { Order } from '../../../../../types/services/order'
|
import { Order } from '../../../../../types/services/order'
|
||||||
import { formatCurrency } from '../../../../../utils/transform'
|
import { formatCurrency, formatDateDDMMYYYY, formatForInputDate } from '../../../../../utils/transform'
|
||||||
|
|
||||||
declare module '@tanstack/table-core' {
|
declare module '@tanstack/table-core' {
|
||||||
interface FilterFns {
|
interface FilterFns {
|
||||||
@ -105,15 +106,28 @@ const DebouncedInput = ({
|
|||||||
const columnHelper = createColumnHelper<ECommerceOrderTypeWithAction>()
|
const columnHelper = createColumnHelper<ECommerceOrderTypeWithAction>()
|
||||||
|
|
||||||
const OrderListTable = () => {
|
const OrderListTable = () => {
|
||||||
|
const theme = useTheme()
|
||||||
|
|
||||||
// States
|
// States
|
||||||
const [rowSelection, setRowSelection] = useState({})
|
const [rowSelection, setRowSelection] = useState({})
|
||||||
const [currentPage, setCurrentPage] = useState(1)
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
const [pageSize, setPageSize] = useState(10)
|
const [pageSize, setPageSize] = useState(10)
|
||||||
const [search, setSearch] = useState('')
|
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({
|
const { data, isLoading, error, isFetching } = useOrders({
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
limit: pageSize,
|
limit: pageSize,
|
||||||
|
date_from: formatDateDDMMYYYY(new Date(filter.date_from)),
|
||||||
|
date_to: formatDateDDMMYYYY(new Date(filter.date_to)),
|
||||||
search
|
search
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -203,6 +217,10 @@ const OrderListTable = () => {
|
|||||||
header: 'Discount',
|
header: 'Discount',
|
||||||
cell: ({ row }) => <Typography>{formatCurrency(row.original.discount_amount)}</Typography>
|
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', {
|
columnHelper.accessor('action', {
|
||||||
header: 'Action',
|
header: 'Action',
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
@ -245,21 +263,74 @@ const OrderListTable = () => {
|
|||||||
state: {
|
state: {
|
||||||
rowSelection,
|
rowSelection,
|
||||||
pagination: {
|
pagination: {
|
||||||
pageIndex: currentPage, // <= penting!
|
pageIndex: currentPage,
|
||||||
pageSize
|
pageSize
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enableRowSelection: true, //enable row selection for all rows
|
enableRowSelection: true,
|
||||||
onRowSelectionChange: setRowSelection,
|
onRowSelectionChange: setRowSelection,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
// Disable client-side pagination since we're handling it server-side
|
|
||||||
manualPagination: true,
|
manualPagination: true,
|
||||||
pageCount: Math.ceil(totalCount / pageSize)
|
pageCount: Math.ceil(totalCount / pageSize)
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<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
|
<DebouncedInput
|
||||||
value={search}
|
value={search}
|
||||||
onChange={value => setSearch(value as string)}
|
onChange={value => setSearch(value as string)}
|
||||||
@ -267,7 +338,12 @@ const OrderListTable = () => {
|
|||||||
className='sm:is-auto'
|
className='sm:is-auto'
|
||||||
/>
|
/>
|
||||||
<div className='flex items-center max-sm:flex-col gap-4 max-sm:is-full 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='10'>10</MenuItem>
|
||||||
<MenuItem value='25'>25</MenuItem>
|
<MenuItem value='25'>25</MenuItem>
|
||||||
<MenuItem value='50'>50</MenuItem>
|
<MenuItem value='50'>50</MenuItem>
|
||||||
@ -282,7 +358,9 @@ const OrderListTable = () => {
|
|||||||
Export
|
Export
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Loading />
|
<Loading />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user