feat(ui): introduce Control Rail design system and shell

This commit is contained in:
NuklearRabbit
2026-08-02 03:27:00 +02:00
parent 73e361002d
commit d0f34e6933
5 changed files with 526 additions and 296 deletions
+36 -23
View File
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../context/AuthContext";
import type { Role } from "../api/types";
import { BrandMark, Icon } from "../components/Icons";
export function Login() {
const { loginAs, loading } = useAuth();
@@ -20,31 +21,43 @@ export function Login() {
return (
<main className="login-shell">
<p className="demo-banner">
Synthetic demo environment — no real customer or vehicle data.
</p>
<section className="login-hero">
<p className="eyebrow">Synthetic proof of concept</p>
<h1>MobilityOps</h1>
<p>Connected operations for vehicle rental and service teams.</p>
<section className="login-story" aria-labelledby="product-name">
<div className="brand-lockup login-brand"><BrandMark className="brand-mark" /><div><strong>MobilityOps</strong><span>Control centre</span></div></div>
<div className="login-message">
<p className="eyebrow">Connected mobility operations</p>
<h1 id="product-name">Every hand-off.<br />One clear view.</h1>
<p>Turn fleet state, rental returns, data quality and automation into one calm operational rhythm.</p>
</div>
<div className="control-illustration" aria-hidden="true">
<div className="illustration-orbit orbit-one"><span /></div>
<div className="illustration-orbit orbit-two"><span /></div>
<div className="illustration-core"><BrandMark /></div>
<span className="illustration-node node-one"><Icon name="fleet" /></span>
<span className="illustration-node node-two"><Icon name="bookings" /></span>
<span className="illustration-node node-three"><Icon name="quality" /></span>
</div>
<p className="login-footnote"><Icon name="shield" /> Synthetic proof of concept · no real customer data</p>
</section>
<section className="login-panel panel" aria-labelledby="login-heading">
<h2 id="login-heading">Choose a demo role</h2>
{error && (
<p className="error" role="alert">
{error}
</p>
)}
<div className="login-options">
<button type="button" disabled={loading} onClick={() => handleLogin("operations_manager")}>
Open as Operations Manager
</button>
<p>See the dashboard, resolve data-quality issues, retry automation and reset the demo.</p>
<button type="button" disabled={loading} onClick={() => handleLogin("rental_employee")}>
Open as Rental Employee
</button>
<p>Register vehicle returns and look up bookings, vehicles and procedures.</p>
<section className="login-access" aria-labelledby="login-heading">
<div className="login-panel">
<p className="page-eyebrow">Demo access</p>
<h2 id="login-heading">Choose your workspace</h2>
<p className="login-intro">No password is required. Each role opens a scoped synthetic environment.</p>
{error && <p className="error" role="alert">{error}</p>}
<div className="login-options">
<button type="button" aria-label="Open as Operations Manager" disabled={loading} onClick={() => handleLogin("operations_manager")}>
<span className="role-icon"><Icon name="activity" /></span>
<span><strong>Operations Manager</strong><small>Full overview, quality resolution and retries</small></span>
<Icon name="chevron" />
</button>
<button type="button" aria-label="Open as Rental Employee" disabled={loading} onClick={() => handleLogin("rental_employee")}>
<span className="role-icon"><Icon name="user" /></span>
<span><strong>Rental Employee</strong><small>Bookings, returns, fleet and procedures</small></span>
<Icon name="chevron" />
</button>
</div>
<div className="access-note"><Icon name="shield" /><p><strong>Safe by design</strong><span>All actions are audited and resettable in this demo.</span></p></div>
</div>
</section>
</main>