Merge branch 'estif-branch-1' of https://github.com/Tria-plc/emaui into estif-branch-1

This commit is contained in:
Estifo77
2026-07-24 12:32:07 +03:00

View File

@@ -8,7 +8,6 @@ import {
Button,
Card,
Divider,
Grid,
Group,
Modal,
MultiSelect,
@@ -125,6 +124,8 @@ export function VesselRegistrationReviewPage() {
}
const isTerminal = status === 'Approved' || status === 'Rejected';
const hasRemarks = Boolean(record.remarks || (record.correctionFields && record.correctionFields.length > 0));
const hasCertificates = Boolean(record.certificates && record.certificates.length > 0);
const decide = (newStatus: RegistrationStatus, label: string) => {
applyDecision(record, newStatus, remarks, newStatus === 'Correction Required' ? correctionFields : undefined);
@@ -245,120 +246,116 @@ export function VesselRegistrationReviewPage() {
</Stepper>
</Paper>
{/* Two-column body */}
<Grid gutter="md">
{/* Left column */}
<Grid.Col span={{ base: 12, lg: 7 }}>
<Tabs defaultValue="information" variant="outline">
<Tabs.List mb="md">
<Tabs.Tab value="information" leftSection={<IconInfoCircle size={15} />}>Information</Tabs.Tab>
<Tabs.Tab value="documents" leftSection={<IconFiles size={15} />}>Documents</Tabs.Tab>
</Tabs.List>
{/* Tabs */}
<Tabs defaultValue="information" variant="outline">
<Tabs.List mb="md">
<Tabs.Tab value="information" leftSection={<IconInfoCircle size={15} />}>Information</Tabs.Tab>
<Tabs.Tab value="documents" leftSection={<IconFiles size={15} />}>Documents</Tabs.Tab>
{hasRemarks && <Tabs.Tab value="remarks" leftSection={<IconAlertTriangle size={15} />}>Officer Remarks</Tabs.Tab>}
{hasCertificates && <Tabs.Tab value="certificates" leftSection={<IconCircleCheck size={15} />}>Certificates</Tabs.Tab>}
</Tabs.List>
<Tabs.Panel value="information">
<Stack gap="md">
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Vessel Information</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<InfoRow label="Vessel Name" value={record.vesselName} />
<InfoRow label="Vessel Type" value={record.vesselType} />
<InfoRow label="Category" value={record.category} />
<InfoRow label="Registration Area" value={record.registrationArea} />
<InfoRow label="Flag State" value={record.flagState} />
<InfoRow
label={record.category === 'Sea-going' ? 'Gross Tonnage (GT)' : 'Passenger Capacity'}
value={(record.category === 'Sea-going' ? record.grossTonnage : record.passengerCapacity) ?? ''}
/>
<InfoRow label="Length / Breadth / Depth" value={`${record.length} / ${record.breadth} / ${record.depth}`} />
</SimpleGrid>
</Paper>
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Technical Specifications</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<InfoRow
label={record.category === 'Sea-going' ? 'IMO Number' : 'Hull Number'}
value={(record.category === 'Sea-going' ? record.imoNumber : record.hullNumber) ?? ''}
/>
<InfoRow label="Shipyard" value={record.shipyard} />
<InfoRow label="Year Built" value={record.yearBuilt} />
<InfoRow label="Engine Type" value={record.engineType} />
<InfoRow label="Engine Number" value={record.engineNumber} />
<InfoRow label="Engine Power" value={record.enginePower} />
<InfoRow label="Hull Material" value={record.hullMaterial} />
</SimpleGrid>
</Paper>
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Ownership Information</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<InfoRow label="Owner Name" value={record.owner.name} />
<InfoRow label="National ID / TIN" value={record.owner.idOrTin} />
<InfoRow label="Phone Number" value={record.owner.phone} />
<InfoRow label="Email Address" value={record.owner.email} />
<InfoRow label="Address" value={record.owner.address} />
</SimpleGrid>
</Paper>
</Stack>
</Tabs.Panel>
<Tabs.Panel value="documents">
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Documents</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="sm">
{record.documents.map((doc) => <DocViewer key={doc.key} label={doc.label} fileName={doc.fileName} fileType={doc.fileType} />)}
</SimpleGrid>
</Paper>
</Tabs.Panel>
</Tabs>
</Grid.Col>
{/* Right column */}
<Grid.Col span={{ base: 12, lg: 5 }}>
<Tabs.Panel value="information">
<Stack gap="md">
{(record.remarks || (record.correctionFields && record.correctionFields.length > 0)) && (
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="sm">Officer Remarks</Text>
{record.remarks && <Text fz="sm" mb="sm">{record.remarks}</Text>}
{record.correctionFields && record.correctionFields.length > 0 && (
<Group gap={6}>
{record.correctionFields.map((f) => <Badge key={f} size="sm" color="orange" variant="light">{f}</Badge>)}
</Group>
)}
</Paper>
)}
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Vessel Information</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<InfoRow label="Vessel Name" value={record.vesselName} />
<InfoRow label="Vessel Type" value={record.vesselType} />
<InfoRow label="Category" value={record.category} />
<InfoRow label="Registration Area" value={record.registrationArea} />
<InfoRow label="Flag State" value={record.flagState} />
<InfoRow
label={record.category === 'Sea-going' ? 'Gross Tonnage (GT)' : 'Passenger Capacity'}
value={(record.category === 'Sea-going' ? record.grossTonnage : record.passengerCapacity) ?? ''}
/>
<InfoRow label="Length / Breadth / Depth" value={`${record.length} / ${record.breadth} / ${record.depth}`} />
</SimpleGrid>
</Paper>
{status === 'Approved' && record.certificates && (
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Certificates</Text>
<Stack gap="sm">
{record.certificates.map((cert) => (
<div key={cert.name}>
<Group justify="space-between" wrap="wrap" gap="xs">
<div>
<Text fw={600} fz="sm">{cert.name}</Text>
<Text fz="xs" c="dimmed">No. {cert.number} Issued {cert.issueDate}</Text>
</div>
<Button
size="xs"
variant="light"
leftSection={<IconDownload size={13} />}
component="a"
href={DEMO_PDF}
download={`${cert.name.replace(/\s+/g, '-')}-${cert.number}.pdf`}
>
Download
</Button>
</Group>
<Divider mt="sm" />
</div>
))}
</Stack>
</Paper>
)}
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Technical Specifications</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<InfoRow
label={record.category === 'Sea-going' ? 'IMO Number' : 'Hull Number'}
value={(record.category === 'Sea-going' ? record.imoNumber : record.hullNumber) ?? ''}
/>
<InfoRow label="Shipyard" value={record.shipyard} />
<InfoRow label="Year Built" value={record.yearBuilt} />
<InfoRow label="Engine Type" value={record.engineType} />
<InfoRow label="Engine Number" value={record.engineNumber} />
<InfoRow label="Engine Power" value={record.enginePower} />
<InfoRow label="Hull Material" value={record.hullMaterial} />
</SimpleGrid>
</Paper>
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Ownership Information</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<InfoRow label="Owner Name" value={record.owner.name} />
<InfoRow label="National ID / TIN" value={record.owner.idOrTin} />
<InfoRow label="Phone Number" value={record.owner.phone} />
<InfoRow label="Email Address" value={record.owner.email} />
<InfoRow label="Address" value={record.owner.address} />
</SimpleGrid>
</Paper>
</Stack>
</Grid.Col>
</Grid>
</Tabs.Panel>
<Tabs.Panel value="documents">
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Documents</Text>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="sm">
{record.documents.map((doc) => <DocViewer key={doc.key} label={doc.label} fileName={doc.fileName} fileType={doc.fileType} />)}
</SimpleGrid>
</Paper>
</Tabs.Panel>
{hasRemarks && (
<Tabs.Panel value="remarks">
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="sm">Officer Remarks</Text>
{record.remarks && <Text fz="sm" mb="sm">{record.remarks}</Text>}
{record.correctionFields && record.correctionFields.length > 0 && (
<Group gap={6}>
{record.correctionFields.map((f) => <Badge key={f} size="sm" color="orange" variant="light">{f}</Badge>)}
</Group>
)}
</Paper>
</Tabs.Panel>
)}
{hasCertificates && (
<Tabs.Panel value="certificates">
<Paper withBorder radius="lg" p="xl">
<Text fw={700} mb="md">Certificates</Text>
<Stack gap="sm">
{record.certificates!.map((cert) => (
<div key={cert.name}>
<Group justify="space-between" wrap="wrap" gap="xs">
<div>
<Text fw={600} fz="sm">{cert.name}</Text>
<Text fz="xs" c="dimmed">No. {cert.number} Issued {cert.issueDate}</Text>
</div>
<Button
size="xs"
variant="light"
leftSection={<IconDownload size={13} />}
component="a"
href={DEMO_PDF}
download={`${cert.name.replace(/\s+/g, '-')}-${cert.number}.pdf`}
>
Download
</Button>
</Group>
<Divider mt="sm" />
</div>
))}
</Stack>
</Paper>
</Tabs.Panel>
)}
</Tabs>
</Stack>
);
}