gitscope
← marzneshin / v0.3.0 / dashboard/src/features/users/dialogs/mutation/index.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/users/dialogs/mutation/index.tsx · TypeScript
Blame Raw
  1import type { FC } from "react";
  2import { useCallback } from "react";
  3import {
  4    DialogTitle,
  5    DialogContent,
  6    Dialog,
  7    DialogHeader,
  8    Form,
  9    Button,
 10    ScrollArea,
 11    VStack,
 12} from "@marzneshin/components";
 13import { useTranslation } from "react-i18next";
 14import type { UserMutationType } from "@marzneshin/features/users";
 15import {
 16    DATA_LIMIT_METRIC,
 17    useUsersCreationMutation,
 18    useUsersUpdateMutation,
 19} from "@marzneshin/features/users";
 20
 21import { UserSchema } from "./schema";
 22import { UsernameField, NoteField, ServicesField } from "./fields";
 23import { useMutationDialog } from "@marzneshin/hooks";
 24import { DataLimitFields, ExpirationMethodFields } from "./sections";
 25
 26interface UsersMutationDialogProps {
 27    entity: UserMutationType | null;
 28    open: boolean;
 29    onOpenChange: (state: boolean) => void;
 30}
 31
 32export const UsersMutationDialog: FC<UsersMutationDialogProps> = ({
 33    entity,
 34    open,
 35    onOpenChange,
 36}) => {
 37    const { t } = useTranslation();
 38    const getDefaultValues = useCallback(
 39        (): UserMutationType => ({
 40            services: [],
 41            data_limit: undefined,
 42            expire: null,
 43            username: "",
 44            data_limit_reset_strategy: "no_reset",
 45            status: "active",
 46            note: "",
 47            on_hold_expire_duration: 0,
 48            on_hold_timeout: undefined,
 49        }),
 50        [],
 51    );
 52
 53    const { form, handleSubmit } = useMutationDialog({
 54        entity,
 55        onOpenChange,
 56        createMutation: useUsersCreationMutation(),
 57        updateMutation: useUsersUpdateMutation(),
 58        schema: UserSchema,
 59        getDefaultValue: getDefaultValues,
 60        loadFormtter: (d) => ({
 61            ...d,
 62            data_limit: (d.data_limit ? d.data_limit : 0) / DATA_LIMIT_METRIC,
 63        }),
 64    });
 65
 66    return (
 67        <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
 68            <DialogContent className="min-w-full h-full md:h-auto md:min-w-[42rem]">
 69                <ScrollArea className="flex flex-col justify-between h-full p-0">
 70                    <DialogHeader>
 71                        <DialogTitle className="text-primary">
 72                            {entity
 73                                ? t("page.users.dialogs.edition.title")
 74                                : t("page.users.dialogs.creation.title")}
 75                        </DialogTitle>
 76                    </DialogHeader>
 77                    <Form {...form}>
 78                        <form onSubmit={handleSubmit} className="">
 79                            <div className="flex-col grid-cols-2 gap-2 sm:flex md:grid h-full">
 80                                <div>
 81                                    <UsernameField disabled={!!entity?.username} />
 82                                    <DataLimitFields />
 83                                    <ExpirationMethodFields entity={entity} />
 84                                    <NoteField />
 85                                </div>
 86                                <VStack>
 87                                    <ServicesField />
 88                                </VStack>
 89                            </div>
 90                            <Button
 91                                className="mt-3 w-full font-semibold"
 92                                type="submit"
 93                                disabled={form.formState.isSubmitting}
 94                            >
 95                                {t("submit")}
 96                            </Button>
 97                        </form>
 98                    </Form>
 99                </ScrollArea>
100            </DialogContent>
101        </Dialog>
102    );
103};