fix(report): SVG logo unsupported, date validation, blob URL cleanup, remove as-any cast
Deploy HiHala Dashboard / deploy (push) Successful in 11s

This commit is contained in:
fahed
2026-04-28 14:47:39 +03:00
parent b6bd3bcff5
commit 594321738a
3 changed files with 13 additions and 7 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ export default function ReportForm({ config: cfg, onChange, allMuseums, allChann
<button type="button" className="rf-remove-btn" onClick={() => onChange({ clientLogoBase64: null })}></button> <button type="button" className="rf-remove-btn" onClick={() => onChange({ clientLogoBase64: null })}></button>
</> </>
)} )}
<input ref={logoInputRef} type="file" accept="image/png,image/jpeg,image/svg+xml" <input ref={logoInputRef} type="file" accept="image/png,image/jpeg"
style={{ display: 'none' }} onChange={handleLogoUpload} /> style={{ display: 'none' }} onChange={handleLogoUpload} />
</div> </div>
</Field> </Field>
+7
View File
@@ -22,6 +22,10 @@ export default function ReportPage({ data }: Props) {
const patch = useCallback((p: Partial<ReportConfig>) => setConfig(c => ({ ...c, ...p })), []); const patch = useCallback((p: Partial<ReportConfig>) => setConfig(c => ({ ...c, ...p })), []);
const handleGenerate = async () => { const handleGenerate = async () => {
if (config.startDate > config.endDate) {
alert('End date must be after start date.');
return;
}
setGenerating(true); setGenerating(true);
try { try {
const reportData = computeReportData(data, config); const reportData = computeReportData(data, config);
@@ -31,10 +35,13 @@ export default function ReportPage({ data }: Props) {
const slug = (config.clientName || 'report').toLowerCase().replace(/\s+/g, '-'); const slug = (config.clientName || 'report').toLowerCase().replace(/\s+/g, '-');
a.href = url; a.href = url;
a.download = `hihala-${slug}-${config.startDate.slice(0, 7)}.pdf`; a.download = `hihala-${slug}-${config.startDate.slice(0, 7)}.pdf`;
try {
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
} finally {
document.body.removeChild(a); document.body.removeChild(a);
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}
} catch (err) { } catch (err) {
console.error('PDF generation failed:', err); console.error('PDF generation failed:', err);
alert('Failed to generate PDF. Please try again.'); alert('Failed to generate PDF. Please try again.');
+1 -2
View File
@@ -106,8 +106,7 @@ function buildTrend(rows: MuseumRecord[], start: string, cfg: ReportConfig): { l
const labels = Array.from({ length: maxK }, (_, i) => `W${i + 1}`); const labels = Array.from({ length: maxK }, (_, i) => `W${i + 1}`);
const values = labels.map((_, i) => { const values = labels.map((_, i) => {
const group = acc[i + 1] || []; const group = acc[i + 1] || [];
const revenueField = cfg.includeVAT ? 'revenue_gross' : 'revenue_net'; return group.reduce((s, r) => s + (cfg.includeVAT ? r.revenue_gross : r.revenue_net) || 0, 0);
return group.reduce((s, r) => s + parseFloat(String((r as any)[revenueField] || 0)), 0);
}); });
return { labels, values }; return { labels, values };
} }