import { Info, Lock, Mail, Plus, User, UsersRound } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { createOrgMember, createOrgSection, listOrgSections } from "../api";
const EMAIL_LOCAL_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62}[A-Za-z0-9])?$/;
function RequiredLabel({ children }) {
return (
<>
{children}
*
>
);
}
function SetupField({ label, error, children, hint }) {
return (
{label && {label}}
{children}
{hint && {hint}}
{error && {error}}
);
}
function InputWrap({ icon: Icon, children }) {
return (
{children}
);
}
function validateForm(form, companyDomain) {
const errors = {};
if (!form.first_name.trim()) errors.first_name = "Please enter a first name.";
if (!form.last_name.trim()) errors.last_name = "Please enter a last name.";
const local = form.email_local.trim();
if (!local) {
errors.email_local = "Please enter a work email address.";
} else if (!EMAIL_LOCAL_PATTERN.test(local)) {
errors.email_local = "Enter a valid email address before @.";
}
if (!form.send_invitation && !form.password.trim()) {
errors.password = "Please set an initial password.";
}
if (form.send_invitation) {
const invite = form.invitation_email.trim();
if (!invite) {
errors.invitation_email = "Please enter a personal email for the invitation.";
} else if (invite.endsWith(`@${companyDomain}`)) {
errors.invitation_email = "Use a personal email, not your company domain.";
}
}
return errors;
}
export default function AddEmployeeForm({
companyDomain,
platformDomain = "gentic.email",
variant = "drawer",
submitLabel = "Create user",
onCreated,
onCancel,
}) {
const token = sessionStorage.getItem("agmail_access_token");
const [sections, setSections] = useState([]);
const [sectionsLoading, setSectionsLoading] = useState(true);
const [showNewSection, setShowNewSection] = useState(false);
const [newSectionName, setNewSectionName] = useState("");
const [sectionError, setSectionError] = useState("");
const [creatingSection, setCreatingSection] = useState(false);
const [form, setForm] = useState({
first_name: "",
last_name: "",
email_local: "",
invitation_email: "",
org_role: "user",
section_id: null,
send_invitation: true,
force_password_change: true,
password: "",
});
const [fieldErrors, setFieldErrors] = useState({});
const [submitAttempted, setSubmitAttempted] = useState(false);
const [status, setStatus] = useState({ loading: false, error: "" });
useEffect(() => {
let cancelled = false;
setSectionsLoading(true);
listOrgSections(token)
.then((items) => {
if (!cancelled) {
setSections(items);
}
})
.catch(() => {
if (!cancelled) {
setSections([]);
}
})
.finally(() => {
if (!cancelled) {
setSectionsLoading(false);
}
});
return () => {
cancelled = true;
};
}, [token]);
const formValid = useMemo(
() => Object.keys(validateForm(form, companyDomain)).length === 0,
[form, companyDomain],
);
function updateField(field, value) {
setForm((current) => {
const next = { ...current, [field]: value };
if (submitAttempted || fieldErrors[field]) {
const nextErrors = validateForm(next, companyDomain);
setFieldErrors((errors) => ({ ...errors, [field]: nextErrors[field] }));
}
return next;
});
}
function selectSection(sectionId) {
setForm((current) => ({
...current,
section_id: current.section_id === sectionId ? null : sectionId,
}));
}
async function handleCreateSection() {
const name = newSectionName.trim();
if (!name) {
setSectionError("Enter a section name.");
return;
}
setCreatingSection(true);
setSectionError("");
try {
const section = await createOrgSection({ name }, token);
setSections((current) => [...current, section].sort((a, b) => a.name.localeCompare(b.name)));
setForm((current) => ({ ...current, section_id: section.id }));
setNewSectionName("");
setShowNewSection(false);
} catch (error) {
setSectionError(error.message);
} finally {
setCreatingSection(false);
}
}
async function handleSubmit(event) {
event.preventDefault();
setSubmitAttempted(true);
const errors = validateForm(form, companyDomain);
setFieldErrors(errors);
if (Object.keys(errors).length > 0) {
return;
}
setStatus({ loading: true, error: "" });
const email = `${form.email_local.trim().toLowerCase()}@${companyDomain}`;
try {
const member = await createOrgMember(
{
first_name: form.first_name.trim(),
last_name: form.last_name.trim(),
email,
invitation_email: form.send_invitation
? form.invitation_email.trim().toLowerCase()
: undefined,
section_id: form.section_id || undefined,
org_role: form.org_role,
send_invitation: form.send_invitation,
force_password_change: form.send_invitation ? false : form.force_password_change,
password: form.send_invitation ? undefined : form.password,
},
token,
);
setForm({
first_name: "",
last_name: "",
email_local: "",
invitation_email: "",
org_role: "user",
section_id: null,
send_invitation: true,
force_password_change: true,
password: "",
});
setFieldErrors({});
setSubmitAttempted(false);
setStatus({ loading: false, error: "" });
onCreated?.(member);
} catch (error) {
setStatus({ loading: false, error: error.message });
}
}
const formClass = variant === "inline"
? "org-setup-form employee-add-form employee-add-form-inline"
: "people-drawer-form employee-add-form";
return (
);
}