diff --git a/apps/backoffice/src/app/features/exam/components/ExamCandidatesPanel/columns.tsx b/apps/backoffice/src/app/features/exam/components/ExamCandidatesPanel/columns.tsx index e25910ab2..0884a3db6 100644 --- a/apps/backoffice/src/app/features/exam/components/ExamCandidatesPanel/columns.tsx +++ b/apps/backoffice/src/app/features/exam/components/ExamCandidatesPanel/columns.tsx @@ -1,5 +1,5 @@ -import { Badge, Button, Menu, Text } from '@mantine/core'; -import { IconChevronDown, IconRefresh, IconUserCheck } from '@tabler/icons-react'; +import { ActionIcon, Badge, Menu, Text } from '@mantine/core'; +import { IconDotsVertical, IconRefresh, IconUserCheck } from '@tabler/icons-react'; import type { TFunction } from 'i18next'; import type { AdvancedColumn } from '@ema-platform/ui'; import { LICENSE_PERMISSIONS, RequirePermission } from '@ema-platform/auth'; @@ -88,14 +88,14 @@ export function examCandidateColumns( return ( - + + void; onDelete: (exam: Exam) => void; onDetails: (exam: Exam) => void; - onChangeStatus: (exam: Exam, status: ExamStatus) => void; + onOpenStatusChange: (exam: Exam) => void; changingStatusId?: string | null; }, ): AdvancedColumn { @@ -33,16 +25,16 @@ export function examActionsColumn( header: t("exam.columns.actions", "Actions"), align: "right", cell: ({ row }) => ( - + - + + {t("exam.action.edit", "Edit")} + } + onClick={() => handlers.onOpenStatusChange(row.original)} + > + {t("exam.form.status")} + } @@ -65,17 +63,6 @@ export function examActionsColumn( > {t("exam.action.delete", "Delete")} - - {t("exam.form.status")} - {STATUSES.map((status) => ( - handlers.onChangeStatus(row.original, status)} - > - {t(`exam.form.${status.toLowerCase()}`)} - - ))} diff --git a/apps/backoffice/src/app/features/exam/pages/ExamPage/index.tsx b/apps/backoffice/src/app/features/exam/pages/ExamPage/index.tsx index 75d6243ef..61ff9aa36 100644 --- a/apps/backoffice/src/app/features/exam/pages/ExamPage/index.tsx +++ b/apps/backoffice/src/app/features/exam/pages/ExamPage/index.tsx @@ -369,6 +369,10 @@ export function ExamPage() { const [deleteOpened, { open: openDelete, close: closeDelete }] = useDisclosure(false); const [changingStatusId, setChangingStatusId] = useState(null); + const [statusTarget, setStatusTarget] = useState(null); + const [pendingStatus, setPendingStatus] = useState(null); + const [statusOpened, { open: openStatus, close: closeStatus }] = + useDisclosure(false); const certOptions = certifications .filter((c) => c.isActive) @@ -419,11 +423,14 @@ export function ExamPage() { } }; - const handleChangeStatus = async (exam: Exam, status: Exam["status"]) => { - setChangingStatusId(exam.id); + const handleChangeStatus = async () => { + if (!statusTarget || !pendingStatus) return; + setChangingStatusId(statusTarget.id); try { - await updateExam({ id: exam.id, status }).unwrap(); + await updateExam({ id: statusTarget.id, status: pendingStatus }).unwrap(); notify.success(t("exam.updated")); + closeStatus(); + setStatusTarget(null); } catch (e) { handleError(e); } finally { @@ -464,7 +471,11 @@ export function ExamPage() { openDelete(); }, onDetails: (exam) => navigate(`/exams/${exam.id}`), - onChangeStatus: handleChangeStatus, + onOpenStatusChange: (exam) => { + setStatusTarget(exam); + setPendingStatus(exam.status); + openStatus(); + }, changingStatusId, }), ]; @@ -541,6 +552,47 @@ export function ExamPage() { + + {/* Quick status change — not the full edit form */} + + + + {statusTarget?.title?.[locale]} + +