Print the rough power balance in the kbp design
The print of the rough power balance was plain grey. It now follows the kbp design of the print view: a title block with office logo, stand, project, number, owner, address, work stage, date, editor and office; header row in kbp blue, cost-group rows tinted with a lilac rule, bold subtotals, the total including reserve as a blue band, colored deviations in the comparison, Arial, exact print colors, and a footer with project, stand and "Seite x von y" on every page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
37a70b6b36
commit
e06c7d91e2
3 changed files with 292 additions and 24 deletions
104
src/frontend/estimate-balance/estimate-print-header.tsx
Normal file
104
src/frontend/estimate-balance/estimate-print-header.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { documentLogoUrl, getDocumentBranding } from "../utils/api";
|
||||
import type { EstimateBalanceDto, OfficeProfileDto, ProjectDto } from "../types";
|
||||
import { formatIsoDateGerman } from "./estimate-balance-format";
|
||||
|
||||
interface EstimatePrintHeaderProps {
|
||||
project: ProjectDto;
|
||||
balance: EstimateBalanceDto;
|
||||
}
|
||||
|
||||
function cssString(value: string) {
|
||||
return JSON.stringify(value.replace(/[<>\r\n]/g, " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print-only title block and page footer of the rough power balance in the
|
||||
* kbp corporate design of the print view (Seitenansicht): logo, blue title,
|
||||
* meta data, "Seite x von y". Hidden on screen.
|
||||
*/
|
||||
export function EstimatePrintHeader({ project, balance }: EstimatePrintHeaderProps) {
|
||||
const [office, setOffice] = useState<OfficeProfileDto | null>(null);
|
||||
const [hasLogo, setHasLogo] = useState(false);
|
||||
const [logoVersion, setLogoVersion] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
getDocumentBranding()
|
||||
.then((branding) => {
|
||||
setOffice(branding.office);
|
||||
setHasLogo(Boolean(branding.logo));
|
||||
setLogoVersion(branding.logo ? branding.logo.updatedAtIso : "");
|
||||
})
|
||||
.catch(() => {
|
||||
setOffice(null);
|
||||
setHasLogo(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const stand = [balance.name, balance.workStage].filter(Boolean).join(" · ");
|
||||
const date = balance.dateIso ? formatIsoDateGerman(balance.dateIso) : null;
|
||||
const footer = `
|
||||
@page estimate-balance {
|
||||
size: A4 landscape;
|
||||
margin: 10mm 10mm 13mm;
|
||||
@bottom-left { content: ${cssString(`${project.name} · Grobe Leistungsbilanz`)}; font: 7.5pt Arial, sans-serif; color: #6b7280; }
|
||||
@bottom-center { content: ${cssString(`Stand ${stand}${date ? ` · ${date}` : ""}`)}; font: 7.5pt Arial, sans-serif; color: #6b7280; }
|
||||
@bottom-right { content: "Seite " counter(page) " von " counter(pages); font: 7.5pt Arial, sans-serif; color: #6b7280; }
|
||||
}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<style>{footer}</style>
|
||||
<header className="estimate-print-titleblock" aria-hidden="true">
|
||||
<div className="estimate-print-logo">
|
||||
{hasLogo ? (
|
||||
<img alt="" src={`${documentLogoUrl}?v=${encodeURIComponent(logoVersion)}`} />
|
||||
) : (
|
||||
<span>{office?.officeName ?? ""}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="estimate-print-title">
|
||||
<div className="estimate-print-kicker">Grobe Leistungsbilanz · KG 400</div>
|
||||
<div className="estimate-print-heading">
|
||||
<span className="estimate-print-stand">{balance.name}</span>
|
||||
<span className="estimate-print-project">{project.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
<dl className="estimate-print-meta">
|
||||
<div>
|
||||
<dt>Projekt-Nr.</dt>
|
||||
<dd>{project.internalProjectNumber ?? "–"}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Bauherr</dt>
|
||||
<dd>{project.buildingOwner ?? "–"}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Anschrift</dt>
|
||||
<dd>{project.siteAddress?.split("\n").join(", ") ?? "–"}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<dl className="estimate-print-meta is-tinted">
|
||||
<div>
|
||||
<dt>Leistungsphase</dt>
|
||||
<dd>{balance.workStage ?? "–"}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Datum</dt>
|
||||
<dd>{date ?? "–"}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Bearbeitung</dt>
|
||||
<dd>{project.projectEditor ?? "–"}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Büro</dt>
|
||||
<dd>{office?.officeName ?? "–"}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</header>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue