f3c95123fa
Brings in the handoff design system from `Breakpilot Platform.zip` (`breakpilot/design_handoff_customer_portal/`) as the base for restyling every customer-area surface. What's in: * **Design tokens & layout primitives** — `src/app/globals.css` is the handoff `styles.css` in full (OKLCH paper + ink + brand-violet, --rule-* hairlines, --sev-* severity ramp, corner-tick bracket treatment, ledger table, 32–36px row density, dark mode via `[data-theme="dark"]`). Tailwind v4 layered on top via PostCSS for utility helpers; the design system itself stays in plain CSS. * **Geist + Geist Mono** wired through `next/font/google` so the monospaced metadata/figures everywhere render at the intended weight. * **Shell chrome** under `src/components/portal/`: `Brand` (Breakpilot. wordmark with the violet trailing dot), `Lifeline` (top full-width tenant rail — active / trial / frozen / demo variants; archived swaps in `ArchivedLockout`), `NavRail` (232px left rail with tenant switcher + workspace/admin/ settings groups + user chip; locked routes show a lock icon and a "Requires X" tooltip rather than vanishing), `Topbar` (breadcrumb + ⌘K button placeholder + theme toggle), `ThemeToggle` (Sun/Moon, persists to `localStorage["bp.theme"]`, no-flash via a head script in the root layout). * **Dashboard** at `/[slug]/dashboard` rebuilt per handoff §1: page-head with Export + Run scan (the latter wrapped in the frozen write-guard hovercard surfacing `HTTP 402 · payment required`), 5-cell bracketed KPI rail (open findings + 14-day sparkbars + 7-day delta, critical with severity stack, controls passing with violet ring gauge + n/240, evidence area sparkline, last-scan cadence), 12-col grid: 30-day findings flow + severity stack legend + top-5 open findings table on the left, product posture rows + scan-activity heatmap (5x7) + recent-activity feed on the right. Plain USER role drops the KPI rail and the org-wide panels per spec. * **Charts** — minimal SVG primitives in `components/portal/charts/`: Sparkbars, Sparkline (area + line), Ring, StackBar, Heatmap + HeatLegend. All token-driven (`var(--sev-*)`, `var(--accent)`). * **Fixtures** — `src/lib/fixtures.ts` is a TS port of the handoff's `data.js`. Deterministic mulberry32 generators give the same realistic DACH/EU compliance data every reload (~5 tenants × 30+ days activity / 4–13 findings per product / 9 months invoices / hash- chained audit). Source of truth for the design until tenant-registry is enriched to carry these fields end-to-end. RBAC table (`canAccess`, `landingFor`) ported alongside. * **Dev session bypass** — `src/lib/get-session.ts` returns a synthetic `SessionWithExtras` from one of the 6 fixtures when `BP_DEV_FIXTURE=<id>` is set. Lets the portal render the design without Keycloak + tenant-registry up. Real Auth.js wiring untouched. What's NOT in yet (next commits): * Products / Product launch / Org / Team / Billing / Audit / SSO pages * Workflows editor (palette + canvas + inspector + drag-wiring) * Command palette + toast system * MSW handlers for the tenant data shapes (today the page reads the fixture module directly server-side; MSW is for client-side calls) Run locally: pnpm install BP_DEV_FIXTURE=admin-acme pnpm dev open http://acme.localhost:3000/acme/dashboard Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
48 lines
1.2 KiB
JSON
48 lines
1.2 KiB
JSON
{
|
|
"name": "@breakpilot/portal",
|
|
"version": "0.0.0",
|
|
"private": true,
|
|
"description": "Customer-facing portal + platform-staff backstage. Next.js + Auth.js v5.",
|
|
"license": "UNLICENSED",
|
|
"engines": {
|
|
"node": ">=20",
|
|
"pnpm": ">=9"
|
|
},
|
|
"scripts": {
|
|
"dev": "next dev --port 3000",
|
|
"build": "next build",
|
|
"start": "next start --port 3000",
|
|
"lint": "eslint . --max-warnings 0",
|
|
"typecheck": "tsc --noEmit",
|
|
"test": "vitest run --coverage",
|
|
"e2e": "playwright test",
|
|
"e2e:install": "playwright install --with-deps chromium"
|
|
},
|
|
"dependencies": {
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"geist": "^1.7.2",
|
|
"lucide-react": "^1.17.0",
|
|
"next": "16.2.6",
|
|
"next-auth": "5.0.0-beta.25",
|
|
"react": "19.0.0",
|
|
"react-dom": "19.0.0",
|
|
"tailwind-merge": "^3.6.0"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.60.0",
|
|
"@tailwindcss/postcss": "^4.3.0",
|
|
"@types/node": "20.16.10",
|
|
"@types/react": "19.0.1",
|
|
"@types/react-dom": "19.0.1",
|
|
"@vitest/coverage-v8": "2.1.8",
|
|
"eslint": "9.15.0",
|
|
"eslint-config-next": "16.2.6",
|
|
"msw": "^2.14.6",
|
|
"postcss": "^8.5.15",
|
|
"tailwindcss": "^4.3.0",
|
|
"typescript": "5.7.2",
|
|
"vitest": "2.1.8"
|
|
}
|
|
}
|