Add authentification

This commit is contained in:
2026-02-17 00:54:36 +01:00
parent ab98ba81c8
commit a8c8c489da
31 changed files with 1118 additions and 451 deletions

View File

@@ -1,50 +1,57 @@
import { Button, Group, Modal, TextInput, Title, type ModalBaseProps } from "@mantine/core";
import { Button, Group, Modal, Select, type ModalBaseProps } from "@mantine/core";
import { t } from "@/config/i18n";
import { useForm } from "@mantine/form";
import { IconCancel, IconEdit, IconPlus } from "@tabler/icons-react";
import { type Contract, type ContractInputs } from "@/services/resources/contracts";
import { IconCancel, IconDownload } from "@tabler/icons-react";
import { useGetForms } from "@/services/api";
import { useMemo } from "react";
export type ContractModalProps = ModalBaseProps & {
currentContract?: Contract;
handleSubmit: (contract: ContractInputs, id?: number) => void;
handleSubmit: (id: number) => void;
};
export function ContractModal({
opened,
onClose,
currentContract,
handleSubmit,
}: ContractModalProps) {
const form = useForm<ContractInputs>({
// initialValues: {
// firstname: currentContract?.firstname ?? "",
// lastname: currentContract?.lastname ?? "",
// email: currentContract?.email ?? "",
// },
// validate: {
// firstname: (value) =>
// !value ? `${t("name", { capfirst: true })} ${t("is required")}` : null,
// email: (value) =>
// !value ? `${t("email", { capfirst: true })} ${t("is required")}` : null,
// },
export type ContractDownloadInputs = {
form_id: number;
};
export function ContractModal({ opened, onClose, handleSubmit }: ContractModalProps) {
const { data: allForms } = useGetForms();
const form = useForm({
initialValues: {
form_id: null,
},
validate: {
form_id: (value) =>
!value ? `${t("a form", { capfirst: true })} ${t("is required")}` : null,
},
});
const formSelect = useMemo(() => {
return allForms?.map((form) => ({
value: String(form.id),
label: `${form.season} ${form.name}`,
}));
}, [allForms]);
return (
<Modal opened={opened} onClose={onClose} title={t("create contract", { capfirst: true })}>
<Title order={4}>{t("informations", { capfirst: true })}</Title>
<TextInput
label={t("contract name", { capfirst: true })}
placeholder={t("contract name", { capfirst: true })}
radius="sm"
<Modal
opened={opened}
onClose={onClose}
title={t("download contracts", { capfirst: true })}
>
<Select
label={t("form", { capfirst: true })}
placeholder={t("select a form", { capfirst: true })}
description={t(
"by selecting a form here you can download all contracts of your form",
{ capfirst: true },
)}
nothingFoundMessage={t("nothing found", { capfirst: true })}
withAsterisk
{...form.getInputProps("name")}
/>
<TextInput
label={t("contract email", { capfirst: true })}
placeholder={t("contract email", { capfirst: true })}
radius="sm"
withAsterisk
{...form.getInputProps("email")}
clearable
allowDeselect
searchable
data={formSelect || []}
{...form.getInputProps("form_id")}
/>
<Group mt="sm" justify="space-between">
<Button
@@ -61,22 +68,16 @@ export function ContractModal({
</Button>
<Button
variant="filled"
aria-label={
currentContract
? t("edit contract", { capfirst: true })
: t("create contract", { capfirst: true })
}
leftSection={currentContract ? <IconEdit /> : <IconPlus />}
aria-label={t("download contracts")}
leftSection={<IconDownload />}
onClick={() => {
form.validate();
if (form.isValid()) {
handleSubmit(form.getValues(), currentContract?.id);
handleSubmit(Number(form.values.form_id));
}
}}
>
{currentContract
? t("edit contract", { capfirst: true })
: t("create contract", { capfirst: true })}
{t("download contracts", { capfirst: true })}
</Button>
</Group>
</Modal>

View File

@@ -10,24 +10,17 @@ export type ContractRowProps = {
};
export default function ContractRow({ contract }: ContractRowProps) {
// const [searchParams] = useSearchParams();
const deleteMutation = useDeleteContract();
// const navigate = useNavigate();
const {refetch, isFetching} = useGetContractFile(contract.id)
const handleDownload = useCallback(async () => {
const { data } = await refetch();
if (!data)
return;
const getContractMutation = useGetContractFile();
const url = URL.createObjectURL(data.blob);
const link = document.createElement("a");
link.href = url;
link.download = data.filename;
link.click();
URL.revokeObjectURL(url);
}, [useGetContractFile])
const handleDownload = useCallback(async () => {
getContractMutation.mutateAsync(contract.id);
}, [useGetContractFile, contract, contract.id]);
return (
<Table.Tr key={contract.id}>
<Table.Td>
{contract.form.name} {contract.form.season}
</Table.Td>
<Table.Td>
{contract.firstname} {contract.lastname}
</Table.Td>
@@ -36,32 +29,16 @@ export default function ContractRow({ contract }: ContractRowProps) {
{contract.cheque_quantity > 0 && contract.cheque_quantity} {contract.payment_method}
</Table.Td>
<Table.Td>
{/* <Tooltip label={t("edit contract", { capfirst: true })}>
<Tooltip label={t("download contract", { capfirst: true })}>
<ActionIcon
size="sm"
mr="5"
onClick={(e) => {
e.stopPropagation();
navigate(
`/dashboard/contracts/${contract.id}/edit${searchParams ? `?${searchParams.toString()}` : ""}`,
);
handleDownload();
}}
>
<IconEdit />
</ActionIcon>
</Tooltip> */}
<Tooltip
label={t("download contract")}
>
<ActionIcon
size="sm"
mr="5"
onClick={(e) => {
e.stopPropagation();
handleDownload()
}}
>
<IconDownload/>
<IconDownload />
</ActionIcon>
</Tooltip>
<Tooltip label={t("remove contract", { capfirst: true })}>