mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-09-07 11:55:43 +00:00
feat(i18n): add new translations for refresh, view, toggle columns, and no results
refactor(payment): remove payment API client and related tests, consolidating payment logic refactor(payment): delete payment modal and associated constants, hooks, and types fix(ui): enhance AdvancedTable with refresh button and column toggle functionality fix(ui): implement pagination in useServerTable for better data handling
This commit is contained in:
@@ -5,7 +5,6 @@ import {
|
||||
Title,
|
||||
Group,
|
||||
Button,
|
||||
Table,
|
||||
Badge,
|
||||
ActionIcon,
|
||||
Modal,
|
||||
@@ -13,8 +12,7 @@ import {
|
||||
TextInput,
|
||||
Textarea,
|
||||
Paper,
|
||||
Loader,
|
||||
Center,
|
||||
Card,
|
||||
Alert,
|
||||
Select,
|
||||
NumberInput,
|
||||
@@ -33,7 +31,7 @@ import {
|
||||
IconClipboardList,
|
||||
IconDetails,
|
||||
} from "@tabler/icons-react";
|
||||
import { notify, useErrorHandler } from "@ema-platform/ui";
|
||||
import { notify, useErrorHandler, AdvancedTable, useServerTable, type AdvancedColumn } from "@ema-platform/ui";
|
||||
import { useGetCertificationsQuery } from "../../certification/api/certification-api";
|
||||
import {
|
||||
useGetExamsQuery,
|
||||
@@ -356,7 +354,8 @@ export function ExamPage() {
|
||||
const { handleError } = useErrorHandler();
|
||||
const locale = i18n.language as "en" | "am";
|
||||
const { data: certRes } = useGetCertificationsQuery();
|
||||
const { data, isLoading, isError } = useGetExamsQuery();
|
||||
const { data, isFetching, isError, refetch } = useGetExamsQuery();
|
||||
const { setPageIndex, pageSize, paginate } = useServerTable({ pageSize: 25 });
|
||||
const [createExam, { isLoading: isCreating }] = useCreateExamMutation();
|
||||
const [updateExam, { isLoading: isUpdating }] = useUpdateExamMutation();
|
||||
const [deleteExam] = useDeleteExamMutation();
|
||||
@@ -431,12 +430,6 @@ export function ExamPage() {
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<Center py="xl">
|
||||
<Loader />
|
||||
</Center>
|
||||
);
|
||||
if (isError)
|
||||
return (
|
||||
<Alert
|
||||
@@ -446,6 +439,109 @@ export function ExamPage() {
|
||||
/>
|
||||
);
|
||||
|
||||
const columns: AdvancedColumn<Exam>[] = [
|
||||
{
|
||||
header: t("exam.columns.title"),
|
||||
cell: ({ row }) => (
|
||||
<Text
|
||||
fz="sm"
|
||||
fw={500}
|
||||
c="blue"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => navigate(`/exams/${row.original.id}`)}
|
||||
>
|
||||
{row.original.title[locale]}
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.certification"),
|
||||
cell: ({ row }) => <Text fz="sm">{getCertName(row.original.certificationId)}</Text>,
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.date"),
|
||||
cell: ({ row }) => <Text fz="sm">{row.original.date}</Text>,
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.type"),
|
||||
cell: ({ row }) => (
|
||||
<Badge size="sm" variant="light" color={row.original.type === "WRITTEN" ? "blue" : "orange"}>
|
||||
{t(`exam.type.${row.original.type}`)}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.form"),
|
||||
cell: ({ row }) => (
|
||||
<Badge size="sm" variant="light" color={row.original.form === "ESSAY" ? "blue" : "violet"}>
|
||||
{t(`exam.formType.${row.original.form}`)}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.venue"),
|
||||
cell: ({ row }) => <Text fz="sm">{row.original.venue}</Text>,
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.questions"),
|
||||
cell: ({ row }) => (
|
||||
<Badge size="sm" variant="light" color="gray">
|
||||
{row.original.questions?.length ?? 0}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.status"),
|
||||
cell: ({ row }) => (
|
||||
<Badge size="sm" variant="light" color={STATUS_COLOR[row.original.status]}>
|
||||
{t(`exam.status.${row.original.status}`)}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
header: t("exam.columns.actions"),
|
||||
align: "right",
|
||||
cell: ({ row }) => (
|
||||
<Group gap="xs">
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="blue"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setEditing(row.original);
|
||||
setShowForm(true);
|
||||
}}
|
||||
>
|
||||
<IconEdit size={14} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="red"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setDeleteTarget(row.original);
|
||||
openDelete();
|
||||
}}
|
||||
>
|
||||
<IconTrash size={14} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="red"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
navigate(`/exams/${row.original.id}`);
|
||||
}}
|
||||
>
|
||||
<IconDetails size={14} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const page = paginate(exams);
|
||||
|
||||
return (
|
||||
<Stack gap="lg">
|
||||
<Group justify="space-between" align="flex-end">
|
||||
@@ -477,127 +573,20 @@ export function ExamPage() {
|
||||
/>
|
||||
)}
|
||||
|
||||
<Paper withBorder radius="md">
|
||||
<Table striped highlightOnHover>
|
||||
<Table.Thead bg="var(--mantine-color-default-hover)">
|
||||
<Table.Tr>
|
||||
<Table.Th>{t("exam.columns.title")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.certification")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.date")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.type")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.form")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.venue")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.questions")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.status")}</Table.Th>
|
||||
<Table.Th>{t("exam.columns.actions")}</Table.Th>
|
||||
<Table.Th />
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{exams.map((exam) => (
|
||||
<Table.Tr key={exam.id}>
|
||||
<Table.Td>
|
||||
<Text
|
||||
fz="sm"
|
||||
fw={500}
|
||||
c="blue"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => navigate(`/exams/${exam.id}`)}
|
||||
>
|
||||
{exam.title[locale]}
|
||||
</Text>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Text fz="sm">{getCertName(exam.certificationId)}</Text>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Text fz="sm">{exam.date}</Text>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="light"
|
||||
color={exam.type === "WRITTEN" ? "blue" : "orange"}
|
||||
>
|
||||
{t(`exam.type.${exam.type}`)}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="light"
|
||||
color={exam.form === "ESSAY" ? "blue" : "violet"}
|
||||
>
|
||||
{t(`exam.formType.${exam.form}`)}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Text fz="sm">{exam.venue}</Text>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Badge size="sm" variant="light" color="gray">
|
||||
{exam.questions?.length ?? 0}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="light"
|
||||
color={STATUS_COLOR[exam.status]}
|
||||
>
|
||||
{t(`exam.status.${exam.status}`)}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Group gap="xs">
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="blue"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setEditing(exam);
|
||||
setShowForm(true);
|
||||
}}
|
||||
>
|
||||
<IconEdit size={14} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="red"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setDeleteTarget(exam);
|
||||
openDelete();
|
||||
}}
|
||||
>
|
||||
<IconTrash size={14} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="red"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
navigate(`/exams/${exam.id}`);
|
||||
}}
|
||||
>
|
||||
<IconDetails size={14} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
{exams.length === 0 && (
|
||||
<Table.Tr>
|
||||
<Table.Td colSpan={9}>
|
||||
<Text c="dimmed" ta="center" py="xl">
|
||||
{t("exam.noItems")}
|
||||
</Text>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
)}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Paper>
|
||||
<Card withBorder padding={0}>
|
||||
<AdvancedTable
|
||||
columns={columns}
|
||||
data={page.rows}
|
||||
tableName={t("exam.title")}
|
||||
itemCount={page.itemCount}
|
||||
pageIndex={page.pageIndex}
|
||||
onPageChange={setPageIndex}
|
||||
pageSize={pageSize}
|
||||
refresh={refetch}
|
||||
isLoading={isFetching}
|
||||
emptyText={t("exam.noItems")}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
{/* Delete confirmation */}
|
||||
<Modal
|
||||
|
||||
Reference in New Issue
Block a user