import { useEffect, useMemo, useState } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useCompany } from "../context/CompanyContext"; import { useBreadcrumbs } from "../context/BreadcrumbContext"; import { companiesApi } from "../api/companies"; import { accessApi } from "../api/access"; import { queryKeys } from "../lib/queryKeys"; import { Button } from "@/components/ui/button"; import { Settings } from "lucide-react"; export function CompanySettings() { const { selectedCompany, selectedCompanyId } = useCompany(); const { setBreadcrumbs } = useBreadcrumbs(); const queryClient = useQueryClient(); const [joinType, setJoinType] = useState<"human" | "agent" | "both">("both"); const [expiresInHours, setExpiresInHours] = useState(72); const [inviteLink, setInviteLink] = useState(null); const [inviteError, setInviteError] = useState(null); const settingsMutation = useMutation({ mutationFn: (requireApproval: boolean) => companiesApi.update(selectedCompanyId!, { requireBoardApprovalForNewAgents: requireApproval, }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: queryKeys.companies.all }); }, }); const inviteMutation = useMutation({ mutationFn: () => accessApi.createCompanyInvite(selectedCompanyId!, { allowedJoinTypes: joinType, expiresInHours, }), onSuccess: (invite) => { setInviteError(null); const base = window.location.origin.replace(/\/+$/, ""); const absoluteUrl = invite.inviteUrl.startsWith("http") ? invite.inviteUrl : `${base}${invite.inviteUrl}`; setInviteLink(absoluteUrl); queryClient.invalidateQueries({ queryKey: queryKeys.sidebarBadges(selectedCompanyId!) }); }, onError: (err) => { setInviteError(err instanceof Error ? err.message : "Failed to create invite"); }, }); const inviteExpiryHint = useMemo(() => { const expiresAt = new Date(Date.now() + expiresInHours * 60 * 60 * 1000); return expiresAt.toLocaleString(); }, [expiresInHours]); useEffect(() => { setBreadcrumbs([ { label: selectedCompany?.name ?? "Company", href: "/dashboard" }, { label: "Settings" }, ]); }, [setBreadcrumbs, selectedCompany?.name]); if (!selectedCompany) { return (
No company selected. Select a company from the switcher above.
); } return (

Company Settings

Hiring
Require board approval for new hires
New agent hires stay pending until approved by board.
Invites

Invite will expire around {inviteExpiryHint}.

{inviteLink && ( )}
{inviteError &&

{inviteError}

} {inviteLink && (
Share link
{inviteLink}
)}
); }