import type { CompanyProfileInput } from "@mrp/shared"; import { useEffect, useState } from "react"; import { useAuth } from "../../auth/AuthProvider"; import { api } from "../../lib/api"; import { useTheme } from "../../theme/ThemeProvider"; export function CompanySettingsPage() { const { token } = useAuth(); const { applyBrandProfile } = useTheme(); const [form, setForm] = useState(null); const [companyId, setCompanyId] = useState(null); const [logoUrl, setLogoUrl] = useState(null); const [status, setStatus] = useState("Loading company profile..."); async function loadLogoPreview(nextToken: string, logoFileId: string | null) { if (!logoFileId) { setLogoUrl((current) => { if (current?.startsWith("blob:")) { window.URL.revokeObjectURL(current); } return null; }); return; } const blob = await api.getFileContentBlob(nextToken, logoFileId); const objectUrl = window.URL.createObjectURL(blob); setLogoUrl((current) => { if (current?.startsWith("blob:")) { window.URL.revokeObjectURL(current); } return objectUrl; }); } useEffect(() => { if (!token) { return; } let active = true; api.getCompanyProfile(token).then((profile) => { setCompanyId(profile.id); setForm({ companyName: profile.companyName, legalName: profile.legalName, email: profile.email, phone: profile.phone, website: profile.website, taxId: profile.taxId, addressLine1: profile.addressLine1, addressLine2: profile.addressLine2, city: profile.city, state: profile.state, postalCode: profile.postalCode, country: profile.country, theme: profile.theme, }); applyBrandProfile(profile); setStatus("Company profile loaded."); if (profile.theme.logoFileId) { loadLogoPreview(token, profile.theme.logoFileId) .then(() => { if (!active) { return; } }) .catch(() => { if (active) { setLogoUrl(null); } }); } else { setLogoUrl(null); } }); return () => { active = false; }; }, [applyBrandProfile, token]); useEffect(() => { return () => { if (logoUrl?.startsWith("blob:")) { window.URL.revokeObjectURL(logoUrl); } }; }, [logoUrl]); if (!form || !token) { return
{status}
; } async function handleSave(event: React.FormEvent) { event.preventDefault(); if (!token || !form) { return; } const profile = await api.updateCompanyProfile(token, form); applyBrandProfile(profile); await loadLogoPreview(token, profile.theme.logoFileId); setStatus("Company settings saved."); } async function handleLogoUpload(event: React.ChangeEvent) { const file = event.target.files?.[0]; if (!file || !companyId || !token) { return; } const attachment = await api.uploadFile(token, file, "company-profile", companyId); setForm((current) => current ? { ...current, theme: { ...current.theme, logoFileId: attachment.id, }, } : current ); await loadLogoPreview(token, attachment.id); setStatus("Logo uploaded. Save to persist it on the profile."); } async function handlePdfPreview() { if (!token) { return; } const blob = await api.getCompanyProfilePreviewPdf(token); const objectUrl = window.URL.createObjectURL(blob); window.open(objectUrl, "_blank", "noopener,noreferrer"); window.setTimeout(() => window.URL.revokeObjectURL(objectUrl), 60_000); } function updateField(key: Key, value: CompanyProfileInput[Key]) { setForm((current) => (current ? { ...current, [key]: value } : current)); } return (

Company Profile

Branding and legal identity

Every internal document and PDF template will inherit its company identity from this profile.

{logoUrl ? Company logo :
LOGO
}
{[ ["companyName", "Company name"], ["legalName", "Legal name"], ["email", "Email"], ["phone", "Phone"], ["website", "Website"], ["taxId", "Tax ID"], ["addressLine1", "Address line 1"], ["addressLine2", "Address line 2"], ["city", "City"], ["state", "State"], ["postalCode", "Postal code"], ["country", "Country"], ].map(([key, label]) => ( ))}

Theme

{status}
); }