Dynamic AGB address, real shipping costs on /versand instead of hardcoded constants

- AGB: name/address/email now come from company-settings via new
  VertragspartnerBlock (mid-document, see LegalPages.ts's contentPart2).
- VersandSections/VersandModal/CartContent/CheckoutContent/versand page:
  shipping cost and free-shipping threshold now come from the real
  ShippingMethods data (already fetched elsewhere for checkout), not the
  hardcoded lib/shipping.ts constants — those had already drifted from
  the real Payload values once. lib/shipping.ts deleted, nothing left to
  export.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-08-02 06:53:12 +00:00
parent 9617478b0d
commit c8f231baa6
9 changed files with 137 additions and 29 deletions
@@ -0,0 +1,59 @@
import { headingId } from "../../components/RichText";
import type { CompanySettings } from "../../lib/payload";
import type { TOCSection } from "../../components/SectionTOC";
// Renders "2. Vertragspartner" straight from company-settings, same
// single-source-of-truth pattern as Impressum's AnbieterAngaben.tsx and
// Datenschutz's VerantwortlicherBlock.tsx — this used to be hand-typed
// name/address/email baked into the AGB richText (seed-agb.ts on the
// Payload side), and had already drifted from the real company-settings
// values once (the richText's placeholder "Björn Wendt"/"Musterstraße
// 12" never got updated when the real address was set). Sits mid-document
// (section 1 "Geltungsbereich" comes before it), which is why AGB's
// content is split into `content` (section 1) + `contentPart2` (sections
// 3 onward) rather than just prepending this block like Datenschutz did —
// see LegalPages.ts's `contentPart2` field comment.
export function vertragspartnerHeadings(): TOCSection[] {
return [{ id: headingId("2. Vertragspartner"), title: "2. Vertragspartner" }];
}
function Heading({ children }: { children: string }) {
return (
<h2
id={headingId(children)}
className="font-semibold text-h-small text-text-primary mt-2 scroll-mt-32 first:mt-0"
style={{ fontFamily: "var(--font-lora)" }}
>
{children}
<span className="block h-[0.125rem] w-8 bg-brand mt-2" aria-hidden />
</h2>
);
}
function P({ children }: { children: React.ReactNode }) {
return <p className="text-body text-text-body">{children}</p>;
}
export function VertragspartnerBlock({ seller }: { seller: CompanySettings }) {
return (
<div className="flex flex-col gap-4 w-full">
<Heading>2. Vertragspartner</Heading>
<P>Der Kaufvertrag kommt zustande mit:</P>
<div className="flex flex-col gap-1">
<P>
<strong>einfach produktiv. {seller.sellerName}</strong>
</P>
<P>
<strong>
{seller.sellerStreet}, {seller.sellerZip} {seller.sellerCity}
</strong>
</P>
<P>
<strong>
E-Mail: <a href={`mailto:${seller.sellerEmail}`} className="hover:underline">{seller.sellerEmail}</a>
</strong>
</P>
</div>
</div>
);
}