Files
emaui/apps/portal/src/app/features/vessel-owner/pages/VesselOwnerDashboardPage.tsx
fitse-yotor eabaae36a0 feat(portal): restore Mengestab's client-approved seafarer and vessel UI
Copied verbatim from the pre-override branch so the approved screens are
recoverable at this exact commit before any wiring changes them.

Brings back the richer flows the client signed off: a four-step seafarer
registration wizard with bilingual inputs and an Ethiopic date picker,
the vessel-owner portal (its own register/login/dashboard), ownership
transfer, and the seaman book, certificate, medical and endorsement
screens.

Six of these pages already call an API; ten are mockups carrying
hardcoded data. Both are committed as-is here -- the wiring that follows
is a separate commit so the diff shows exactly what changed from what
the client approved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 23:19:08 +03:00

115 lines
3.8 KiB
TypeScript

import { useNavigate } from 'react-router-dom';
import {
Alert,
Button,
Card,
Group,
Paper,
SimpleGrid,
Stack,
Text,
ThemeIcon,
Title,
} from '@mantine/core';
import {
IconAnchor,
IconCheck,
IconClock,
IconInfoCircle,
IconShip,
} from '@tabler/icons-react';
// Sample mock — in production this comes from the API
const MOCK_MY_VESSELS = [
{
id: 'VR-2024-001',
vesselName: 'Lake Tana Star',
category: 'Inland Waterway Vessel',
vesselType: 'Passenger Ferry',
status: 'Under Review',
submittedDate: '2024-03-15',
},
];
const STATUS_COLOR: Record<string, string> = {
Pending: 'gray', 'Under Review': 'yellow', Approved: 'teal', Rejected: 'red', 'Correction Required': 'orange',
};
export function VesselOwnerDashboardPage() {
const navigate = useNavigate();
return (
<Stack gap="md">
<Group justify="space-between">
<Group gap="sm">
<ThemeIcon size={44} radius="md" color="blue" variant="light">
<IconShip size={24} />
</ThemeIcon>
<div>
<Title order={3}>My Vessels</Title>
<Text fz="sm" c="dimmed">Manage your vessel registrations</Text>
</div>
</Group>
<Button leftSection={<IconAnchor size={16} />} onClick={() => navigate('/vessel-registration/apply')}>
Register New Vessel
</Button>
</Group>
{MOCK_MY_VESSELS.length === 0 ? (
<Paper withBorder radius="lg" p="xl">
<Stack align="center" gap="md" py="xl">
<ThemeIcon size={56} radius="xl" color="blue" variant="light">
<IconAnchor size={30} />
</ThemeIcon>
<Title order={4} ta="center">No Vessels Registered</Title>
<Text fz="sm" c="dimmed" ta="center" maw={400}>
You haven't registered any vessels yet. Click "Register New Vessel" to begin the application process.
</Text>
<Button onClick={() => navigate('/vessel-registration/apply')}>Start Registration</Button>
</Stack>
</Paper>
) : (
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
{MOCK_MY_VESSELS.map((v) => (
<Card key={v.id} withBorder radius="md" p="md">
<Group justify="space-between" mb="xs">
<Group gap="sm">
<ThemeIcon size={36} radius="md" color="blue" variant="light">
<IconShip size={20} />
</ThemeIcon>
<div>
<Text fw={700} fz="sm">{v.vesselName}</Text>
<Text fz="xs" c="dimmed">{v.id}</Text>
</div>
</Group>
<Text fz="xs" fw={600} c={`${STATUS_COLOR[v.status]}.6`}>{v.status}</Text>
</Group>
<Stack gap={4} mt="sm">
<Group gap="xs">
<Text fz="xs" c="dimmed">Category:</Text>
<Text fz="xs">{v.category}</Text>
</Group>
<Group gap="xs">
<Text fz="xs" c="dimmed">Type:</Text>
<Text fz="xs">{v.vesselType}</Text>
</Group>
<Group gap="xs">
<Text fz="xs" c="dimmed">Submitted:</Text>
<Text fz="xs">{v.submittedDate}</Text>
</Group>
</Stack>
<Button size="xs" variant="light" fullWidth mt="sm" onClick={() => navigate('/vessel-registration')}>
View Details
</Button>
</Card>
))}
</SimpleGrid>
)}
<Alert icon={<IconInfoCircle size={16} />} color="blue" variant="light">
Vessel registration is valid for <strong>5 years</strong> from the approval date. You will be notified when renewal is due.
</Alert>
</Stack>
);
}