refactor: migrate page components to Design System v4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-22 02:04:16 -04:00
parent fd28921373
commit e4ef904707
58 changed files with 1416 additions and 1416 deletions

View File

@@ -280,8 +280,8 @@ export function SessionHistoryPage() {
<PageMeta title="Sessions" />
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
<div className="mb-8">
<h1 className="text-2xl font-heading font-bold text-foreground sm:text-3xl">Sessions</h1>
<p className="mt-2 text-muted-foreground">
<h1 className="text-2xl font-heading font-bold text-[#e2e5eb] sm:text-3xl">Sessions</h1>
<p className="mt-2 text-[#848b9b]">
View and manage all your sessions
</p>
</div>
@@ -295,13 +295,13 @@ export function SessionHistoryPage() {
<div className="flex gap-3">
<Link
to="/trees"
className="inline-flex items-center gap-2 rounded-[10px] bg-gradient-brand px-5 py-2.5 text-sm font-semibold text-[#101114] shadow-lg shadow-primary/20 hover:opacity-90 active:scale-[0.97] transition-all"
className="inline-flex items-center gap-2 rounded-lg bg-[#22d3ee] px-5 py-2.5 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] transition-all"
>
Start a Flow
</Link>
<Link
to="/pilot"
className="inline-flex items-center gap-2 rounded-[10px] border border-border bg-[rgba(255,255,255,0.04)] px-5 py-2.5 text-sm font-semibold text-foreground hover:border-[rgba(255,255,255,0.12)] transition-all"
className="inline-flex items-center gap-2 rounded-lg border border-[#1e2130] bg-[rgba(255,255,255,0.04)] px-5 py-2.5 text-sm font-semibold text-[#e2e5eb] hover:border-[rgba(255,255,255,0.12)] transition-all"
>
Start AI Session
</Link>
@@ -314,20 +314,20 @@ export function SessionHistoryPage() {
{/* FlowPilot Sessions Section */}
{showAiSection && (
<>
<h2 className="font-label text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground mb-3">FlowPilot Sessions</h2>
<h2 className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-[#848b9b] mb-3">FlowPilot Sessions</h2>
{/* AI Session Filter Bar */}
<div className="glass-card-static p-3 mb-4">
<div className="card-flat p-3 mb-4">
<div className="flex flex-wrap gap-3 items-center">
{/* Search input */}
<div className="relative flex-1 min-w-[180px]">
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" />
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[#848b9b] pointer-events-none" />
<input
type="text"
value={aiSearchInput}
onChange={(e) => setAiSearchInput(e.target.value)}
placeholder="Search sessions..."
className="w-full rounded-lg border border-border bg-card pl-8 pr-3 py-1.5 text-sm text-foreground placeholder:text-muted-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none"
className="w-full rounded-lg border border-[#1e2130] bg-[#14161d] pl-8 pr-3 py-1.5 text-sm text-[#e2e5eb] placeholder:text-[#848b9b] focus:border-[rgba(6,182,212,0.3)] focus:outline-none"
/>
</div>
@@ -336,7 +336,7 @@ export function SessionHistoryPage() {
value={aiFilters.problem_domain}
onChange={(e) => setAiFilters((f) => ({ ...f, problem_domain: e.target.value }))}
title="Filter by problem domain"
className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none [&>option]:bg-[#1a1c21] [&>option]:text-foreground"
className="rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-1.5 text-sm text-[#e2e5eb] focus:border-[rgba(6,182,212,0.3)] focus:outline-none [&>option]:bg-[#1a1c21] [&>option]:text-[#e2e5eb]"
>
<option value="">All domains</option>
<option value="Active Directory">Active Directory</option>
@@ -358,10 +358,10 @@ export function SessionHistoryPage() {
key={tier}
onClick={() => setAiFilters((f) => ({ ...f, confidence_tier: tier }))}
className={cn(
'rounded-full border px-3 py-1 text-xs font-label transition-colors',
'rounded-full border px-3 py-1 text-xs font-sans text-xs transition-colors',
aiFilters.confidence_tier === tier
? 'bg-primary/10 text-foreground border-primary/30'
: 'bg-card text-muted-foreground border-border hover:text-foreground hover:border-[rgba(255,255,255,0.12)]'
? 'bg-[rgba(34,211,238,0.10)] text-[#e2e5eb] border-primary/30'
: 'bg-[#14161d] text-[#848b9b] border-[#1e2130] hover:text-[#e2e5eb] hover:border-[rgba(255,255,255,0.12)]'
)}
>
{tier === '' ? 'All' : tier.charAt(0).toUpperCase() + tier.slice(1)}
@@ -376,15 +376,15 @@ export function SessionHistoryPage() {
value={aiFilters.date_from}
onChange={(e) => setAiFilters((f) => ({ ...f, date_from: e.target.value }))}
title="From date"
className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none [color-scheme:dark]"
className="rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-1.5 text-sm text-[#e2e5eb] focus:border-[rgba(6,182,212,0.3)] focus:outline-none [color-scheme:dark]"
/>
<span className="text-xs text-muted-foreground">to</span>
<span className="text-xs text-[#848b9b]">to</span>
<input
type="date"
value={aiFilters.date_to}
onChange={(e) => setAiFilters((f) => ({ ...f, date_to: e.target.value }))}
title="To date"
className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none [color-scheme:dark]"
className="rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-1.5 text-sm text-[#e2e5eb] focus:border-[rgba(6,182,212,0.3)] focus:outline-none [color-scheme:dark]"
/>
</div>
@@ -395,7 +395,7 @@ export function SessionHistoryPage() {
setAiSearchInput('')
setAiFilters({ q: '', problem_domain: '', confidence_tier: '', date_from: '', date_to: '' })
}}
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
className="text-xs text-[#848b9b] hover:text-[#e2e5eb] transition-colors"
>
Clear
</button>
@@ -417,7 +417,7 @@ export function SessionHistoryPage() {
setAiSearchInput('')
setAiFilters({ q: '', problem_domain: '', confidence_tier: '', date_from: '', date_to: '' })
}}
className="text-foreground hover:underline text-sm"
className="text-[#e2e5eb] hover:underline text-sm"
>
Clear all filters
</button>
@@ -433,7 +433,7 @@ export function SessionHistoryPage() {
{/* Divider between sections */}
{showFlowSection && (
<div className="my-8 border-t border-border" />
<div className="my-8 border-t border-[#1e2130]" />
)}
</>
)}
@@ -441,10 +441,10 @@ export function SessionHistoryPage() {
{/* Flow Sessions Section */}
{showFlowSection && (
<>
<h2 className="font-label text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground mb-3">Flow Sessions</h2>
<h2 className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-[#848b9b] mb-3">Flow Sessions</h2>
{/* Filter Tabs */}
<div className="mb-6 flex gap-2 border-b border-border">
<div className="mb-6 flex gap-2 border-b border-[#1e2130]">
{(['active', 'prepared', 'completed', 'all'] as const).map((tab) => (
<button
key={tab}
@@ -452,8 +452,8 @@ export function SessionHistoryPage() {
className={cn(
'px-4 py-2 text-sm font-medium transition-colors',
filter === tab
? 'border-b-2 border-primary text-foreground'
: 'text-muted-foreground hover:text-foreground'
? 'border-b-2 border-primary text-[#e2e5eb]'
: 'text-[#848b9b] hover:text-[#e2e5eb]'
)}
>
{tab.charAt(0).toUpperCase() + tab.slice(1)}
@@ -481,7 +481,7 @@ export function SessionHistoryPage() {
title="No sessions match your filters"
description="Try adjusting your search or filters."
action={
<button onClick={handleClearFilters} className="text-foreground hover:underline text-sm">
<button onClick={handleClearFilters} className="text-[#e2e5eb] hover:underline text-sm">
Clear all filters
</button>
}
@@ -494,7 +494,7 @@ export function SessionHistoryPage() {
action={
<Link
to="/trees"
className="inline-flex items-center gap-2 rounded-[10px] bg-gradient-brand px-5 py-2.5 text-sm font-semibold text-[#101114] shadow-lg shadow-primary/20 hover:opacity-90 active:scale-[0.97] transition-all"
className="inline-flex items-center gap-2 rounded-lg bg-[#22d3ee] px-5 py-2.5 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] transition-all"
>
Start a Session
</Link>
@@ -515,7 +515,7 @@ export function SessionHistoryPage() {
style={{ '--stagger-index': i } as React.CSSProperties}
>
<div
className="bg-card border border-border rounded-xl p-4 transition-all hover:bg-accent/50"
className="bg-[#14161d] border border-[#1e2130] rounded-xl p-4 transition-all hover:bg-accent/50"
>
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<div className="flex-1">
@@ -527,11 +527,11 @@ export function SessionHistoryPage() {
session.completed_at ? 'bg-green-500' : 'bg-yellow-500'
)}
/>
<span className="font-medium text-foreground">
<span className="font-medium text-[#e2e5eb]">
{session.ticket_number || 'No ticket'}
</span>
{session.client_name && (
<span className="rounded-full bg-accent px-2.5 py-0.5 text-xs font-medium text-foreground">
<span className="rounded-full bg-accent px-2.5 py-0.5 text-xs font-medium text-[#e2e5eb]">
{session.client_name}
</span>
)}
@@ -545,7 +545,7 @@ export function SessionHistoryPage() {
session.outcome === 'unresolved' && 'bg-rose-500/20 text-rose-300',
session.outcome === 'cancelled' && 'bg-zinc-500/20 text-zinc-300',
session.outcome === 'resolved_externally' && 'bg-cyan-500/20 text-cyan-300',
!session.outcome && 'bg-accent text-muted-foreground'
!session.outcome && 'bg-accent text-[#848b9b]'
)}
>
{formatOutcomeLabel(session.outcome)}
@@ -554,12 +554,12 @@ export function SessionHistoryPage() {
</div>
{/* Tree Name */}
<p className="mt-1 text-sm text-muted-foreground">
<p className="mt-1 text-sm text-[#848b9b]">
<span className="font-medium">Tree:</span> {getTreeName(session)}
</p>
{/* Timestamps */}
<p className="mt-1 text-sm text-muted-foreground">
<p className="mt-1 text-sm text-[#848b9b]">
Started: {session.started_at ? formatDate(session.started_at) : 'Not started'}
{session.completed_at && (
<> · Completed: {formatDate(session.completed_at)}</>
@@ -567,7 +567,7 @@ export function SessionHistoryPage() {
</p>
{/* Stats */}
<p className="mt-1 text-sm text-muted-foreground">
<p className="mt-1 text-sm text-[#848b9b]">
{session.decisions.length} decision{session.decisions.length !== 1 ? 's' : ''} recorded
{session.scratchpad && session.scratchpad.trim() && (
<span> · Has notes</span>
@@ -580,8 +580,8 @@ export function SessionHistoryPage() {
<button
onClick={() => navigate(`/sessions/${session.id}`)}
className={cn(
'rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground',
'hover:bg-accent hover:text-foreground'
'rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b]',
'hover:bg-accent hover:text-[#e2e5eb]'
)}
>
View Details
@@ -595,9 +595,9 @@ export function SessionHistoryPage() {
setCloseNotes('')
}}
className={cn(
'rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground',
'hover:bg-accent hover:text-foreground',
closingSessionId === session.id && 'bg-accent text-foreground'
'rounded-md border border-[#1e2130] px-3 py-2 text-sm font-medium text-[#848b9b]',
'hover:bg-accent hover:text-[#e2e5eb]',
closingSessionId === session.id && 'bg-accent text-[#e2e5eb]'
)}
>
Close
@@ -605,8 +605,8 @@ export function SessionHistoryPage() {
<button
onClick={() => navigate(getSessionResumePath(session.tree_id, session.tree_snapshot?.tree_type), { state: { sessionId: session.id } })}
className={cn(
'rounded-md bg-gradient-brand px-3 py-2 text-sm font-medium text-white shadow-lg shadow-primary/20',
'hover:opacity-90'
'rounded-md bg-[#22d3ee] px-3 py-2 text-sm font-medium text-white',
'hover:brightness-110'
)}
>
Resume
@@ -618,16 +618,16 @@ export function SessionHistoryPage() {
{closingSessionId === session.id && (
<div
ref={closePopoverRef}
className="absolute right-0 top-full z-20 mt-2 w-72 rounded-xl border border-border bg-card p-4 shadow-xl"
className="absolute right-0 top-full z-20 mt-2 w-72 rounded-xl border border-[#1e2130] bg-[#14161d] p-4 shadow-xl"
>
<p className="text-sm font-heading font-medium text-foreground mb-3">Close Session</p>
<p className="text-sm font-heading font-medium text-[#e2e5eb] mb-3">Close Session</p>
<label className="block text-xs font-label text-muted-foreground mb-1">Outcome</label>
<label className="block text-xs font-sans text-xs text-[#848b9b] mb-1">Outcome</label>
<select
value={closeOutcome}
onChange={(e) => setCloseOutcome(e.target.value as SessionOutcome)}
title="Session outcome"
className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none mb-3"
className="w-full rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] focus:border-[rgba(6,182,212,0.3)] focus:outline-none mb-3"
>
<option value="">Select outcome...</option>
<option value="resolved">Resolved</option>
@@ -638,13 +638,13 @@ export function SessionHistoryPage() {
<option value="resolved_externally">Resolved Externally</option>
</select>
<label className="block text-xs font-label text-muted-foreground mb-1">Notes (optional)</label>
<label className="block text-xs font-sans text-xs text-[#848b9b] mb-1">Notes (optional)</label>
<textarea
value={closeNotes}
onChange={(e) => setCloseNotes(e.target.value)}
rows={2}
placeholder="Add closure notes..."
className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none resize-none mb-3"
className="w-full rounded-lg border border-[#1e2130] bg-[#14161d] px-3 py-2 text-sm text-[#e2e5eb] placeholder:text-[#848b9b] focus:border-[rgba(6,182,212,0.3)] focus:outline-none resize-none mb-3"
/>
<div className="flex items-center justify-end gap-2">
@@ -654,7 +654,7 @@ export function SessionHistoryPage() {
setCloseOutcome('')
setCloseNotes('')
}}
className="rounded-lg px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
className="rounded-lg px-3 py-1.5 text-sm text-[#848b9b] hover:bg-accent hover:text-[#e2e5eb]"
>
Cancel
</button>
@@ -662,10 +662,10 @@ export function SessionHistoryPage() {
onClick={handleCloseSession}
disabled={!closeOutcome || closeLoading}
className={cn(
'rounded-lg px-4 py-1.5 text-sm font-medium shadow-lg shadow-primary/20 transition-opacity',
'rounded-lg px-4 py-1.5 text-sm font-medium transition-opacity',
closeOutcome
? 'bg-gradient-brand text-[#101114] hover:opacity-90'
: 'bg-gradient-brand text-[#101114] opacity-50 cursor-not-allowed'
? 'bg-[#22d3ee] text-white hover:brightness-110'
: 'bg-[#22d3ee] text-white opacity-50 cursor-not-allowed'
)}
>
{closeLoading ? 'Closing...' : 'Confirm'}
@@ -680,11 +680,11 @@ export function SessionHistoryPage() {
))}
</div>
{hasMore ? (
<p className="text-center text-sm text-muted-foreground py-4">
<p className="text-center text-sm text-[#848b9b] py-4">
Showing the 50 most recent sessions
</p>
) : sessions.length > 0 ? (
<p className="text-center text-sm text-muted-foreground py-4">
<p className="text-center text-sm text-[#848b9b] py-4">
Showing all {sessions.length} sessions
</p>
) : null}