feat: use data-table on template pages

This commit is contained in:
Ephraim Atta-Duncan
2025-06-05 10:53:53 +00:00
parent 9ccd8e0397
commit 9739a0ca96
10 changed files with 390 additions and 301 deletions

View File

@ -1,11 +1,11 @@
import type { Table } from '@tanstack/react-table';
import { Calendar, CircleDashedIcon, ListFilter, X, XCircle } from 'lucide-react';
import { Calendar, CircleDashedIcon, Globe, ListFilter, X, XCircle } from 'lucide-react';
import { Button } from '../button';
import { Input } from '../input';
import { DataTableFacetedFilter } from './data-table-faceted-filter';
import { DataTableSingleFilter } from './data-table-single-filter';
import { statuses, timePeriodGroups, timePeriods } from './data/data';
import { sources, statuses, timePeriodGroups, timePeriods } from './data/data';
interface DataTableToolbarProps<TData> {
table: Table<TData>;
@ -14,9 +14,12 @@ interface DataTableToolbarProps<TData> {
selectedStatusValues?: string[];
onTimePeriodFilterChange?: (values: string[]) => void;
selectedTimePeriodValues?: string[];
onSourceFilterChange?: (values: string[]) => void;
selectedSourceValues?: string[];
onResetFilters?: () => void;
isStatusFiltered?: boolean;
isTimePeriodFiltered?: boolean;
isSourceFiltered?: boolean;
}
export function DataTableToolbar<TData>({
@ -26,12 +29,18 @@ export function DataTableToolbar<TData>({
selectedStatusValues,
onTimePeriodFilterChange,
selectedTimePeriodValues,
onSourceFilterChange,
selectedSourceValues,
onResetFilters,
isStatusFiltered,
isTimePeriodFiltered,
isSourceFiltered,
}: DataTableToolbarProps<TData>) {
const isFiltered =
table.getState().columnFilters.length > 0 || isStatusFiltered || isTimePeriodFiltered;
table.getState().columnFilters.length > 0 ||
isStatusFiltered ||
isTimePeriodFiltered ||
isSourceFiltered;
const searchValue = (table.getColumn('title')?.getFilterValue() as string) ?? '';
const handleClearFilter = () => {
@ -91,6 +100,17 @@ export function DataTableToolbar<TData>({
/>
)}
{table.getColumn('source') && (
<DataTableFacetedFilter
column={table.getColumn('source')}
title="Source"
options={sources}
icon={Globe}
onFilterChange={onSourceFilterChange}
selectedValues={selectedSourceValues}
/>
)}
{isFiltered && (
<Button variant="ghost" className="h-8 gap-2" size="sm" onClick={handleReset}>
Reset

View File

@ -40,9 +40,12 @@ interface DataTableProps<TData, TValue> {
selectedStatusValues?: string[];
onTimePeriodFilterChange?: (values: string[]) => void;
selectedTimePeriodValues?: string[];
onSourceFilterChange?: (values: string[]) => void;
selectedSourceValues?: string[];
onResetFilters?: () => void;
isStatusFiltered?: boolean;
isTimePeriodFiltered?: boolean;
isSourceFiltered?: boolean;
skeleton?: {
enable: boolean;
rows: number;
@ -73,9 +76,12 @@ export function DataTable<TData, TValue>({
selectedStatusValues,
onTimePeriodFilterChange,
selectedTimePeriodValues,
onSourceFilterChange,
selectedSourceValues,
onResetFilters,
isStatusFiltered,
isTimePeriodFiltered,
isSourceFiltered,
emptyState,
}: DataTableProps<TData, TValue>) {
const [rowSelection, setRowSelection] = React.useState({});
@ -150,9 +156,12 @@ export function DataTable<TData, TValue>({
selectedStatusValues={selectedStatusValues}
onTimePeriodFilterChange={onTimePeriodFilterChange}
selectedTimePeriodValues={selectedTimePeriodValues}
onSourceFilterChange={onSourceFilterChange}
selectedSourceValues={selectedSourceValues}
onResetFilters={onResetFilters}
isStatusFiltered={isStatusFiltered}
isTimePeriodFiltered={isTimePeriodFiltered}
isSourceFiltered={isSourceFiltered}
/>
{table.getRowModel().rows?.length || error?.enable || skeleton?.enable ? (
<div className="rounded-md border">

View File

@ -1,4 +1,4 @@
import { CheckCircle2, Clock, File, Inbox, XCircle } from 'lucide-react';
import { CheckCircle2, Clock, File, FileText, Inbox, Link, XCircle } from 'lucide-react';
export const statuses = [
{
@ -19,8 +19,8 @@ export const statuses = [
value: 'PENDING',
label: 'Pending',
icon: Clock,
color: 'text-water-700 dark:text-water-300',
bgColor: 'bg-water-100 dark:bg-water-100 text-water-700 dark:text-water-700',
color: 'text-blue-700 dark:text-blue-300',
bgColor: 'bg-blue-100 dark:bg-blue-100 text-blue-700 dark:text-blue-700',
},
{
value: 'COMPLETED',
@ -38,6 +38,23 @@ export const statuses = [
},
];
export const sources = [
{
value: 'TEMPLATE',
label: 'Template',
icon: FileText,
color: 'text-blue-700 dark:text-blue-300',
bgColor: 'bg-blue-100 dark:bg-blue-100 text-blue-700 dark:text-blue-700',
},
{
value: 'DIRECT_LINK',
label: 'Direct Link',
icon: Link,
color: 'text-green-700 dark:text-green-300',
bgColor: 'bg-green-100 dark:bg-green-100 text-green-700 dark:text-green-700',
},
];
export const timePeriods = [
{
value: 'today',

View File

@ -1,17 +1,20 @@
import { DateTime } from 'luxon';
export type TimePeriod =
| 'today'
| 'this-week'
| 'this-month'
| 'this-quarter'
| 'this-year'
| 'yesterday'
| 'last-week'
| 'last-month'
| 'last-quarter'
| 'last-year'
| 'all-time';
export const timePeriods = [
'today',
'this-week',
'this-month',
'this-quarter',
'this-year',
'yesterday',
'last-week',
'last-month',
'last-quarter',
'last-year',
'all-time',
] as const;
export type TimePeriod = (typeof timePeriods)[number];
export function getDateRangeForPeriod(
period: TimePeriod,