import { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faEye, faEyeSlash, faRotate } from '@fortawesome/pro-duotone-svg-icons'; import { Input } from '@/components/base/input/input'; import { Select } from '@/components/base/select/select'; // In-place employee creation form used by the Team wizard step and // the /settings/team slideout. Replaces the multi-email InviteMemberForm // — this project never uses email invitations, all employees are // created directly with a temp password that the admin hands out. // // Two modes: // // - 'create': all fields editable. The temp password is auto-generated // on form mount (parent does this) and revealed via an eye icon. A // refresh icon next to the eye lets the admin re-roll the password // before saving. // // - 'edit': email is read-only (it's the login id, can't change), // password field is hidden entirely (no reset-password from the // wizard). Only firstName/lastName/role can change. // // SIP seat assignment is intentionally NOT in this form — it lives // exclusively in the Telephony wizard step, so there's a single source // of truth for "who is on which seat" and admins don't have to remember // two places to manage the same thing. export type RoleOption = { id: string; label: string; supportingText?: string; }; export type EmployeeCreateFormValues = { firstName: string; lastName: string; email: string; password: string; roleId: string; }; export const emptyEmployeeCreateFormValues: EmployeeCreateFormValues = { firstName: '', lastName: '', email: '', password: '', roleId: '', }; // Random temp password generator. Skips visually-ambiguous chars // (0/O/1/l/I) so admins can read the password back over a phone call // without typo risk. 11 alphanumerics + 1 symbol = 12 chars total. export const generateTempPassword = (): string => { const chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'; const symbols = '!@#$'; let pwd = ''; for (let i = 0; i < 11; i++) { pwd += chars[Math.floor(Math.random() * chars.length)]; } pwd += symbols[Math.floor(Math.random() * symbols.length)]; return pwd; }; type EmployeeCreateFormProps = { value: EmployeeCreateFormValues; onChange: (value: EmployeeCreateFormValues) => void; roles: RoleOption[]; // 'create' = full form, 'edit' = name + role only. mode?: 'create' | 'edit'; }; // Eye / eye-slash button rendered inside the password field's // trailing slot. Stays internal to this form since password reveal // is the only place we need it right now. const EyeButton = ({ visible, onClick, title }: { visible: boolean; onClick: () => void; title: string }) => ( ); const RegenerateButton = ({ onClick }: { onClick: () => void }) => ( ); // Kept simple — name + contact + creds + role. No avatar, no phone, // no title. The goal is to get employees onto the system fast; they // can fill in the rest from their own profile page later. export const EmployeeCreateForm = ({ value, onChange, roles, mode = 'create', }: EmployeeCreateFormProps) => { const [showPassword, setShowPassword] = useState(false); const patch = (partial: Partial) => onChange({ ...value, ...partial }); const isEdit = mode === 'edit'; return (
patch({ firstName: v })} isRequired /> patch({ lastName: v })} />
patch({ email: v })} isRequired={!isEdit} isReadOnly={isEdit} isDisabled={isEdit} hint={ isEdit ? 'Email is the login id and cannot be changed.' : 'This is the login id for the employee. Cannot be changed later.' } /> {!isEdit && (
patch({ password: e.target.value })} placeholder="Auto-generated" className="flex-1 bg-transparent py-2 font-mono text-sm text-primary placeholder:text-placeholder outline-none" /> setShowPassword((v) => !v)} title={showPassword ? 'Hide password' : 'Show password'} /> { patch({ password: generateTempPassword() }); setShowPassword(true); }} />

Auto-generated. Click the refresh icon to roll a new one. Share with the employee directly — they should change it after first login.

)}
SIP seats are managed in the Telephony step — create the employee here first, then assign them a seat there.
); };