mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 10:52:53 +00:00
152 lines
6.8 KiB
TypeScript
152 lines
6.8 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import { ArrowUpRight, ChevronDown, Globe } from "lucide-react";
|
|
|
|
const LOGIN_IMAGE = "/assets/login.png";
|
|
const EDR_LOGO = "/assets/logo.svg";
|
|
|
|
export const fieldClass =
|
|
"h-11 w-full rounded-xl border border-gray-200/90 bg-white px-4 text-sm text-gray-900 shadow-sm placeholder:text-gray-400 outline-none transition-all duration-200 hover:border-gray-300 focus:border-primary focus:bg-white focus:ring-4 focus:ring-primary/10";
|
|
|
|
export const primaryButtonClass =
|
|
"h-11 w-full rounded-full bg-primary text-sm font-semibold text-primary-foreground shadow-[0_8px_20px_-6px_rgba(16,94,52,0.5)] transition-all duration-200 hover:bg-primary/90 hover:shadow-[0_10px_24px_-6px_rgba(16,94,52,0.55)] active:scale-[0.99] disabled:cursor-not-allowed disabled:opacity-60 disabled:shadow-none";
|
|
|
|
const LeftPanelDecor = () => (
|
|
<div className="pointer-events-none absolute inset-0 overflow-hidden" aria-hidden>
|
|
<svg
|
|
className="absolute -bottom-24 -left-24 h-[420px] w-[420px] text-white/[0.07]"
|
|
viewBox="0 0 400 400"
|
|
fill="none"
|
|
>
|
|
{[0, 1, 2, 3, 4, 5].map((ring) => (
|
|
<circle key={ring} cx="200" cy="200" r={60 + ring * 36} stroke="currentColor" strokeWidth="1" />
|
|
))}
|
|
</svg>
|
|
<div className="absolute right-0 top-0 h-40 w-40 rounded-full bg-white/[0.06] blur-2xl" />
|
|
</div>
|
|
);
|
|
|
|
const RightPanelDecor = () => (
|
|
<div className="pointer-events-none absolute inset-0 overflow-hidden" aria-hidden>
|
|
<div className="absolute -right-16 -top-20 h-56 w-56 rounded-full bg-primary/[0.06] blur-3xl" />
|
|
<div className="absolute -bottom-12 left-1/4 h-40 w-40 rounded-full bg-primary/[0.04] blur-2xl" />
|
|
<svg className="absolute inset-0 h-full w-full text-gray-200/40" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<pattern id="auth-grid" width="28" height="28" patternUnits="userSpaceOnUse">
|
|
<circle cx="1" cy="1" r="0.75" fill="currentColor" />
|
|
</pattern>
|
|
</defs>
|
|
<rect width="100%" height="100%" fill="url(#auth-grid)" />
|
|
</svg>
|
|
</div>
|
|
);
|
|
|
|
export interface AuthShellProps {
|
|
children: ReactNode;
|
|
/** Tagline shown in the highlighted card over the left image panel. */
|
|
tagline?: string;
|
|
taglineBody?: string;
|
|
}
|
|
|
|
const LeftPanel = ({ tagline, taglineBody }: Pick<AuthShellProps, "tagline" | "taglineBody">) => (
|
|
<div className="relative hidden shrink-0 flex-col overflow-hidden rounded-2xl shadow-[0_8px_32px_rgba(15,23,42,0.1)] lg:flex lg:h-auto lg:min-h-0 lg:flex-1 lg:basis-1/2 lg:rounded-[28px]">
|
|
<img
|
|
src={LOGIN_IMAGE}
|
|
alt="Ethio Djibouti Railway"
|
|
className="absolute inset-0 h-full w-full object-cover object-center"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-br from-[#0a2e1a]/92 via-[#0f4a2a]/55 to-[#1a5c34]/45" />
|
|
<LeftPanelDecor />
|
|
|
|
<div className="relative z-10 flex shrink-0 items-center justify-between px-4 pt-4 sm:px-6 sm:pt-6 lg:px-8 lg:pt-8">
|
|
<img src={EDR_LOGO} alt="EDR Freight" className="h-7 w-auto brightness-0 invert sm:h-9" />
|
|
<a
|
|
href="#"
|
|
className="flex items-center gap-1.5 rounded-full border border-white/70 bg-white/10 px-3 py-1.5 text-xs font-medium text-white backdrop-blur-sm transition-colors hover:bg-white/20 sm:px-4 sm:py-2 sm:text-sm"
|
|
>
|
|
Support
|
|
<ArrowUpRight className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
|
</a>
|
|
</div>
|
|
|
|
<div className="relative z-10 mt-auto hidden px-8 pb-8 lg:block">
|
|
<div className="max-w-md rounded-2xl border border-white/15 bg-black/30 p-5 backdrop-blur-md">
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<div className="h-2 w-2 shrink-0 rounded-full bg-primary" />
|
|
<span className="text-sm font-semibold text-white">
|
|
{tagline ?? "Empower Your Freight Operations"}
|
|
</span>
|
|
</div>
|
|
<p className="text-sm leading-relaxed text-white/85">
|
|
{taglineBody ??
|
|
"Sign in to manage shipments, track cargo, and run logistics operations on the Ethio Djibouti Railway freight platform."}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
const LanguageSelector = () => (
|
|
<div className="flex cursor-pointer items-center gap-1.5 rounded-full border border-gray-200/80 bg-white px-3 py-1.5 text-sm text-gray-600 shadow-sm">
|
|
<Globe className="h-4 w-4 text-gray-500" />
|
|
<span>Eng</span>
|
|
<ChevronDown className="h-4 w-4 text-gray-400" />
|
|
</div>
|
|
);
|
|
|
|
const FormFooter = () => (
|
|
<div className="relative z-10 flex shrink-0 flex-col items-center justify-between gap-3 border-t border-gray-100 px-4 py-4 text-xs text-gray-400 sm:flex-row sm:gap-4 sm:px-6 sm:py-4 lg:px-8 lg:pb-6">
|
|
<span className="shrink-0">© 2026 EDR Freight</span>
|
|
<div className="flex flex-wrap items-center justify-center gap-3 sm:justify-end sm:gap-6">
|
|
<a href="#" className="font-semibold text-gray-700 transition-colors hover:text-primary">
|
|
Terms & Conditions
|
|
</a>
|
|
<a href="#" className="font-semibold text-gray-700 transition-colors hover:text-primary">
|
|
Privacy Policy
|
|
</a>
|
|
<a href="#" className="font-semibold text-gray-700 transition-colors hover:text-primary">
|
|
Help & Support
|
|
</a>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
export default function AuthShell({ children, tagline, taglineBody }: AuthShellProps) {
|
|
return (
|
|
<>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
|
|
<div
|
|
className="flex h-[100dvh] overflow-hidden bg-[#e8eaef] px-4 py-3 antialiased sm:px-6 sm:py-4 md:px-[70px]"
|
|
style={{ fontFamily: "'Outfit', var(--font-sans)" }}
|
|
>
|
|
<div className="flex h-full min-h-0 w-full flex-col gap-3 lg:flex-row lg:gap-4">
|
|
<LeftPanel tagline={tagline} taglineBody={taglineBody} />
|
|
|
|
<div className="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden rounded-2xl bg-[#f5f7fa] shadow-[0_8px_32px_rgba(15,23,42,0.08)] lg:basis-1/2 lg:rounded-[28px]">
|
|
<RightPanelDecor />
|
|
|
|
<div className="relative z-10 flex shrink-0 justify-end px-4 pt-4 sm:px-6 sm:pt-6 lg:px-8 lg:pt-8">
|
|
<LanguageSelector />
|
|
</div>
|
|
|
|
<div className="relative z-10 min-h-0 flex-1 overflow-y-auto overscroll-contain">
|
|
<div className="flex min-h-full justify-center px-4 py-4 sm:px-6 sm:py-6 lg:px-8 lg:py-8">
|
|
<div className="my-auto w-full max-w-xl rounded-3xl border border-gray-100/80 bg-white px-5 py-6 shadow-[0_4px_24px_rgba(15,23,42,0.06)] sm:px-7 sm:py-8 lg:px-9 lg:py-9">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<FormFooter />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|