loreal-utilisation-dept/frontend/src/components/Loading.tsx
DJP 6320fb389c style: dark slate theme matching the original SPA's look
Pure styling sweep — no behaviour changes, no new dependencies, all
data-tutorial-id selectors preserved. typecheck / lint / build clean.
Main entry 16.36 KB gz (was 12.85), recharts unchanged at 154.57 KB gz.

Foundations:
- body bg-slate-950 text-slate-100, color-scheme:dark, Apple-system font.
- .btn-primary indigo, .btn-secondary slate-700, .card slate-900 +
  slate-800 border, .input slate-800/600, .label slate-400 uppercase.

Top chrome:
- Navbar rewritten as a two-row header: title row with brand + dynamic
  subtitle (filename + row count once a timelog is loaded), then the
  three coloured upload pills inline, then user identity + Sign-out text
  link. Tab row hangs off `border-b border-slate-800` with the
  original's rounded-top "tab" look — active `bg-slate-800 text-white
  border-t border-x border-slate-700`, inactive `text-slate-400`.
- HeaderUploads now matches the original: indigo Time Log pill, emerald
  Deliverable when loaded, violet Project Summary when loaded; neutral
  slate-700 surfaces when empty. Re-uploading replaces (no Clear
  button). Errors collapse to a small ⚠ marker so the header height
  doesn't jump.
- StatsBar: bg-slate-900/50 strip below the navbar with five stacked
  stats (label slate-400 / value white).

Filter rail:
- bg-slate-900/30 strip with stacked-label fields and slate-800/600
  inputs. Native <select multiple> capped to h-20 for the brand/division/
  hub/userRole multiselects (closer to the original's selects than our
  prior chip pattern). Reset is a slate-400 text link, pushed right.
  Filter blocks only render when their option list is populated.

Charts (all six):
- CartesianGrid stroke #334155, axis ticks #94a3b8 on #475569 axis lines.
- Tooltip contentStyle: slate-800 surface + slate-700 border + slate-200
  text, indigo cursor highlight. Tooltip filterNull preserved on Project
  Load.
- "Available"/"Idle" greys swapped to slate-600 so they're visible on
  dark. Primary booking blue swapped to indigo so it harmonises with the
  rest of the indigo accent set.

Side panel + FAB:
- ChatView panel slate-900 / slate-700 border, indigo user bubbles,
  slate-800 assistant bubbles. Repositioned to bottom-24 right-6 so it
  clears the FAB. ChatToggle now indigo, moved to bottom-6 right-6.

Pages:
- Login: slate-950 page, slate-900 card, indigo affordances.
- Department / Resourcing / Bookings / Forecast / ProjectTypeSummary /
  TimeLogDetail / Tutorial all recoloured. Forecast's capacity-decision
  banner is inlined rather than using .card so it can carry the
  colour-coded tint. Bookings virtualised table re-skinned to slate-800
  header / slate-300 rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:28:41 -04:00

10 lines
336 B
TypeScript

import { Loader2 } from 'lucide-react';
export default function Loading({ label = 'Loading…' }: { label?: string }) {
return (
<div className="flex items-center justify-center gap-3 p-8 text-slate-400">
<Loader2 className="h-5 w-5 animate-spin text-indigo-500" aria-hidden />
<span>{label}</span>
</div>
);
}