Mega-Tracker/src/components/ThemeControls.tsx
Dave 471cf6fb3c Project tracker seeded from the Mega Infrastructure Candy barchart
App for the Mega Infrastructure AI Integration programme (A000) and Mega
Plant (B110). 100 activities across 2 programmes, 06 Oct 2026 - 31 Aug 2027,
parsed from the client PDF and frozen as an immutable baseline.

Views: Dashboard, Timeline (month grid + week grid matching the PDF's
Friday-anchored week numbering), Todo list, WBS, Data.

Notes on the source data:
- Hierarchy is derived from the PDF's indentation, not the activity code.
  Codes do not sort structurally (A490 sits under Workforce, A510 under
  Financials), so a code-ordered import would produce a wrong tree.
- The schedule is built from the dates, not the PDF's "Durn" column, which
  disagrees with its own dates for 13 of the 100 activities.
- Spec issues found in the PDF are surfaced in-app under Data: 2 unresolved
  "?" placeholders, 6 activities sharing one stretched 6-week window while
  declared 15 days, 13 duration mismatches, 17 spelling corrections
  (original wording preserved and viewable).

Progress (status, % complete, note) is stored behind a pluggable adapter so
the site can be static today and point at a shared JSON store later without
touching the UI.
2026-10-01 08:48:51 +02:00

51 lines
1.6 KiB
TypeScript

import { ACCENTS, useAppearance } from '../lib/appearance'
export function ThemeControls() {
const { mode, accent, setAccent, toggle } = useAppearance()
return (
<div className="appearance">
<div className="swatches" role="radiogroup" aria-label="Accent colour">
{ACCENTS.map((a) => (
<button
key={a.id}
type="button"
role="radio"
aria-checked={accent === a.id}
aria-label={a.label}
title={a.label}
className={`swatch${accent === a.id ? ' on' : ''}`}
data-accent={a.id}
onClick={() => setAccent(a.id)}
/>
))}
</div>
<button
type="button"
className="mode-toggle"
onClick={toggle}
title={mode === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
aria-label={mode === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
>
{mode === 'dark' ? <SunIcon /> : <MoonIcon />}
</button>
</div>
)
}
function SunIcon() {
return (
<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
<circle cx="10" cy="10" r="3.6" />
<path d="M10 1.6v2.1M10 16.3v2.1M18.4 10h-2.1M3.7 10H1.6M15.9 4.1l-1.5 1.5M5.6 14.4l-1.5 1.5M15.9 15.9l-1.5-1.5M5.6 5.6L4.1 4.1" />
</svg>
)
}
function MoonIcon() {
return (
<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
<path d="M17.5 12.4A7.9 7.9 0 0 1 7.6 2.5a7.9 7.9 0 1 0 9.9 9.9z" />
</svg>
)
}