From 3ca554c3672f1f31dc22e9fc0e0a706691e66286 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 18 Aug 2026 03:55:07 +0000 Subject: [PATCH] redesign UI with left sidebar, card grids, and two-column dashboard layout --- src/app/applications/page.tsx | 62 +-- src/app/globals.css | 44 +- src/app/jobs/[id]/apply/apply-wizard.tsx | 264 +++++++++--- src/app/jobs/[id]/job-actions.tsx | 16 +- src/app/jobs/[id]/page.tsx | 36 +- src/app/jobs/new/page.tsx | 32 +- src/app/jobs/page.tsx | 349 ++++++++-------- src/app/layout.tsx | 70 +--- src/app/navbar.tsx | 179 ++++++++ src/app/page.tsx | 500 ++++++++++++++--------- src/app/profile/profile-editor.tsx | 18 +- src/app/report/page.tsx | 82 ++-- src/app/resumes/[id]/resume-editor.tsx | 30 +- src/app/resumes/page.tsx | 123 ++++-- 14 files changed, 1151 insertions(+), 654 deletions(-) create mode 100644 src/app/navbar.tsx diff --git a/src/app/applications/page.tsx b/src/app/applications/page.tsx index 9c15cad..ea1b8a9 100644 --- a/src/app/applications/page.tsx +++ b/src/app/applications/page.tsx @@ -16,51 +16,51 @@ const STATUS_CONFIG: Record< }, reviewing: { label: "Reviewing", - bg: "bg-amber-50 dark:bg-amber-950/40", + bg: "bg-amber-50 dark:bg-amber-950/50", text: "text-amber-700 dark:text-amber-300", - border: "border-amber-200 dark:border-amber-800/60", + border: "border-amber-200/80 dark:border-amber-900/60", dot: "bg-amber-500", }, tailoring: { label: "Tailoring", - bg: "bg-purple-50 dark:bg-purple-950/40", + bg: "bg-purple-50 dark:bg-purple-950/50", text: "text-purple-700 dark:text-purple-300", - border: "border-purple-200 dark:border-purple-800/60", + border: "border-purple-200/80 dark:border-purple-900/60", dot: "bg-purple-500", }, ready: { label: "Ready", - bg: "bg-blue-50 dark:bg-blue-950/40", + bg: "bg-blue-50 dark:bg-blue-950/50", text: "text-blue-700 dark:text-blue-300", - border: "border-blue-200 dark:border-blue-800/60", + border: "border-blue-200/80 dark:border-blue-900/60", dot: "bg-blue-500", }, applied: { label: "Applied", - bg: "bg-indigo-50 dark:bg-indigo-950/40", + bg: "bg-indigo-50 dark:bg-indigo-950/50", text: "text-indigo-700 dark:text-indigo-300", - border: "border-indigo-200 dark:border-indigo-800/60", + border: "border-indigo-200/80 dark:border-indigo-900/60", dot: "bg-indigo-500", }, interviewing: { label: "Interviewing", - bg: "bg-teal-50 dark:bg-teal-950/40", + bg: "bg-teal-50 dark:bg-teal-950/50", text: "text-teal-700 dark:text-teal-300", - border: "border-teal-200 dark:border-teal-800/60", + border: "border-teal-200/80 dark:border-teal-900/60", dot: "bg-teal-500", }, offer: { label: "Offer", - bg: "bg-emerald-50 dark:bg-emerald-950/40", + bg: "bg-emerald-50 dark:bg-emerald-950/50", text: "text-emerald-700 dark:text-emerald-300", - border: "border-emerald-200 dark:border-emerald-800/60", + border: "border-emerald-200/80 dark:border-emerald-900/60", dot: "bg-emerald-500", }, rejected: { label: "Rejected", - bg: "bg-rose-50 dark:bg-rose-950/40", + bg: "bg-rose-50 dark:bg-rose-950/50", text: "text-rose-700 dark:text-rose-300", - border: "border-rose-200 dark:border-rose-800/60", + border: "border-rose-200/80 dark:border-rose-900/60", dot: "bg-rose-500", }, dead: { @@ -108,36 +108,48 @@ export default async function ApplicationsPage() { return (
{/* Header */} -
+
-

Applications

+

+ Applications +

{apps.length} {apps.length === 1 ? "application" : "applications"}

- Track submitted job applications and their current recruitment pipeline status. + Track submitted job applications and monitor feedback throughout your hiring process.

+ + + + + + Browse Jobs Pipeline +
{/* Applications List */} {apps.length === 0 ? ( -
+
-

No applications recorded yet

+

No applications recorded yet

- Open any job in your list and click “Mark Applied” to log an application submission here. + Open any job in your list and click “Mark Applied” or complete the “Apply Wizard” to record a submission.

Browse Jobs @@ -153,7 +165,7 @@ export default async function ApplicationsPage() { return (
- {a.job.company} + {a.job.company} · {a.method} submission · @@ -196,10 +208,10 @@ export default async function ApplicationsPage() { View Job - + diff --git a/src/app/globals.css b/src/app/globals.css index 79f8eb3..eeca5bd 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,7 +2,7 @@ :root { --background: #f8fafc; - --foreground: #0f172a; + --foreground: #09090b; --card-bg: #ffffff; --card-border: #e2e8f0; } @@ -21,20 +21,31 @@ } } +* { + border-color: var(--card-border); +} + body { background-color: var(--background); color: var(--foreground); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + letter-spacing: -0.011em; +} + +/* Headings tracking & typography tweaks */ +h1, h2, h3, h4, h5, h6 { + letter-spacing: -0.025em; } ::selection { - background-color: rgba(99, 102, 241, 0.25); + background-color: rgba(99, 102, 241, 0.22); color: inherit; } -/* Custom Scrollbar */ +/* Polished Minimalist Scrollbar */ ::-webkit-scrollbar { width: 6px; height: 6px; @@ -45,7 +56,7 @@ body { } ::-webkit-scrollbar-thumb { - background: rgba(148, 163, 184, 0.4); + background: rgba(148, 163, 184, 0.35); border-radius: 9999px; } @@ -53,6 +64,21 @@ body { background: rgba(148, 163, 184, 0.6); } +/* Focus styles for keyboard accessibility */ +:focus-visible { + outline: 2px solid rgba(99, 102, 241, 0.6); + outline-offset: 2px; +} + +/* Smooth Interactive Card Accents */ +.card-hover-effect { + transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.2s ease; +} + +.card-hover-effect:hover { + transform: translateY(-2px); +} + /* Resume & Markdown Preview Styling */ .resume-preview { font-family: "Charter", "Bitstream Vera Serif", "Cambria", "Times New Roman", serif; @@ -80,18 +106,16 @@ body { } .resume-preview h2 { - font-size: 1.2rem; - font-weight: 600; - letter-spacing: -0.01em; + font-size: 0.85rem; + font-weight: 700; + letter-spacing: 0.08em; margin-top: 1.5rem; margin-bottom: 0.5rem; - color: #1e293b; + color: #334155; border-bottom: 1px solid #e2e8f0; padding-bottom: 0.25rem; text-transform: uppercase; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; - font-size: 0.85rem; - letter-spacing: 0.08em; } .dark .resume-preview h2 { diff --git a/src/app/jobs/[id]/apply/apply-wizard.tsx b/src/app/jobs/[id]/apply/apply-wizard.tsx index 3ed3350..c61623d 100644 --- a/src/app/jobs/[id]/apply/apply-wizard.tsx +++ b/src/app/jobs/[id]/apply/apply-wizard.tsx @@ -13,13 +13,22 @@ function CopyField({ label, value }: { label: string; value: string }) { const [copied, setCopied] = useState(false); if (!value) return null; return ( -
- {label} - {value} +
+ {label} + {value}
); @@ -35,7 +44,8 @@ export default function ApplyWizard({ job, profile }: { job: Job; profile: Profi const [err, setErr] = useState(""); async function genAnswers() { - setBusy(true); setErr(""); + setBusy(true); + setErr(""); try { const qs = questions.split("\n").map((q) => q.trim()).filter(Boolean); const res = await fetch("/api/ai/answers", { @@ -46,7 +56,11 @@ export default function ApplyWizard({ job, profile }: { job: Job; profile: Profi const data = await res.json(); if (!res.ok) throw new Error(data.error ?? "failed"); setAnswers(data.answers); - } catch (e) { setErr(String(e)); } finally { setBusy(false); } + } catch (e) { + setErr(String(e)); + } finally { + setBusy(false); + } } async function markSubmitted() { @@ -67,95 +81,213 @@ export default function ApplyWizard({ job, profile }: { job: Job; profile: Profi return (
+ {/* Header */}
- ← Back to job -

Apply: {job.title}

-
{job.company}
+ + + + + Back to Job + +

+ Apply Wizard: {job.title} +

+

+ {job.company} · Follow these 5 steps to efficiently submit and record your application. +

{/* Step 1: open the application page */} -
-

1 · Open the application page

+
+
+ + 1 + +

Open the Employer Application Page

+
{job.applyUrl || job.url ? ( - - Open application page ↗ + + Open Application Page + + + - ) :

No apply URL saved — add one on the job page.

} + ) : ( +

No application URL saved — add one on the job page.

+ )}
{/* Step 2: copy-ready profile fields */} -
-

2 · Copy your details into the form

- - - - - - - - - +
+
+ + 2 + +

Copy Profile Fields into Form

+
+

+ Click copy on any field to easily paste into the employer's application portal. +

+
+ + + + + + + + + +
{/* Step 3: resume + cover letter */} -
-

3 · Attach documents

+
+
+ + 3 + +

Attach Tailored Documents

+
{job.resumes.length ? ( -
-
{/* Step 4: AI answers for form questions */} -
-

4 · Application questions (optional, AI-drafted)

-