mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-27 07:22:56 +00:00
195 lines
5.5 KiB
TypeScript
195 lines
5.5 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import {
|
|
Box,
|
|
Center,
|
|
Flex,
|
|
Group,
|
|
Stack,
|
|
Text,
|
|
Title,
|
|
rem,
|
|
useComputedColorScheme,
|
|
useMantineTheme,
|
|
type BoxProps,
|
|
} from '@mantine/core';
|
|
import { IconCheck } from '@tabler/icons-react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { ColorSchemeToggle, LanguageSwitcher } from '@ema-platform/ui';
|
|
import { useAuthConfig } from '../AuthConfig';
|
|
|
|
export function BrandMark({ size = 44, ...boxProps }: BoxProps & { size?: number }) {
|
|
const { logoUrl } = useAuthConfig();
|
|
return (
|
|
<Box
|
|
component="img"
|
|
src={logoUrl}
|
|
alt="EMA"
|
|
w={size}
|
|
h={size}
|
|
style={{ display: 'block', objectFit: 'contain', flexShrink: 0 }}
|
|
{...boxProps}
|
|
/>
|
|
);
|
|
}
|
|
|
|
interface AuthShellProps {
|
|
children: ReactNode;
|
|
brandTitle?: string;
|
|
brandSubtitle?: string;
|
|
}
|
|
|
|
export function AuthShell({ children, brandTitle, brandSubtitle }: AuthShellProps) {
|
|
const { t } = useTranslation();
|
|
const theme = useMantineTheme();
|
|
const { logoUrl } = useAuthConfig();
|
|
const heroGradient = theme.other.heroGradient as string;
|
|
const computed = useComputedColorScheme('light');
|
|
const isDark = computed === 'dark';
|
|
const resolvedBrandTitle =
|
|
brandTitle ?? t('authShell.brandTitle', 'Maritime licensing, made simple.');
|
|
const resolvedBrandSubtitle =
|
|
brandSubtitle ??
|
|
t(
|
|
'authShell.brandSubtitle',
|
|
'Apply for vessel and seafarer licenses, upload documents, and track every application in one secure portal.',
|
|
);
|
|
const FEATURES = [
|
|
t('authShell.feature1', 'Submit applications online, 24/7'),
|
|
t('authShell.feature2', 'Real-time status tracking & alerts'),
|
|
t('authShell.feature3', 'Available in English & አማርኛ'),
|
|
];
|
|
|
|
return (
|
|
<Box
|
|
mih="100vh"
|
|
style={{
|
|
background: 'var(--mantine-color-body)',
|
|
position: 'relative',
|
|
}}
|
|
p="md"
|
|
>
|
|
{/* Language switcher & Theme toggle — top-right corner */}
|
|
<Group
|
|
gap="xs"
|
|
style={{
|
|
position: 'absolute',
|
|
top: rem(16),
|
|
right: rem(16),
|
|
zIndex: 10,
|
|
}}
|
|
>
|
|
<LanguageSwitcher supportedLanguages={['en', 'am']} />
|
|
<ColorSchemeToggle />
|
|
</Group>
|
|
|
|
<Flex
|
|
mih="100vh"
|
|
align="center"
|
|
justify="center"
|
|
>
|
|
<Box
|
|
mx="auto"
|
|
maw={1280}
|
|
w="100%"
|
|
p={12}
|
|
style={{
|
|
borderRadius: rem(16),
|
|
background: 'var(--mantine-color-body)',
|
|
boxShadow: isDark
|
|
? '0 20px 60px rgba(0,0,0,0.5)'
|
|
: '0 20px 60px rgba(0,0,0,0.15)',
|
|
overflow: 'hidden',
|
|
}}
|
|
>
|
|
<Flex direction={{ base: 'column', lg: 'row' }}>
|
|
<Box
|
|
w={{ base: '100%', lg: '50%' }}
|
|
px={48}
|
|
py={48}
|
|
style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center' }}
|
|
>
|
|
{children}
|
|
</Box>
|
|
|
|
<Box
|
|
visibleFrom="lg"
|
|
w="50%"
|
|
p="lg"
|
|
pos="relative"
|
|
style={{ background: heroGradient, overflow: 'hidden' }}
|
|
>
|
|
<Box
|
|
pos="absolute"
|
|
top={-80}
|
|
right={-40}
|
|
w={240}
|
|
h={240}
|
|
style={{ borderRadius: '50%', background: 'rgba(255,255,255,0.10)' }}
|
|
/>
|
|
<Box
|
|
pos="absolute"
|
|
bottom={-80}
|
|
left={-60}
|
|
w={220}
|
|
h={220}
|
|
style={{ borderRadius: '50%', background: 'rgba(255,255,255,0.08)' }}
|
|
/>
|
|
|
|
<Stack
|
|
gap="lg"
|
|
pos="relative"
|
|
style={{ zIndex: 1 }}
|
|
h="100%"
|
|
justify="center"
|
|
>
|
|
<Center>
|
|
<Box
|
|
component="img"
|
|
src={logoUrl}
|
|
alt="EMA Portal"
|
|
style={{ display: 'block', maxWidth: '60%', height: 'auto' }}
|
|
/>
|
|
</Center>
|
|
|
|
<Stack gap={6}>
|
|
<Title order={2} c="white" fz={rem(28)} lh={1.2} fw={700}>
|
|
{resolvedBrandTitle}
|
|
</Title>
|
|
<Text fz="sm" lh={1.6} style={{ color: 'rgba(255,255,255,0.85)' }}>
|
|
{resolvedBrandSubtitle}
|
|
</Text>
|
|
</Stack>
|
|
|
|
<Stack gap="sm">
|
|
{FEATURES.map((feature) => (
|
|
<Group key={feature} gap="sm" wrap="nowrap">
|
|
<Center
|
|
w={22}
|
|
h={22}
|
|
style={{
|
|
borderRadius: '50%',
|
|
background: 'rgba(255,255,255,0.2)',
|
|
flexShrink: 0,
|
|
}}
|
|
>
|
|
<IconCheck size={12} color="white" stroke={2.4} />
|
|
</Center>
|
|
<Text c="white" fz="sm" fw={500}>
|
|
{feature}
|
|
</Text>
|
|
</Group>
|
|
))}
|
|
</Stack>
|
|
|
|
<Text fz="xs" style={{ color: 'rgba(255,255,255,0.7)' }}>
|
|
{t('authShell.copyright', '© 2026 Ethiopian Maritime Authority')}
|
|
</Text>
|
|
</Stack>
|
|
</Box>
|
|
</Flex>
|
|
</Box>
|
|
</Flex>
|
|
</Box>
|
|
);
|
|
}
|