Impressum mit den Anbieterdaten der GEFIM UG

Daten aus gefim.de/impressum als zentrale Konstante (src/lib/marketing/imprint.ts), Seite
/impressum öffentlich und in der Fußzeile verlinkt. Der dort abgeschnittene Satz zur
Verbraucherstreitbeilegung ist mit der Standardformulierung vervollständigt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 09:02:30 +02:00
co-authored by Claude Opus 5
parent 4815a957b0
commit f665999d81
6 changed files with 125 additions and 2 deletions
+17
View File
@@ -398,5 +398,22 @@
},
"shotFrame": {
"label": "Bildschirmfoto aus Craftvia"
},
"imprint": {
"title": "Impressum",
"intro": "Angaben gemäß § 5 Digitale-Dienste-Gesetz (DDG).",
"provider": "Anbieter",
"represented": "Vertreten durch",
"contact": "Kontakt",
"phone": "Telefon",
"email": "E-Mail",
"register": "Registereintrag",
"registerCourt": "Registergericht",
"registerNumber": "Handelsregister",
"vat": "Umsatzsteuer-ID",
"vatText": "Umsatzsteuer-Identifikationsnummer gemäß § 27 a Umsatzsteuergesetz:",
"editorial": "Redaktionell verantwortlich",
"dispute": "Verbraucherstreitbeilegung / Universalschlichtungsstelle",
"disputeText": "Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen."
}
}
+17
View File
@@ -398,5 +398,22 @@
},
"shotFrame": {
"label": "Screenshot from Craftvia"
},
"imprint": {
"title": "Imprint",
"intro": "Information pursuant to § 5 of the German Digital Services Act (DDG).",
"provider": "Provider",
"represented": "Represented by",
"contact": "Contact",
"phone": "Phone",
"email": "E-mail",
"register": "Commercial register",
"registerCourt": "Register court",
"registerNumber": "Register number",
"vat": "VAT ID",
"vatText": "VAT identification number pursuant to § 27 a of the German VAT Act:",
"editorial": "Editorially responsible",
"dispute": "Consumer dispute resolution",
"disputeText": "We are neither willing nor obliged to take part in dispute resolution proceedings before a consumer arbitration board."
}
}
+70
View File
@@ -0,0 +1,70 @@
import type { Metadata } from "next";
import { getTranslations } from "next-intl/server";
import { IMPRINT } from "@/lib/marketing/imprint";
export async function generateMetadata(): Promise<Metadata> {
const t = await getTranslations("marketing.imprint");
return { title: t("title"), robots: { index: true, follow: true } };
}
/** Impressum der Produktseite — Daten aus src/lib/marketing/imprint.ts. */
export default async function ImprintPage() {
const t = await getTranslations("marketing.imprint");
const block = "mt-8 font-heading text-[17px] font-semibold";
return (
<article className="mx-auto max-w-3xl px-4 py-12 sm:px-6">
<h1 className="font-heading text-[30px] font-bold text-[var(--ui-primary)]">{t("title")}</h1>
<p className="mt-2 text-[14px] text-muted-foreground">{t("intro")}</p>
<h2 className={block}>{t("provider")}</h2>
<address className="mt-2 text-[15px] leading-relaxed not-italic">
{IMPRINT.company}
<br />
{IMPRINT.street}
<br />
{IMPRINT.city}
<br />
{IMPRINT.country}
</address>
<h2 className={block}>{t("represented")}</h2>
<p className="mt-2 text-[15px]">{IMPRINT.representatives.join(", ")}</p>
<h2 className={block}>{t("contact")}</h2>
<dl className="mt-2 grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-[15px]">
<dt className="text-muted-foreground">{t("phone")}</dt>
<dd>
<a href={IMPRINT.phoneHref} className="underline-offset-2 hover:underline">
{IMPRINT.phone}
</a>
</dd>
<dt className="text-muted-foreground">{t("email")}</dt>
<dd>
<a href={`mailto:${IMPRINT.email}`} className="underline-offset-2 hover:underline">
{IMPRINT.email}
</a>
</dd>
</dl>
<h2 className={block}>{t("register")}</h2>
<dl className="mt-2 grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-[15px]">
<dt className="text-muted-foreground">{t("registerCourt")}</dt>
<dd>{IMPRINT.registerCourt}</dd>
<dt className="text-muted-foreground">{t("registerNumber")}</dt>
<dd>{IMPRINT.registerNumber}</dd>
</dl>
<h2 className={block}>{t("vat")}</h2>
<p className="mt-2 text-[15px]">
{t("vatText")} {IMPRINT.vatId}
</p>
<h2 className={block}>{t("editorial")}</h2>
<p className="mt-2 text-[15px]">{IMPRINT.editorial}</p>
<h2 className={block}>{t("dispute")}</h2>
<p className="mt-2 text-[15px] leading-relaxed">{t("disputeText")}</p>
</article>
);
}
+1 -1
View File
@@ -70,7 +70,7 @@ export async function MarketingShell({ children }: { children: React.ReactNode }
<nav aria-labelledby="footer-legal">
<h2 id="footer-legal" className="text-[13px] font-semibold tracking-wide uppercase">{t("footer.company")}</h2>
<ul className="mt-2 grid">
<li><Link href="/login" className="inline-flex min-h-11 items-center text-[14px] text-muted-foreground hover:text-foreground">{t("footer.login")}</Link></li>
<li><Link href="/impressum" className="inline-flex min-h-11 items-center text-[14px] text-muted-foreground hover:text-foreground">{t("footer.imprint")}</Link></li>
<li><Link href="/testen/nutzungsbedingungen" className="inline-flex min-h-11 items-center text-[14px] text-muted-foreground hover:text-foreground">{t("footer.terms")}</Link></li>
<li><Link href="/testen/datenschutz" className="inline-flex min-h-11 items-center text-[14px] text-muted-foreground hover:text-foreground">{t("footer.privacy")}</Link></li>
</ul>
+19
View File
@@ -0,0 +1,19 @@
/**
* Anbieterkennzeichnung (§ 5 DDG) — übernommen aus https://gefim.de/impressum (Stand 21.09.2026).
* Einzige Quelle für Impressum und ggf. Mail-Fußzeilen; Beschriftungen stehen im Message-Katalog.
*/
export const IMPRINT = {
company: "GEFIM UG (haftungsbeschränkt)",
street: "Neckarstraße 7",
city: "38120 Braunschweig",
country: "Deutschland",
registerNumber: "211852",
registerCourt: "Braunschweig",
representatives: ["Martin Solarczek", "Marcel Martin Hofmann"],
phone: "+49 531 180 540 80",
phoneHref: "tel:+4953118054080",
email: "info@gefim.de",
vatId: "DE449952428",
/** Redaktionell verantwortlich (§ 18 Abs. 2 MStV) — wie auf gefim.de angegeben */
editorial: "GEFIM UG (haftungsbeschränkt), Neckarstraße 7, 38120 Braunschweig",
} as const;
+1 -1
View File
@@ -12,7 +12,7 @@ import { NextResponse, type NextRequest } from "next/server";
// L15 Testphase: `/testen` (Wizard, Bestätigung, Nutzungsbedingungen, Datenschutz) ist öffentlich —
// abgesichert über Rate-Limit je IP/E-Mail, Honeypot, Double-Opt-in und Enumeration-Neutralität.
// Startseite ist die öffentliche Produktseite; angemeldete Nutzer leitet page.tsx weiter.
const PUBLIC_PATHS = ["/", "/funktionen", "/sicherheit", "/preise", "/login", "/api/auth", "/forgot-password", "/reset", "/invite", "/verify-email", "/platform/login", "/api/platform-auth", "/testen"];
const PUBLIC_PATHS = ["/", "/funktionen", "/sicherheit", "/preise", "/impressum", "/login", "/api/auth", "/forgot-password", "/reset", "/invite", "/verify-email", "/platform/login", "/api/platform-auth", "/testen"];
// Plattform-Bereich (getrennte Session/Login): diese Routen werden über das
// Plattform-Cookie gegatet und leiten anonyme Besucher auf /platform/login —