Commit Graph

10 Commits

Author SHA1 Message Date
cesnimda 4f69d395be fix(nav): only the most-specific sidebar item is active
On /career/builder/{id} both "Career Workspace" (/career) and "CV Builder"
(/career/builder) highlighted, because AppShell tested each item with
`pathname === to || pathname.startsWith(to + "/")` — so /career matched
every /career/... child. No "most specific wins" rule.

Add AppShell.activeNavTo(pathname, tos): the longest `to` that the path is
at or under wins, across both nav lists; every other item is inactive. A
child route never lights up a parent nav item. `selected` now compares
against that single computed activeTo. Exported as a pure function so the
ownership rule is unit-tested directly (sidebar-active-nav.test.ts):
exactly one active item for /career, /career/builder and
/career/builder/{id}, and no double-highlight.

Also give the breadcrumb/title in App.tsx explicit /career/builder ->
"CV Builder" ownership (it previously showed "Career Workspace"), and
reframe the Career Workspace header to the "Career Profile" product
framing: "This information powers your CVs, applications, cover letters
and AI assistance."

Frontend only — no change to CareerProfiles, CvVariants, CV generation,
extraction APIs, AI, permissions or tenant isolation. Plan for the deeper
information-architecture work is in docs/career-workspace-ux-refactor.md,
staged so the 1376-line CareerProfilePage and the live CV/extraction
pipeline are refactored incrementally with verification, not in one risky
rewrite.

Verified: tsc clean, frontend build clean, 135 frontend tests pass
(128 + 7 new nav tests). Backend untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 02:29:50 +02:00
cesnimda 9615ee3f41 feat(ux): per-view subtitles, correspondence cross-links, mobile kanban, a11y
Continuing the product/UX review's deferred items:

- Every top-level view now gets a one-line subtitle under its title
  (Dashboard/Jobs/Kanban/Reminders/Correspondence/Gmail review) stating
  what that specific view is for, instead of navigation being the only
  signal of what each page does.
- Correspondence inbox and Gmail review queue cross-link to each other
  instead of being two unexplained flat sidebar items -- kept both nav
  entries (renaming/nesting risked breaking muscle memory) but made the
  relationship between them explicit in the UI itself.
- Kanban board switches to a horizontal scroll-snap row on phone-width
  viewports instead of stacking all 5 columns vertically, which meant
  a lot of scrolling to see anything past "Applied".
- Match-score ring gets an aria-label with the actual percentage --
  it was two nested decorative CircularProgress elements with no
  accessible text. (Keyboard-accessible status changes on kanban cards
  were already covered by the existing "..." menu -- no gap there.)
2026-07-12 04:14:37 +02:00
cesnimda 7cfbdf504a feat(ui): dark navy sidebar + restrained kanban status colors
CI and Deploy / test (pull_request) Successful in 2m2s
CI and Deploy / deploy (pull_request) Has been skipped
First pass of the /frontend-design overhaul against the mockups at
F:\Pictures\website\jobtracker\new. Two highest-leverage gaps from the
backlog note ("dark sidebar, KPI cards, exact status colours"):

- AppShell: nav rail is now a fixed dark navy (#0f172a) regardless of
  the app's light/dark theme toggle, matching the mockup's signature
  look -- selected item gets an indigo-tinted pill + icon accent,
  muted slate text for the rest. Kept icon+label rows (mockup's sidebar
  is text-only) since the existing collapsed-sidebar mode depends on
  icons; that's a deliberate deviation, not an oversight.
- JobbjaktMark: replaced the briefcase glyph with the gradient
  checkmark-in-square mark used throughout the mockups (hero, dashboard,
  kanban) -- also fixed a latent SVG gradient id collision across
  multiple rendered instances via useId().
- KanbanBoard: mockup uses color sparingly (a small dot in the column
  header, a 4px accent on the card's left edge) rather than tinting the
  whole column/card background as the previous version did. Reworked
  to match; also swapped card title/subtitle order (job title bold,
  company/location as subtitle) per the mockup.

Remaining for follow-up passes: Dashboard KPI card layout and the job
workspace (candidate-fit ring, AI summary card) -- both structurally
close already but not yet pixel-matched.

Verified: `next build` clean, all 57 frontend tests green, dark
sidebar confirmed live (computed bg #0f172a) against a running dev
server with light content mode forced.
2026-07-12 01:45:20 +02:00
cesnimda acf60c2a07 build(frontend): migrate CRA to Next.js (CSR lift-and-shift)
CI and Deploy / test (pull_request) Failing after 50s
CI and Deploy / deploy (pull_request) Has been skipped
Wave 6. Swaps react-scripts' build/dev tooling for Next.js while
keeping the app's actual routing/rendering model unchanged -- the app
is almost entirely behind auth with no proven SSR/SEO need, so a real
App Router rewrite would touch ~90 files for zero user-visible benefit.

- next.config.js: output:'export' (static HTML+JS, same "single
  index.html served by nginx with try_files fallback" deploy as CRA).
- app/layout.tsx + app/page.tsx: root shell ports public/index.html's
  <head>, mounts the whole existing App tree client-only (ssr:false)
  since it reads window/localStorage during initial render and Next's
  static prerender would otherwise execute that on the server.
- Renamed src/pages/ -> src/views/ (Next's Pages Router auto-detects
  any `pages/` dir under the app root and tried to build our React
  Router page components as its own routes).
- REACT_APP_* -> NEXT_PUBLIC_* across code, .env.development,
  Dockerfile, docker-compose.yml build args.
- Replaced the CRA SVGR import (`ReactComponent` from .svg, unsupported
  under Turbopack) with a small inline JobbjaktMark component.
- TypeScript 4.9 -> 5.9 (MUI v8's type-checked build needs syntax
  4.9's parser rejects; CRA never hit this because babel doesn't
  type-check).
- Dropped CRA-only files (index.tsx, reportWebVitals, react-app-env.d.ts,
  public/index.html); kept react-scripts as the Jest test runner only
  (next/jest migration not needed -- the existing config already works).

Verified: `next build` static export succeeds, `next dev` serves the
landing page and client-side routes (login etc.) correctly, all 57
frontend tests + 172 backend tests still green.

Known caveat: deep-linking straight to a sub-route (e.g. /login) 404s
in `next dev` since there's no server route for it -- the app only
ever mounts at "/". Production is unaffected: nginx's existing
try_files fallback still serves index.html for any path.
2026-07-12 00:50:45 +02:00
cesnimda 99fc94bc18 Polish mobile layout and add collapsible sidebar 2026-03-29 14:24:43 +02:00
cesnimda 2bcee6e07c Prefer usernames in shell and admin flows 2026-03-23 21:07:21 +01:00
cesnimda fcafda6f52 Polish UI, harden company creation, and add error pages 2026-03-23 19:34:29 +01:00
cesnimda 6d9c278f40 fix: repair frontend production build regressions 2026-03-22 20:36:02 +01:00
cesnimda f1c7c38a19 feat: improve reminders summarizer output and system metadata handling 2026-03-22 14:58:56 +01:00
cesnimda 2e8a29b4d0 First Commit 2026-03-21 11:55:27 +01:00