import React, { useEffect, useState } from "react"; import { Autocomplete, Box, Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, TextField, } from "@mui/material"; import { useSnackbar } from "notistack"; import { useApi } from "../../../contexts/ApiContext"; import { useI18n } from "../../../contexts/I18nContext"; import { PageProps } from "../../../types"; import { GroupOption, StaffOptions } from "../types/staff"; export interface InviteUserModalProps { open: boolean; setOpen: (open: boolean) => void; refresh: PageProps["refresh"]; } export const InviteUserModal: React.FC = ({ open, setOpen, refresh }) => { const { t } = useI18n(); const api = useApi(); const { enqueueSnackbar } = useSnackbar(); const [email, setEmail] = useState(""); const [selectedGroups, setSelectedGroups] = useState([]); const [availableGroups, setAvailableGroups] = useState([]); const [loading, setLoading] = useState(false); const [emailError, setEmailError] = useState(""); useEffect(() => { const fetchOptions = async () => { const response = await api.operations["user.staff:options"].call({}); if (response.ok) { const options: StaffOptions = await response.json(); setAvailableGroups(options.groups); } }; if (open) { fetchOptions(); } }, [api, open]); const handleClose = () => { setEmail(""); setSelectedGroups([]); setEmailError(""); setOpen(false); }; const validateEmail = (email: string): boolean => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }; const handleSubmit = async () => { // Validate email if (!email) { setEmailError(t("Email is required")); return; } if (!validateEmail(email)) { setEmailError(t("Please enter a valid email address")); return; } if (selectedGroups.length === 0) { enqueueSnackbar(t("Please select at least one group"), { variant: "error" }); return; } setLoading(true); setEmailError(""); try { const response = await api.operations["user.staff:invite"].call({ body: { email, groups: selectedGroups.map((g) => g.id), }, }); if (response.ok) { const data = await response.json(); enqueueSnackbar(data.message || t("Invite sent successfully"), { variant: "success" }); handleClose(); refresh(); } else { const errorData = await response.json(); if (errorData.detail && Array.isArray(errorData.detail)) { const emailErrors = errorData.detail.filter((err: { loc?: string[]; msg?: string }) => err.loc?.includes("email"), ); if (emailErrors.length > 0) { setEmailError(emailErrors[0].msg); } else { enqueueSnackbar(errorData.detail[0]?.msg || t("Failed to send invite"), { variant: "error", }); } } else { enqueueSnackbar(t("Failed to send invite"), { variant: "error" }); } } } catch (error) { console.error("[INVITE_USER]", error); enqueueSnackbar(t("Failed to send invite"), { variant: "error" }); } finally { setLoading(false); } }; return ( {t("Invite Staff User")} { setEmail(e.target.value); setEmailError(""); }} /> option.name} isOptionEqualToValue={(option, value) => option.id === value.id} options={availableGroups} renderInput={(params) => ( )} renderTags={(value, getTagProps) => value.map((option, index) => ( )) } size="small" value={selectedGroups} onChange={(_, newValue) => setSelectedGroups(newValue)} /> ); }; export default InviteUserModal;