mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 11:21:18 +00:00
149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import type { ReactNode } from "react";
|
||
import { Box, Image, Stack, Text, Title } from "@mantine/core";
|
||
import { ChevronDown, Globe } from "lucide-react";
|
||
|
||
const EDR_IMAGE = "/assets/edr_image.png";
|
||
const EDR_LOGO = "/assets/logo.svg";
|
||
|
||
/** Muted deep-green brand wash for the left panel. */
|
||
const LEFT_PANEL_BG =
|
||
"linear-gradient(158deg, #2E6B55 0%, #21503F 46%, #16352A 100%)";
|
||
|
||
/** Radial opacity mask: image fully opaque at its center, fading to nothing at the edges. */
|
||
const IMAGE_FADE_MASK =
|
||
"linear-gradient(-90deg, #000 95%, #0009 97%, #0000 100%), linear-gradient(0deg, #000 80%, #0001 100%)";
|
||
|
||
export interface AuthShellProps {
|
||
children: ReactNode;
|
||
/** Headline shown in the top-left of the green panel. */
|
||
tagline?: string;
|
||
taglineBody?: string;
|
||
}
|
||
|
||
const LeftPanel = ({
|
||
tagline,
|
||
taglineBody,
|
||
}: Pick<AuthShellProps, "tagline" | "taglineBody">) => (
|
||
<Box
|
||
className="relative hidden shrink-0 overflow-hidden rounded-2xl shadow-[0_8px_32px_rgba(15,23,42,0.12)] lg:flex lg:h-auto lg:min-h-0 lg:flex-1 lg:basis-1/2 lg:rounded-[28px]"
|
||
style={{ background: LEFT_PANEL_BG }}
|
||
>
|
||
{/* Top-left: logo, title, description — stacked, left aligned. */}
|
||
<Stack
|
||
gap="xl"
|
||
className="relative z-10 p-8 lg:p-10"
|
||
style={{ maxWidth: 520 }}
|
||
>
|
||
<Image
|
||
src={EDR_LOGO}
|
||
alt="EDR Freight"
|
||
h={40}
|
||
w="auto"
|
||
fit="contain"
|
||
style={{ filter: "brightness(0) invert(1)", alignSelf: "flex-start" }}
|
||
/>
|
||
|
||
<Stack gap="sm">
|
||
<Title
|
||
order={1}
|
||
c="white"
|
||
fz={38}
|
||
fw={800}
|
||
lh={1.08}
|
||
style={{ letterSpacing: "-0.02em" }}
|
||
>
|
||
{tagline ?? "Ethiopian Djibouti Railway"}
|
||
</Title>
|
||
<Text fz="md" lh={1.6} c="rgba(255,255,255,0.82)" maw={440}>
|
||
{taglineBody ??
|
||
"Manage bookings, track cargo, and run day-to-day logistics for the Ethio–Djibouti Railway from a single backoffice."}
|
||
</Text>
|
||
</Stack>
|
||
</Stack>
|
||
|
||
{/* Bottom-right: brand image with a center-to-edge opacity fade, no color tint. */}
|
||
<Image
|
||
src={EDR_IMAGE}
|
||
alt=""
|
||
aria-hidden
|
||
fit="cover"
|
||
pos="absolute"
|
||
right={0}
|
||
bottom={0}
|
||
w="80%"
|
||
h="60%"
|
||
style={{
|
||
WebkitMaskImage: IMAGE_FADE_MASK,
|
||
maskImage: IMAGE_FADE_MASK,
|
||
pointerEvents: "none",
|
||
opacity: 0.9,
|
||
maskComposite: "intersect",
|
||
}}
|
||
/>
|
||
</Box>
|
||
);
|
||
|
||
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>
|
||
);
|
||
|
||
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>
|
||
);
|
||
|
||
export default function AuthShell({
|
||
children,
|
||
tagline,
|
||
taglineBody,
|
||
}: AuthShellProps) {
|
||
return (
|
||
<div className="flex h-[100dvh] overflow-hidden bg-[#e8eaef] px-4 py-3 antialiased sm:px-6 sm:py-4 md:px-[70px]">
|
||
<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-white 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">
|
||
<div className="my-auto w-full max-w-xl rounded-3xl px-5 py-6 sm:px-7 sm:py-8 lg:px-9 lg:py-9">
|
||
{children}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|