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;
},
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 }) {
return request<CrmRecordSummaryDto[]>(
`/api/v1/crm/customers${buildQueryString({

View File

@@ -13,14 +13,36 @@ export function CompanySettingsPage() {
const [logoUrl, setLogoUrl] = useState<string | null>(null);
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(() => {
if (!token) {
return;
}
let active = true;
api.getCompanyProfile(token).then((profile) => {
setCompanyId(profile.id);
setLogoUrl(profile.logoUrl);
setForm({
companyName: profile.companyName,
legalName: profile.legalName,
@@ -38,9 +60,37 @@ export function CompanySettingsPage() {
});
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 <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);
applyBrandProfile(profile);
setLogoUrl(profile.logoUrl);
await loadLogoPreview(token, profile.theme.logoFileId);
setStatus("Company settings saved.");
}
@@ -74,7 +124,7 @@ export function CompanySettingsPage() {
}
: current
);
setLogoUrl(`/api/v1/files/${attachment.id}/content`);
await loadLogoPreview(token, attachment.id);
setStatus("Logo uploaded. Save to persist it on the profile.");
}