From de8224d8232072de4287a41ff4fb15619d75d25f Mon Sep 17 00:00:00 2001 From: DaKheera47 Date: Thu, 15 Jan 2026 14:52:03 +0000 Subject: [PATCH] UI redesign --- .../src/client/pages/OrchestratorPage.tsx | 371 +++++++++--------- 1 file changed, 175 insertions(+), 196 deletions(-) diff --git a/orchestrator/src/client/pages/OrchestratorPage.tsx b/orchestrator/src/client/pages/OrchestratorPage.tsx index 9f3a9b2..6ddff5d 100644 --- a/orchestrator/src/client/pages/OrchestratorPage.tsx +++ b/orchestrator/src/client/pages/OrchestratorPage.tsx @@ -8,14 +8,12 @@ import { Calendar, CheckCircle2, ChevronDown, - Clock, Copy, DollarSign, Edit2, ExternalLink, FileText, Filter, - GraduationCap, Loader2, MapPin, MoreHorizontal, @@ -47,7 +45,6 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; -import { Separator } from "@/components/ui/separator"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; @@ -252,31 +249,39 @@ const jobMatchesQuery = (job: Job, query: string) => { const stripHtml = (value: string) => value.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(); +// Default fallback for unknown statuses +const defaultStatusToken = { + label: "Unknown", + badge: "border-muted-foreground/20 bg-muted/30 text-muted-foreground", + dot: "bg-muted-foreground", +}; + +// Subdued status pill for inspector panel - not competing with list const StatusPill: React.FC<{ status: JobStatus }> = ({ status }) => { - const tokens = statusTokens[status]; + const tokens = statusTokens[status] ?? defaultStatusToken; return ( - + {tokens.label} ); }; +// Compact score meter for inspector panel const ScoreMeter: React.FC<{ score: number | null }> = ({ score }) => { if (score == null) { - return Not scored; + return ; } return ( -
-
+
+
@@ -693,15 +698,9 @@ export const OrchestratorPage: React.FC = () => {
-
+
-
-

Pipeline console

-

- Focused workspace with a split list/detail layout and icon-led actions. -

-
-
{totalJobs} total jobs
+

Jobs

{isPipelineRunning && ( @@ -710,58 +709,55 @@ export const OrchestratorPage: React.FC = () => {
)} -
- {[ - { label: "Discovered", value: stats.discovered }, - { label: "Processing", value: stats.processing }, - { label: "Ready", value: stats.ready }, - { label: "Applied", value: stats.applied }, - { label: "Skipped", value: stats.skipped }, - { label: "Expired", value: stats.expired }, - ].map((item, index) => ( -
0 && "border-t border-border/60 sm:border-t-0 sm:border-l", - index > 0 && index % 3 === 0 && "sm:border-l-0 sm:border-t", - index > 2 && "lg:border-t-0 lg:border-l", - )} - > - {item.label} - {item.value} -
- ))} + {/* Compact metrics summary - demoted visual weight */} +
+ {totalJobs} jobs total + + {stats.ready} ready + + {stats.discovered + stats.processing} pending + + {stats.applied} applied + {(stats.skipped > 0 || stats.expired > 0) && ( + <> + + {stats.skipped + stats.expired} archived + + )}
-
+ + {/* Main content: tabs/filters -> list/detail */} +
setActiveTab(value as FilterTab)}>
{tabs.map((tab) => ( - + {tab.label} - ({counts[tab.id]}) + {counts[tab.id] > 0 && ( + {counts[tab.id]} + )} ))}
-
- +
+ setSearchQuery(event.target.value)} - placeholder="Filter jobs..." - className="pl-9" + placeholder="Search..." + className="h-8 pl-8 text-sm" />
- @@ -783,9 +779,9 @@ export const OrchestratorPage: React.FC = () => { - @@ -820,19 +816,18 @@ export const OrchestratorPage: React.FC = () => { - - {activeResultsCount} jobs -
-
-
-
- {isLoading && jobs.length === 0 ? ( -
- -
Loading jobs...
+ + {/* List/Detail grid - directly under tabs, no extra section */} +
+ {/* Primary region: Job list with highest visual weight */} +
+ {isLoading && jobs.length === 0 ? ( +
+ +
Loading jobs...
) : activeJobs.length === 0 ? (
@@ -842,51 +837,61 @@ export const OrchestratorPage: React.FC = () => {

) : ( -
+
{activeJobs.map((job) => { const isSelected = job.id === selectedJobId; + const hasScore = job.suitabilityScore != null; + const statusToken = statusTokens[job.status] ?? defaultStatusToken; return ( ); })} @@ -894,115 +899,102 @@ export const OrchestratorPage: React.FC = () => { )}
-
+ {/* Inspector panel: visually subordinate to list */} +
{!selectedJob ? ( -
-
Select a job
-

Pick a job from the list to see details here.

+
+
No job selected
+

Select a job to view details

) : ( -
-
+
+ {/* Detail header: lighter weight than list items */} +
-
{selectedJob.title}
-
{selectedJob.employer}
-
-
- - {sourceLabel[selectedJob.source]} - - +
{selectedJob.title}
+
{selectedJob.employer}
+ + {sourceLabel[selectedJob.source]} +
-
+ {/* Tertiary metadata - subdued */} +
{selectedJob.location && ( - + {selectedJob.location} )} {selectedDeadline && ( - + {selectedDeadline} )} - {selectedDiscoveredAt && ( - - - Discovered {selectedDiscoveredAt} - - )} {selectedJob.salary && ( - + {selectedJob.salary} )} - {selectedJob.degreeRequired && ( - - - {selectedJob.degreeRequired} - - )}
-
- Suitability + {/* Status and score: single line, subdued */} +
+
- - -
- {showReadyPdf && (selectedHasPdf ? ( - ) : ( - ))} {showGeneratePdf && ( )} {canApply && ( )} @@ -1076,69 +1068,55 @@ export const OrchestratorPage: React.FC = () => {
setDetailTab(value as typeof detailTab)}> - - Overview - Tailoring - Description + + Overview + Tailoring + Description - -
- {selectedJob.suitabilityReason - ? `"${selectedJob.suitabilityReason}"` - : "No suitability summary yet."} -
+ + {selectedJob.suitabilityReason && ( +
+ "{selectedJob.suitabilityReason}" +
+ )} -
+
-
Discipline
-
{selectedJob.disciplines || "Not set"}
+
Discipline
+
{selectedJob.disciplines || "—"}
-
Job function
-
{selectedJob.jobFunction || "Not set"}
+
Function
+
{selectedJob.jobFunction || "—"}
-
Job level
-
{selectedJob.jobLevel || "Not set"}
+
Level
+
{selectedJob.jobLevel || "—"}
-
Job type
-
{selectedJob.jobType || "Not set"}
+
Type
+
{selectedJob.jobType || "—"}
- - -
-
-
- Description Preview -
- -
-
- {description} -
- + {description} + +
+ +
@@ -1267,6 +1245,7 @@ export const OrchestratorPage: React.FC = () => {
)}
+