This commit is contained in:
2026-03-14 16:17:04 -05:00
parent 9c8298c5e3
commit a8d0533f4a
2 changed files with 66 additions and 3 deletions

View File

@@ -93,6 +93,19 @@ export const api = {
} }
return json.data; return json.data;
}, },
async getFileContentBlob(token: string, fileId: string) {
const response = await fetch(`/api/v1/files/${fileId}/content`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
throw new ApiError("Unable to load file content.", "FILE_CONTENT_FAILED");
}
return response.blob();
},
getCustomers(token: string, filters?: { q?: string; status?: CrmRecordStatus; state?: string }) { getCustomers(token: string, filters?: { q?: string; status?: CrmRecordStatus; state?: string }) {
return request<CrmRecordSummaryDto[]>( return request<CrmRecordSummaryDto[]>(
`/api/v1/crm/customers${buildQueryString({ `/api/v1/crm/customers${buildQueryString({

View File

@@ -13,14 +13,36 @@ export function CompanySettingsPage() {
const [logoUrl, setLogoUrl] = useState<string | null>(null); const [logoUrl, setLogoUrl] = useState<string | null>(null);
const [status, setStatus] = useState<string>("Loading company profile..."); const [status, setStatus] = useState<string>("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(() => { useEffect(() => {
if (!token) { if (!token) {
return; return;
} }
let active = true;
api.getCompanyProfile(token).then((profile) => { api.getCompanyProfile(token).then((profile) => {
setCompanyId(profile.id); setCompanyId(profile.id);
setLogoUrl(profile.logoUrl);
setForm({ setForm({
companyName: profile.companyName, companyName: profile.companyName,
legalName: profile.legalName, legalName: profile.legalName,
@@ -38,9 +60,37 @@ export function CompanySettingsPage() {
}); });
applyBrandProfile(profile); applyBrandProfile(profile);
setStatus("Company profile loaded."); 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]); }, [applyBrandProfile, token]);
useEffect(() => {
return () => {
if (logoUrl?.startsWith("blob:")) {
window.URL.revokeObjectURL(logoUrl);
}
};
}, [logoUrl]);
if (!form || !token) { if (!form || !token) {
return <div className="rounded-[28px] border border-line/70 bg-surface/90 p-8 text-sm text-muted shadow-panel">{status}</div>; return <div className="rounded-[28px] border border-line/70 bg-surface/90 p-8 text-sm text-muted shadow-panel">{status}</div>;
} }
@@ -52,7 +102,7 @@ export function CompanySettingsPage() {
} }
const profile = await api.updateCompanyProfile(token, form); const profile = await api.updateCompanyProfile(token, form);
applyBrandProfile(profile); applyBrandProfile(profile);
setLogoUrl(profile.logoUrl); await loadLogoPreview(token, profile.theme.logoFileId);
setStatus("Company settings saved."); setStatus("Company settings saved.");
} }
@@ -74,7 +124,7 @@ export function CompanySettingsPage() {
} }
: current : current
); );
setLogoUrl(`/api/v1/files/${attachment.id}/content`); await loadLogoPreview(token, attachment.id);
setStatus("Logo uploaded. Save to persist it on the profile."); setStatus("Logo uploaded. Save to persist it on the profile.");
} }