chore(dependencies): update multiple packages to latest versions (#342)

- Upgraded `@types/react` to `19.1.12` and `@types/react-dom` to `19.1.9` for improved type definitions.
- Bumped `react-i18next` to `^15.7.3` for localization fixes.
- Updated `@manypkg/cli` to `^0.25.1` for dependency management improvements.
- Incremented `@sentry/nextjs` to `^10.8.0` and `stripe` to `^18.5.0` to incorporate recent enhancements.
- Adjusted `ai` to `5.0.28` and `@ai-sdk/openai` to `^2.0.23` for AI-related updates.
- Introduced sorting improvements and code examples in `DataTable` for server-side and client-side capabilities.
This commit is contained in:
Giancarlo Buomprisco
2025-08-29 21:25:36 +07:00
committed by GitHub
parent 9ce150609e
commit caf86ce09b
26 changed files with 1287 additions and 984 deletions

View File

@@ -68,6 +68,101 @@ interface DataTableControls {
enableColumnVisibility: boolean;
}
// Server-side sorting example component
function ServerSideSortingExample({
data,
compact = false,
}: {
data: User[];
compact?: boolean;
}) {
const [sorting, setSorting] = useState<{ id: string; desc: boolean }[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [lastSortAction, setLastSortAction] = useState<string>('');
const handleSortingChange = (newSorting: { id: string; desc: boolean }[]) => {
setSorting(newSorting);
setIsLoading(true);
// Simulate server request
const sortInfo =
newSorting.length > 0
? `${newSorting[0].id} ${newSorting[0].desc ? 'DESC' : 'ASC'}`
: 'No sorting';
setLastSortAction(`Server request would be: ORDER BY ${sortInfo}`);
// Simulate loading delay
setTimeout(() => {
setIsLoading(false);
}, 800);
};
const columns: ColumnDef<User>[] = [
{
accessorKey: 'name',
header: 'Name',
enableSorting: true,
},
{
accessorKey: 'department',
header: 'Department',
enableSorting: true,
},
{
accessorKey: 'salary',
header: 'Salary',
enableSorting: true,
cell: ({ row }) => {
const salary = row.getValue('salary') as number;
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
}).format(salary);
},
},
];
return (
<div className="space-y-3">
{!compact && (
<div className="space-y-2 text-xs">
<div className="flex items-center gap-2">
<span className="font-semibold">Current Sort State:</span>
<code className="rounded bg-slate-100 px-2 py-1 text-xs">
{sorting.length > 0
? `${sorting[0].id}: ${sorting[0].desc ? 'desc' : 'asc'}`
: 'none'}
</code>
{isLoading && (
<span className="animate-pulse text-blue-600"> Loading...</span>
)}
</div>
{lastSortAction && (
<div className="text-xs text-slate-600">🔍 {lastSortAction}</div>
)}
</div>
)}
<div className={compact ? 'h-full' : 'h-64 rounded border'}>
<DataTable
columns={columns}
data={data}
pageSize={data.length}
pageCount={1}
getRowId={(row) => row.id}
manualSorting={true} // This is the key difference!
sorting={sorting}
onSortingChange={handleSortingChange}
sticky={!compact}
className={isLoading ? 'opacity-50' : ''}
/>
</div>
</div>
);
}
export function DataTableStory() {
const { controls, updateControl } = useStoryControls<DataTableControls>({
dataCount: 50,
@@ -291,6 +386,7 @@ export function DataTableStory() {
pageCount={Math.ceil(data.length / controls.pageSize)}
sticky={controls.stickyHeader}
forcePagination={true}
manualSorting={false} // Enable client-side sorting for demo
columnVisibility={
controls.enableColumnVisibility
? columnManagement.columnVisibility
@@ -1397,6 +1493,154 @@ export function DataTableStory() {
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Server-Side Sorting (Manual Sorting)</CardTitle>
<CardDescription>
Demonstrates server-side sorting with manualSorting=true. Click
headers to see sorting state, but data doesn't change (would
require server integration).
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
<p className="text-sm text-blue-800">
<strong>Server-Side Mode:</strong> This table has
manualSorting=true (default). Clicking column headers triggers
onSortingChange callback where you would fetch sorted data
from your server. The table shows current sort state but
doesn't modify data locally.
</p>
</div>
<ServerSideSortingExample data={data.slice(0, 10)} />
<div className="text-muted-foreground space-y-2 text-xs">
<p>💡 Server-side sorting pattern:</p>
<ul className="ml-4 list-disc space-y-1">
<li>
Use onSortingChange to detect sort column/direction changes
</li>
<li>Send sorting parameters to your API endpoint</li>
<li>Update data state with sorted results from server</li>
<li>Show loading states during sort operations</li>
<li>
Handle sort state in URL for bookmarkable sorted views
</li>
</ul>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Client-Side vs Server-Side Sorting Comparison</CardTitle>
<CardDescription>
Side-by-side comparison of client-side and server-side sorting
approaches
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-6">
<div className="grid gap-4 md:grid-cols-2">
<div className="space-y-3">
<h4 className="text-sm font-semibold text-green-700">
Client-Side Sorting (manualSorting=false)
</h4>
<div className="h-48 rounded border">
<DataTable
columns={[
{
accessorKey: 'name',
header: 'Name',
enableSorting: true,
},
{
accessorKey: 'department',
header: 'Department',
enableSorting: true,
},
{
accessorKey: 'salary',
header: 'Salary',
enableSorting: true,
cell: ({ row }) => {
const salary = row.getValue('salary') as number;
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
}).format(salary);
},
},
]}
data={data.slice(0, 8)}
pageSize={8}
pageCount={1}
getRowId={(row) => row.id}
manualSorting={false}
sticky={true}
/>
</div>
<p className="text-xs text-green-600">
✅ Data sorts immediately when headers are clicked
</p>
</div>
<div className="space-y-3">
<h4 className="text-sm font-semibold text-blue-700">
Server-Side Sorting (manualSorting=true - default)
</h4>
<div className="h-48 rounded border">
<ServerSideSortingExample
data={data.slice(0, 8)}
compact={true}
/>
</div>
<p className="text-xs text-blue-600">
Headers show sort state but data unchanged (awaits
server)
</p>
</div>
</div>
<div className="rounded-lg border bg-slate-50 p-4">
<h4 className="mb-3 text-sm font-semibold">
When to use each approach:
</h4>
<div className="grid gap-4 text-xs md:grid-cols-2">
<div>
<h5 className="mb-2 font-semibold text-green-700">
Client-Side (manualSorting=false)
</h5>
<ul className="ml-4 list-disc space-y-1">
<li>Small to medium datasets (&lt;1000 rows)</li>
<li>All data already loaded</li>
<li>Instant sorting feedback</li>
<li>Works offline</li>
<li>Simpler implementation</li>
</ul>
</div>
<div>
<h5 className="mb-2 font-semibold text-blue-700">
Server-Side (manualSorting=true - default)
</h5>
<ul className="ml-4 list-disc space-y-1">
<li>Large datasets (&gt;1000 rows)</li>
<li>Paginated data loading</li>
<li>Database-level sorting performance</li>
<li>Memory efficient</li>
<li>Required for real-world applications</li>
</ul>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
);
};

View File

@@ -8,11 +8,11 @@
"format": "prettier --check --write \"**/*.{js,cjs,mjs,ts,tsx,md,json}\""
},
"dependencies": {
"@ai-sdk/openai": "^2.0.22",
"@ai-sdk/openai": "^2.0.23",
"@faker-js/faker": "^10.0.0",
"@hookform/resolvers": "^5.2.1",
"@tanstack/react-query": "5.85.5",
"ai": "5.0.26",
"ai": "5.0.28",
"lucide-react": "^0.542.0",
"next": "15.5.2",
"nodemailer": "^7.0.5",
@@ -30,9 +30,9 @@
"@tailwindcss/postcss": "^4.1.12",
"@types/node": "^24.3.0",
"@types/nodemailer": "7.0.1",
"@types/react": "19.1.11",
"@types/react-dom": "19.1.8",
"babel-plugin-react-compiler": "19.1.0-rc.2",
"@types/react": "19.1.12",
"@types/react-dom": "19.1.9",
"babel-plugin-react-compiler": "19.1.0-rc.3",
"pino-pretty": "13.0.0",
"react-hook-form": "^7.62.0",
"recharts": "2.15.3",