Skip to content

Commit 1401541

Browse files
committed
Phase 4 frontend polish: bundle analyzer, useTransition, error UX
- next.config: wrap config with @next/bundle-analyzer (enabled via ANALYZE=true) so future bundle deltas are inspectable - web/package.json: add analyze script + bundle-analyzer devDep - admin/disputes: wrap state updates in startTransition so the status-filter swap doesn't block the table; fade table while pending so the user gets feedback without a loading spinner - add segment-level error boundaries for /invitations, /social, and /mcp using the existing RouteError component so failures in those fetch-heavy interactive routes show contextual UI instead of falling back to the root error page
1 parent a898f0b commit 1401541

7 files changed

Lines changed: 171 additions & 13 deletions

File tree

packages/web/next.config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import type { NextConfig } from 'next';
2+
import withBundleAnalyzer from '@next/bundle-analyzer';
3+
4+
const bundleAnalyzer = withBundleAnalyzer({
5+
enabled: process.env.ANALYZE === 'true',
6+
});
27

38
const nextConfig: NextConfig = {
49
output: 'standalone',
@@ -17,4 +22,4 @@ const nextConfig: NextConfig = {
1722
},
1823
};
1924

20-
export default nextConfig;
25+
export default bundleAnalyzer(nextConfig);

packages/web/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"scripts": {
66
"dev": "next dev --port 3200",
77
"build": "next build",
8+
"analyze": "ANALYZE=true next build",
89
"start": "next start --port 3200",
910
"test": "node --test tests/**/*.test.mjs",
1011
"lint": "eslint .",
@@ -21,6 +22,7 @@
2122
},
2223
"devDependencies": {
2324
"@eslint/eslintrc": "^3.3.5",
25+
"@next/bundle-analyzer": "^16.2.4",
2426
"@tailwindcss/postcss": "^4.1.0",
2527
"@types/react": "^19.1.0",
2628
"@types/react-dom": "^19.1.0",

packages/web/src/app/admin/disputes/page.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
'use client';
22

3-
import { useEffect, useState } from 'react';
3+
import { useEffect, useState, useTransition } from 'react';
44
import { fetchAdminDisputes, type AdminDispute } from '@/lib/api';
55

66
export default function AdminDisputesPage() {
77
const [disputes, setDisputes] = useState<AdminDispute[]>([]);
88
const [total, setTotal] = useState(0);
99
const [loading, setLoading] = useState(true);
1010
const [statusFilter, setStatusFilter] = useState<string>('');
11+
const [isPending, startTransition] = useTransition();
1112

1213
useEffect(() => {
1314
const adminKey = sessionStorage.getItem('adminKey') ?? '';
1415
if (!adminKey) return;
1516
setLoading(true);
1617
fetchAdminDisputes(adminKey, { status: statusFilter || undefined, limit: '50' }).then((data) => {
1718
if (data) {
18-
setDisputes(data.disputes);
19-
setTotal(data.total);
19+
startTransition(() => {
20+
setDisputes(data.disputes);
21+
setTotal(data.total);
22+
});
2023
}
2124
setLoading(false);
2225
});
@@ -49,7 +52,7 @@ export default function AdminDisputesPage() {
4952
) : disputes.length === 0 ? (
5053
<p className="mono mt-8 text-sm text-[var(--color-text-3)]">No disputes found.</p>
5154
) : (
52-
<table className="mono mt-6 w-full text-sm">
55+
<table className={`mono mt-6 w-full text-sm ${isPending ? 'opacity-60 transition-opacity' : ''}`}>
5356
<thead>
5457
<tr className="border-b border-[var(--color-border)] text-left text-[var(--color-text-3)]">
5558
<th className="py-2">ID</th>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use client';
2+
import RouteError from '@/components/RouteError';
3+
export default function Error(props: { error: Error & { digest?: string }; reset: () => void }) {
4+
return <RouteError {...props} section="invitations" />;
5+
}

packages/web/src/app/mcp/error.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use client';
2+
import RouteError from '@/components/RouteError';
3+
export default function Error(props: { error: Error & { digest?: string }; reset: () => void }) {
4+
return <RouteError {...props} section="MCP services" />;
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use client';
2+
import RouteError from '@/components/RouteError';
3+
export default function Error(props: { error: Error & { digest?: string }; reset: () => void }) {
4+
return <RouteError {...props} section="social feed" />;
5+
}

0 commit comments

Comments
 (0)