diff --git a/client/src/Components/v2/design-elements/ConfirmDialog.tsx b/client/src/Components/v2/design-elements/ConfirmDialog.tsx new file mode 100644 index 000000000..1fe4d7b89 --- /dev/null +++ b/client/src/Components/v2/design-elements/ConfirmDialog.tsx @@ -0,0 +1,105 @@ +import { useId } from "react"; +import { Modal, Stack, Typography, Box } from "@mui/material"; +import { useTheme } from "@mui/material/styles"; +import { Button } from "@/Components/v2/inputs"; +import { useTranslation } from "react-i18next"; + +interface ConfirmDialogProps { + open: boolean; + onClose: () => void; + title: string; + description?: string; + onConfirm: () => void; + confirmText?: string; + cancelText?: string; + isLoading?: boolean; + confirmColor?: "error" | "primary" | "secondary" | "success" | "warning" | "info"; +} + +export const ConfirmDialog = ({ + open, + onClose, + title, + description, + onConfirm, + confirmText, + cancelText, + isLoading = false, + confirmColor = "error", +}: ConfirmDialogProps) => { + const theme = useTheme(); + const { t } = useTranslation(); + const titleId = useId(); + const descriptionId = useId(); + + return ( + e.stopPropagation()} + > + + + {title} + + {description && ( + + {description} + + )} + + + + + + + ); +}; diff --git a/client/src/Hooks/useProfileForm.ts b/client/src/Hooks/useProfileForm.ts new file mode 100644 index 000000000..e426f904e --- /dev/null +++ b/client/src/Hooks/useProfileForm.ts @@ -0,0 +1,14 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { profileSchema, type ProfileFormData } from "@/Validation/profile"; + +export const useProfileForm = () => { + return { + resolver: zodResolver(profileSchema), + defaults: { + firstName: "", + lastName: "", + profileImage: null, + deleteProfileImage: false, + } as ProfileFormData, + }; +}; diff --git a/client/src/Validation/profile.ts b/client/src/Validation/profile.ts new file mode 100644 index 000000000..56301c31f --- /dev/null +++ b/client/src/Validation/profile.ts @@ -0,0 +1,20 @@ +import { z } from "zod"; + +const NAME_PATTERN = /^[A-Za-z'-]+$/; + +export const profileSchema = z.object({ + firstName: z + .string() + .min(1, "First name is required") + .max(50, "First name must be 50 characters or less") + .regex(NAME_PATTERN, "First name can only contain letters, hyphens, and apostrophes"), + lastName: z + .string() + .min(1, "Last name is required") + .max(50, "Last name must be 50 characters or less") + .regex(NAME_PATTERN, "Last name can only contain letters, hyphens, and apostrophes"), + profileImage: z.instanceof(File).optional().nullable(), + deleteProfileImage: z.boolean().optional(), +}); + +export type ProfileFormData = z.infer;