chore: minor changes

This commit is contained in:
Ephraim Atta-Duncan
2025-06-05 11:41:26 +00:00
parent 9739a0ca96
commit 2c064d5aff
12 changed files with 169 additions and 550 deletions

View File

@ -11,8 +11,6 @@ import { DocumentVisibility } from '../../types/document-visibility';
import { type FindResultResponse } from '../../types/search-params';
import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document';
export type PeriodSelectorValue = '' | TimePeriod;
export type FindDocumentsOptions = {
userId: number;
teamId?: number;
@ -25,7 +23,7 @@ export type FindDocumentsOptions = {
column: keyof Omit<Document, 'document'>;
direction: 'asc' | 'desc';
};
period?: PeriodSelectorValue;
period?: TimePeriod;
senderIds?: number[];
query?: string;
folderId?: string;
@ -236,58 +234,71 @@ export const findDocuments = async ({
if (period && period !== 'all-time') {
const now = DateTime.now();
let startDate: DateTime;
let endDate: DateTime;
switch (period) {
case 'today':
startDate = now.startOf('day');
endDate = now.endOf('day');
break;
case 'yesterday':
startDate = now.minus({ days: 1 }).startOf('day');
endDate = now.minus({ days: 1 }).endOf('day');
break;
case 'this-week':
startDate = now.startOf('week');
endDate = now.endOf('week');
break;
case 'last-week':
startDate = now.minus({ weeks: 1 }).startOf('week');
endDate = now.minus({ weeks: 1 }).endOf('week');
break;
case 'this-month':
startDate = now.startOf('month');
endDate = now.endOf('month');
break;
case 'last-month':
startDate = now.minus({ months: 1 }).startOf('month');
endDate = now.minus({ months: 1 }).endOf('month');
break;
case 'this-quarter':
startDate = now.startOf('quarter');
endDate = now.endOf('quarter');
break;
case 'last-quarter':
startDate = now.minus({ quarters: 1 }).startOf('quarter');
endDate = now.minus({ quarters: 1 }).endOf('quarter');
break;
case 'this-year':
startDate = now.startOf('year');
endDate = now.endOf('year');
break;
case 'last-year':
startDate = now.minus({ years: 1 }).startOf('year');
endDate = now.minus({ years: 1 }).endOf('year');
break;
default:
startDate = now.startOf('day');
endDate = now.endOf('day');
}
const { startDate, endDate } = match(period)
.with('today', () => ({
startDate: now.startOf('day'),
endDate: now.startOf('day').plus({ days: 1 }),
}))
.with('yesterday', () => {
const yesterday = now.minus({ days: 1 });
return {
startDate: yesterday.startOf('day'),
endDate: yesterday.startOf('day').plus({ days: 1 }),
};
})
.with('this-week', () => ({
startDate: now.startOf('week'),
endDate: now.startOf('week').plus({ weeks: 1 }),
}))
.with('last-week', () => {
const lastWeek = now.minus({ weeks: 1 });
return {
startDate: lastWeek.startOf('week'),
endDate: lastWeek.startOf('week').plus({ weeks: 1 }),
};
})
.with('this-month', () => ({
startDate: now.startOf('month'),
endDate: now.startOf('month').plus({ months: 1 }),
}))
.with('last-month', () => {
const lastMonth = now.minus({ months: 1 });
return {
startDate: lastMonth.startOf('month'),
endDate: lastMonth.startOf('month').plus({ months: 1 }),
};
})
.with('this-quarter', () => ({
startDate: now.startOf('quarter'),
endDate: now.startOf('quarter').plus({ quarters: 1 }),
}))
.with('last-quarter', () => {
const lastQuarter = now.minus({ quarters: 1 });
return {
startDate: lastQuarter.startOf('quarter'),
endDate: lastQuarter.startOf('quarter').plus({ quarters: 1 }),
};
})
.with('this-year', () => ({
startDate: now.startOf('year'),
endDate: now.startOf('year').plus({ years: 1 }),
}))
.with('last-year', () => {
const lastYear = now.minus({ years: 1 });
return {
startDate: lastYear.startOf('year'),
endDate: lastYear.startOf('year').plus({ years: 1 }),
};
})
.otherwise(() => ({
startDate: now.startOf('day'),
endDate: now.startOf('day').plus({ days: 1 }),
}));
whereClause.createdAt = {
gte: startDate.toJSDate(),
lte: endDate.toJSDate(),
lt: endDate.toJSDate(),
};
}

View File

@ -1,167 +0,0 @@
import React, { useMemo } from 'react';
import { Trans } from '@lingui/react/macro';
import type {
ColumnDef,
PaginationState,
Table as TTable,
Updater,
VisibilityState,
} from '@tanstack/react-table';
import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
import { Skeleton } from './skeleton';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './table';
export type DataTableChildren<TData> = (_table: TTable<TData>) => React.ReactNode;
export type { ColumnDef as DataTableColumnDef } from '@tanstack/react-table';
export interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
columnVisibility?: VisibilityState;
data: TData[];
perPage?: number;
currentPage?: number;
totalPages?: number;
onPaginationChange?: (_page: number, _perPage: number) => void;
onClearFilters?: () => void;
hasFilters?: boolean;
children?: DataTableChildren<TData>;
skeleton?: {
enable: boolean;
rows: number;
component?: React.ReactNode;
};
error?: {
enable: boolean;
component?: React.ReactNode;
};
}
export function DataTable<TData, TValue>({
columns,
columnVisibility,
data,
error,
perPage,
currentPage,
totalPages,
skeleton,
hasFilters,
onClearFilters,
onPaginationChange,
children,
}: DataTableProps<TData, TValue>) {
const pagination = useMemo<PaginationState>(() => {
if (currentPage !== undefined && perPage !== undefined) {
return {
pageIndex: currentPage - 1,
pageSize: perPage,
};
}
return {
pageIndex: 0,
pageSize: 0,
};
}, [currentPage, perPage]);
const manualPagination = Boolean(currentPage !== undefined && totalPages !== undefined);
const onTablePaginationChange = (updater: Updater<PaginationState>) => {
if (typeof updater === 'function') {
const newState = updater(pagination);
onPaginationChange?.(newState.pageIndex + 1, newState.pageSize);
} else {
onPaginationChange?.(updater.pageIndex + 1, updater.pageSize);
}
};
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
state: {
pagination: manualPagination ? pagination : undefined,
columnVisibility,
},
manualPagination,
pageCount: totalPages,
onPaginationChange: onTablePaginationChange,
});
return (
<>
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
style={{
width: `${cell.column.getSize()}px`,
}}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : error?.enable ? (
<TableRow>
{error.component ?? (
<TableCell colSpan={columns.length} className="h-32 text-center">
<Trans>Something went wrong.</Trans>
</TableCell>
)}
</TableRow>
) : skeleton?.enable ? (
Array.from({ length: skeleton.rows }).map((_, i) => (
<TableRow key={`skeleton-row-${i}`}>{skeleton.component ?? <Skeleton />}</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-32 text-center">
<p>
<Trans>No results found</Trans>
</p>
{hasFilters && onClearFilters !== undefined && (
<button
onClick={() => onClearFilters()}
className="text-foreground mt-1 text-sm"
>
<Trans>Clear filters</Trans>
</button>
)}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
{children && <div className="mt-8 w-full">{children(table)}</div>}
</>
);
}

View File

@ -64,7 +64,7 @@ export function DataTableFacetedFilter<TData, TValue>({
key={option.value}
className={cn(
'rounded-sm border-none px-2 py-0.5 font-normal',
option.bgColor ? option.bgColor : 'variant-secondary',
option.bgColor ? option.bgColor : 'bg-secondary',
)}
>
{option.label}
@ -130,20 +130,6 @@ export function DataTableFacetedFilter<TData, TValue>({
);
})}
</CommandGroup>
{/* Option to clear filters, disabled for now since it makes the ui clanky. */}
{/* {selectedValues.size > 0 && (
<>
<CommandSeparator />
<CommandGroup>
<CommandItem
onSelect={() => column?.setFilterValue(undefined)}
className="justify-center text-center"
>
Clear filters
</CommandItem>
</CommandGroup>
</>
)} */}
</CommandList>
</Command>
</PopoverContent>

View File

@ -44,8 +44,7 @@ export function DataTableSingleFilter<TData, TValue>({
selectedValues,
}: DataTableSingleFilterProps<TData, TValue>) {
const filterValue = column?.getFilterValue() as string[] | undefined;
const selectedValue =
selectedValues?.[0] || (filterValue && filterValue.length > 0 ? filterValue[0] : undefined);
const selectedValue = selectedValues?.[0] || (filterValue?.[0] ?? undefined);
const selectedOption = options.find((option) => option.value === selectedValue);
const handleValueChange = (value: string) => {

View File

@ -29,7 +29,6 @@ import { DataTableToolbar } from './data-table-toolbar';
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
columnVisibility?: VisibilityState;
perPage?: number;
currentPage?: number;
totalPages?: number;
@ -126,7 +125,7 @@ export function DataTable<TData, TValue>({
pagination: manualPagination ? pagination : undefined,
},
manualPagination,
pageCount: totalPages,
pageCount: manualPagination ? totalPages : undefined,
initialState: {
pagination: {
pageSize: 10,

View File

@ -101,15 +101,15 @@ export function getDateRangeForPeriod(
}
export function isDateInPeriod(date: Date, period: TimePeriod): boolean {
const dateTime = DateTime.fromJSDate(date);
if (period === 'all-time') {
return true;
}
const dateTime = DateTime.fromJSDate(date);
const range = getDateRangeForPeriod(period);
if (!range) {
return true;
return false;
}
return dateTime >= range.start && dateTime <= range.end;