images
This commit is contained in:
@@ -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({
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user