import { useState } from 'react'; import { Alert, Button, Modal, Select, Stack, Text } from '@mantine/core'; import { IconCalendarEvent } from '@tabler/icons-react'; import { useTranslation } from 'react-i18next'; import { ModalFooter } from '@ema-platform/ui'; import { useGetEligibleExamsQuery } from '@ema-platform/api'; interface Props { opened: boolean; applicationId: string; applicantName: string; loading: boolean; onClose: () => void; onConfirm: (payload: { examId: string; examDate?: string }) => void; } /** * Places a candidate who has paid the examination fee into an existing sitting. * * Sessions are picked from the exam calendar rather than typed, because the * candidate joins a scheduled sitting — this is an assignment, not the creation * of a per-candidate appointment. Scoped to sittings whose certification * matches this application's rank, so a Chief Mate candidate cannot be seated * into an OOW Deck sitting by accident. */ export function ScheduleExamModal({ opened, applicationId, applicantName, loading, onClose, onConfirm, }: Props) { const { t } = useTranslation(); const { data: exams, isLoading } = useGetEligibleExamsQuery(applicationId, { skip: !opened }); const [examId, setExamId] = useState(null); const options = (exams ?? []).map((exam) => ({ value: exam.id, label: [exam.title?.en ?? exam.title?.am ?? t('exam.untitled', 'Untitled exam'), exam.date] .filter(Boolean) .join(' — '), })); const selected = exams?.find((exam) => exam.id === examId); function confirm() { if (!examId) return; onConfirm({ examId, examDate: selected?.date ? String(selected.date) : undefined, }); } return ( {t('review.scheduleExam.intro', { defaultValue: 'Assign {{applicant}} to a scheduled sitting. They will be notified with the date and their admission number.', applicant: applicantName, })} {!isLoading && options.length === 0 ? ( }> {t( 'review.scheduleExam.noSessions', 'No exam sessions for this rank exist yet. Create one in the Exams area first.', )} ) : (