@@ -14,6 +14,9 @@ import HowItWorksPage from "@/pages/how-it-works"
|
|||||||
import KlarpreisPage from "@/pages/klarpreis"
|
import KlarpreisPage from "@/pages/klarpreis"
|
||||||
import { SimplePage } from "@/pages/placeholder"
|
import { SimplePage } from "@/pages/placeholder"
|
||||||
import ProductsPage from "@/pages/products"
|
import ProductsPage from "@/pages/products"
|
||||||
|
import WissenPage from "@/pages/wissen"
|
||||||
|
import DatenschutzSicherheitPage from "@/pages/wissen/datenschutz-sicherheit"
|
||||||
|
import GesetzlicheAnforderungenPage from "@/pages/wissen/gesetzliche-anforderungen"
|
||||||
|
|
||||||
function ScrollToTop() {
|
function ScrollToTop() {
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
@@ -55,31 +58,14 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
<Route path="/konfigurator" element={<ConfiguratorPage />} />
|
<Route path="/konfigurator" element={<ConfiguratorPage />} />
|
||||||
<Route path="/klarpreis" element={<KlarpreisPage />} />
|
<Route path="/klarpreis" element={<KlarpreisPage />} />
|
||||||
|
<Route path="/wissen" element={<WissenPage />} />
|
||||||
<Route
|
<Route
|
||||||
path="/wissen"
|
path="/wissen/gesetzliche-anforderungen"
|
||||||
element={
|
element={<GesetzlicheAnforderungenPage />}
|
||||||
<SimplePage
|
|
||||||
breadcrumb={[
|
|
||||||
{ label: "Startseite", to: "/" },
|
|
||||||
{ label: "Wissen" },
|
|
||||||
]}
|
|
||||||
title="Wissen"
|
|
||||||
lead="Hintergründe zu Messtechnik, Abrechnung und gesetzlichen Vorgaben rund um Wohngebäude."
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/technik-sicherheit"
|
path="/wissen/datenschutz-sicherheit"
|
||||||
element={
|
element={<DatenschutzSicherheitPage />}
|
||||||
<SimplePage
|
|
||||||
breadcrumb={[
|
|
||||||
{ label: "Startseite", to: "/" },
|
|
||||||
{ label: "Technik & Sicherheit" },
|
|
||||||
]}
|
|
||||||
title="Technik & Sicherheit"
|
|
||||||
lead="Messtechnik, Datenübertragung, Hosting und Zugriffsrechte – wie GebOS den laufenden Messbetrieb technisch und organisatorisch absichert."
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/unternehmen"
|
path="/unternehmen"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Container } from "@/components/gebos/section"
|
|||||||
*/
|
*/
|
||||||
function PageHero({
|
function PageHero({
|
||||||
breadcrumb,
|
breadcrumb,
|
||||||
|
eyebrow,
|
||||||
title,
|
title,
|
||||||
lead,
|
lead,
|
||||||
actions,
|
actions,
|
||||||
@@ -18,6 +19,7 @@ function PageHero({
|
|||||||
className,
|
className,
|
||||||
}: {
|
}: {
|
||||||
breadcrumb?: React.ReactNode
|
breadcrumb?: React.ReactNode
|
||||||
|
eyebrow?: React.ReactNode
|
||||||
title: React.ReactNode
|
title: React.ReactNode
|
||||||
lead?: React.ReactNode
|
lead?: React.ReactNode
|
||||||
actions?: React.ReactNode
|
actions?: React.ReactNode
|
||||||
@@ -41,6 +43,11 @@ function PageHero({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className={cn("max-w-xl", breadcrumb && "lg:self-start")}>
|
<div className={cn("max-w-xl", breadcrumb && "lg:self-start")}>
|
||||||
|
{eyebrow ? (
|
||||||
|
<p className="mb-2 text-xs font-bold tracking-[0.14em] text-primary uppercase">
|
||||||
|
{eyebrow}
|
||||||
|
</p>
|
||||||
|
) : null}
|
||||||
<h1 className="text-4xl font-extrabold tracking-tight text-balance text-navy sm:text-5xl">
|
<h1 className="text-4xl font-extrabold tracking-tight text-balance text-navy sm:text-5xl">
|
||||||
{title}
|
{title}
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ type TrustPanelItem = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Trust panel: a pale plate carrying the headline and the technical properties
|
* Trust panel: a pale plate carrying the headline and the technical properties
|
||||||
* as white pills (teal line icon beside a short label). Three pills across from
|
* as white pills (teal line icon beside a short label), two across from `sm`
|
||||||
* `lg`, so five items settle into 3 + 2 as in the design, with the security
|
* so the labels stay on one line next to the security render, with the
|
||||||
* render alongside and the follow-up link on the baseline underneath.
|
* follow-up link on the baseline underneath.
|
||||||
*/
|
*/
|
||||||
function TrustPanel({
|
function TrustPanel({
|
||||||
title,
|
title,
|
||||||
@@ -31,34 +31,45 @@ function TrustPanel({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"border-border shadow-card rounded-3xl border bg-gradient-to-br from-white via-white to-secondary p-6 sm:p-8 lg:p-10",
|
/* the plate is a wash, not a card: it stays translucent so the page
|
||||||
|
reads through it and the white pills keep their contrast */
|
||||||
|
"border-border/70 rounded-3xl border bg-gradient-to-br from-white/70 via-white/40 to-brand-50/40 p-6 sm:p-8 lg:p-10",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col gap-8 lg:flex-row lg:items-center lg:gap-10">
|
<div className="lg:flex lg:items-center lg:gap-10">
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<h2 className="text-navy text-2xl font-extrabold tracking-tight text-balance sm:text-[1.75rem]">
|
<h2 className="text-navy text-lg font-bold tracking-tight text-balance sm:text-xl">
|
||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
<div className="mt-6 grid gap-4 sm:grid-cols-2">
|
||||||
{items.map((item, i) => (
|
{items.map((item, i) => (
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
className="bg-card shadow-card flex items-center gap-4 rounded-2xl px-5 py-4"
|
className="bg-card shadow-card flex items-center gap-5 rounded-xl px-5 py-3.5"
|
||||||
>
|
>
|
||||||
<span className="text-brand-600 flex shrink-0 [&_svg]:size-8">
|
<span className="text-brand-600 flex shrink-0 [&_svg]:size-7">
|
||||||
{item.icon}
|
{item.icon}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-navy/80 text-[0.9375rem] leading-snug font-semibold text-balance">
|
<span className="text-navy/75 text-[0.9375rem] leading-snug font-medium text-balance">
|
||||||
{item.label}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{visual ? <div className="shrink-0 self-center">{visual}</div> : null}
|
{visual ? (
|
||||||
|
/* stacked layouts hang the render off the right edge instead of
|
||||||
|
centring it, so it anchors the link underneath rather than
|
||||||
|
leaving the row beside it empty */
|
||||||
|
<div className="mt-8 flex justify-end lg:mt-0 lg:shrink-0">
|
||||||
|
{visual}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
{action ? <div className="mt-8 flex justify-end">{action}</div> : null}
|
{action ? (
|
||||||
|
<div className="mt-8 flex justify-end lg:mt-6">{action}</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -72,7 +83,7 @@ function TrustShieldArt({ className }: { className?: string }) {
|
|||||||
<AssetRender
|
<AssetRender
|
||||||
render={renders.glassShieldLock}
|
render={renders.glassShieldLock}
|
||||||
alt=""
|
alt=""
|
||||||
className={cn("mx-auto block w-40 sm:w-44", className)}
|
className={cn("block w-40 lg:w-56", className)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
Calculator,
|
Calculator,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
Lock,
|
Lock,
|
||||||
Puzzle,
|
|
||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
Users,
|
Users,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
@@ -374,7 +373,6 @@ const trustProperties = [
|
|||||||
{ icon: <ShieldCheck />, label: "AES-geschützte Messdaten" },
|
{ icon: <ShieldCheck />, label: "AES-geschützte Messdaten" },
|
||||||
{ icon: <Lock />, label: "TLS-verschlüsselte Übertragung" },
|
{ icon: <Lock />, label: "TLS-verschlüsselte Übertragung" },
|
||||||
{ icon: <Users />, label: "Rollenbasierte Zugriffsrechte" },
|
{ icon: <Users />, label: "Rollenbasierte Zugriffsrechte" },
|
||||||
{ icon: <Puzzle />, label: "Interoperable Messtechnik" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
@@ -647,13 +645,13 @@ export default function HomePage() {
|
|||||||
|
|
||||||
<Section>
|
<Section>
|
||||||
<TrustPanel
|
<TrustPanel
|
||||||
title="Technik, Datenschutz & Sicherheit"
|
title="Datenschutz & Sicherheit"
|
||||||
items={trustProperties}
|
items={trustProperties}
|
||||||
visual={<TrustShieldArt />}
|
visual={<TrustShieldArt />}
|
||||||
action={
|
action={
|
||||||
<Button asChild variant="link" className="h-auto p-0 font-bold">
|
<Button asChild variant="link" className="h-auto p-0 font-bold">
|
||||||
<Link to="/technik-sicherheit">
|
<Link to="/wissen/datenschutz-sicherheit">
|
||||||
Mehr zu Technik & Sicherheit
|
Mehr zu Datenschutz & Sicherheit
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { KeyRound, Lock, MapPin, ShieldCheck, Users } from "lucide-react"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { CtaBanner } from "@/components/gebos/cta-banner"
|
||||||
|
import { Section, SectionHeading } from "@/components/gebos/section"
|
||||||
|
import {
|
||||||
|
AssetRender,
|
||||||
|
renders,
|
||||||
|
vectors,
|
||||||
|
} from "@/components/gebos/site-assets"
|
||||||
|
import {
|
||||||
|
TopicCards,
|
||||||
|
WissenArticle,
|
||||||
|
WissenRelated,
|
||||||
|
type Topic,
|
||||||
|
} from "@/pages/wissen/wissen-article"
|
||||||
|
|
||||||
|
const safeguards: Topic[] = [
|
||||||
|
{
|
||||||
|
icon: <MapPin />,
|
||||||
|
title: "Datenstandort",
|
||||||
|
body: "Anwendungs- und Messdaten werden in Falkenstein, Deutschland, gehostet.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Lock />,
|
||||||
|
title: "Verschlüsselte Übertragung",
|
||||||
|
body: "Messdaten werden bereits auf der Funkstrecke mittels AES geschützt. Die Übertragung zwischen Gateway und GebOS sowie der Zugriff auf das Portal erfolgen TLS-verschlüsselt.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Users />,
|
||||||
|
title: "Rollen und Zugriffsrechte",
|
||||||
|
body: "Zugriffe werden nach Rolle, Gebäude, Wohnung und Nutzungszeitraum begrenzt. Bewohner sehen ausschließlich die ihrem eigenen Nutzungsverhältnis zugeordneten Verbrauchsdaten – nicht die Daten von Vor- oder Nachmietern.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <KeyRound />,
|
||||||
|
title: "Kontrollierbare Geräteschlüssel",
|
||||||
|
body: "Die Schlüssel der installierten Verbrauchserfassungsgeräte können ausgelesen und dem Gebäudeeigentümer zur Verfügung gestellt werden. Die Messtechnik bleibt dadurch nicht dauerhaft an GebOS gebunden.",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hero art: the glass shield with the lock as the subject, the wireless orb
|
||||||
|
* and the gateway beside it – the chain the copy describes
|
||||||
|
* (Funkstrecke → Gateway → Plattform). Decorative; the copy carries meaning.
|
||||||
|
*/
|
||||||
|
function SecurityHeroArt() {
|
||||||
|
return (
|
||||||
|
<div className="relative mx-auto flex aspect-[1.3] w-full max-w-md items-center">
|
||||||
|
<img
|
||||||
|
src={vectors.wirelessOrb}
|
||||||
|
alt=""
|
||||||
|
className="absolute top-0 right-[4%] w-[22%]"
|
||||||
|
/>
|
||||||
|
<AssetRender
|
||||||
|
render={renders.glassShieldLock}
|
||||||
|
alt=""
|
||||||
|
className="mx-auto w-[74%]"
|
||||||
|
loading="eager"
|
||||||
|
/>
|
||||||
|
<AssetRender
|
||||||
|
render={renders.glassGateway}
|
||||||
|
alt=""
|
||||||
|
className="absolute bottom-[2%] left-0 w-[26%]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DatenschutzSicherheitPage() {
|
||||||
|
return (
|
||||||
|
<WissenArticle
|
||||||
|
breadcrumb="Datenschutz & Sicherheit"
|
||||||
|
eyebrow="Technik & Sicherheit"
|
||||||
|
title="Datenschutz und technische Sicherheit"
|
||||||
|
lead="Wo die Messdaten liegen, wie sie übertragen werden und wer sie sehen darf – jeweils auf die Ebene begrenzt, die für den Messbetrieb erforderlich ist."
|
||||||
|
visual={<SecurityHeroArt />}
|
||||||
|
>
|
||||||
|
<Section className="pt-2 sm:pt-4 lg:pt-6">
|
||||||
|
<SectionHeading
|
||||||
|
eyebrow="Sicherheit"
|
||||||
|
title="Technische und organisatorische Maßnahmen"
|
||||||
|
lead="Messdaten entstehen in der Wohnung und werden zentral verarbeitet. Auf jedem Abschnitt dieses Wegs gilt eine eigene Schutzmaßnahme."
|
||||||
|
/>
|
||||||
|
<TopicCards items={safeguards} className="sm:grid-cols-2" />
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<WissenRelated
|
||||||
|
to="/wissen/gesetzliche-anforderungen"
|
||||||
|
title="Gesetzliche Anforderungen an den Messbetrieb"
|
||||||
|
summary="Unterjährige Verbrauchsinformation, Fernablesbarkeit und interoperable Messtechnik nach HeizkostenV."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Section className="pt-0 sm:pt-0 lg:pt-0">
|
||||||
|
<CtaBanner
|
||||||
|
icon={<ShieldCheck />}
|
||||||
|
title="Fragen zu Datenschutz oder technischer Sicherheit?"
|
||||||
|
description="Wir gehen Datenhaltung, Datenübertragung und Zugriffsrechte für Ihr Gebäude konkret durch."
|
||||||
|
actions={
|
||||||
|
<>
|
||||||
|
<Button asChild variant="inverse" size="lg">
|
||||||
|
<Link to="/kontakt">Kontakt aufnehmen</Link>
|
||||||
|
</Button>
|
||||||
|
<Button asChild variant="inverseOutline" size="lg">
|
||||||
|
<Link to="/konfigurator">Preis berechnen</Link>
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
</WissenArticle>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { BarChart3, KeyRound, Puzzle, RadioTower, ShieldCheck } from "lucide-react"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { CtaBanner } from "@/components/gebos/cta-banner"
|
||||||
|
import { IconBadge } from "@/components/gebos/icon-tile"
|
||||||
|
import { Section, SectionHeading } from "@/components/gebos/section"
|
||||||
|
import {
|
||||||
|
AssetRender,
|
||||||
|
renders,
|
||||||
|
vectors,
|
||||||
|
} from "@/components/gebos/site-assets"
|
||||||
|
import {
|
||||||
|
HEIZKOSTENV,
|
||||||
|
TopicCards,
|
||||||
|
WissenArticle,
|
||||||
|
WissenRelated,
|
||||||
|
type Topic,
|
||||||
|
} from "@/pages/wissen/wissen-article"
|
||||||
|
|
||||||
|
const requirements: Topic[] = [
|
||||||
|
{
|
||||||
|
icon: <BarChart3 />,
|
||||||
|
title: "Unterjährige Verbrauchsinformation",
|
||||||
|
body: "Monatliche Verbrauchsinformationen auf Basis der erfassten Verbrauchs- und Ablesewerte – zur Umsetzung der Anforderungen des § 6a HeizkostenV.",
|
||||||
|
source: { cite: "§ 6a HeizkostenV", href: `${HEIZKOSTENV}/__6a.html` },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <RadioTower />,
|
||||||
|
title: "Fernablesbarkeit",
|
||||||
|
body: "Verbrauchswerte werden ohne Zugang zu den einzelnen Wohnungen ausgelesen und zentral für Verbrauchsinformation und Abrechnung bereitgestellt.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Puzzle />,
|
||||||
|
title: "Interoperable Messtechnik",
|
||||||
|
body: "Die eingesetzten Verbrauchserfassungsgeräte sind OMS-fähig. Soweit für die jeweilige Ausstattung anwendbar, erfüllt die gelieferte Messtechnik die Anforderungen an Interoperabilität und Stand der Technik nach § 5 HeizkostenV.",
|
||||||
|
source: { cite: "§ 5 HeizkostenV", href: `${HEIZKOSTENV}/__5.html` },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hero art: the UVI pane as the subject with the consumption donut and the
|
||||||
|
* UVI badge beside it – what the requirements produce for the resident.
|
||||||
|
* Decorative; the copy carries the meaning.
|
||||||
|
*/
|
||||||
|
function RequirementsHeroArt() {
|
||||||
|
return (
|
||||||
|
<div className="relative mx-auto flex aspect-[1.3] w-full max-w-md items-center">
|
||||||
|
<img
|
||||||
|
src={vectors.uviBadge}
|
||||||
|
alt=""
|
||||||
|
className="absolute top-0 right-[4%] w-[22%]"
|
||||||
|
/>
|
||||||
|
<AssetRender
|
||||||
|
render={renders.uviGlassPane}
|
||||||
|
alt=""
|
||||||
|
className="mx-auto w-[74%]"
|
||||||
|
loading="eager"
|
||||||
|
/>
|
||||||
|
<AssetRender
|
||||||
|
render={renders.glassDonutShadow}
|
||||||
|
alt=""
|
||||||
|
className="absolute bottom-0 left-0 w-[30%]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function GesetzlicheAnforderungenPage() {
|
||||||
|
return (
|
||||||
|
<WissenArticle
|
||||||
|
breadcrumb="Gesetzliche Anforderungen"
|
||||||
|
eyebrow="Technik & Anforderungen"
|
||||||
|
title="Gesetzliche Anforderungen an den Messbetrieb"
|
||||||
|
tagline="Für den Messbetrieb gebaut."
|
||||||
|
lead="GebOS verbindet fernablesbare Messtechnik, Verbrauchsinformationen und Abrechnung in einer klaren technischen und organisatorischen Struktur."
|
||||||
|
visual={<RequirementsHeroArt />}
|
||||||
|
>
|
||||||
|
<Section className="pt-2 sm:pt-4 lg:pt-6">
|
||||||
|
<SectionHeading
|
||||||
|
eyebrow="Anforderungen"
|
||||||
|
title="Was die Heizkostenverordnung verlangt"
|
||||||
|
lead="Verbrauchsinformation, Fernablesbarkeit und Interoperabilität sind keine getrennten Themen – sie hängen an derselben Messtechnik und derselben Datenerfassung."
|
||||||
|
/>
|
||||||
|
<TopicCards
|
||||||
|
items={requirements}
|
||||||
|
className="sm:grid-cols-2 lg:grid-cols-3"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<aside className="mt-6 flex flex-col gap-5 rounded-3xl border border-brand-200 bg-brand-50/50 p-6 sm:flex-row sm:items-center sm:gap-6 sm:p-8">
|
||||||
|
<IconBadge
|
||||||
|
variant="solid"
|
||||||
|
shape="squircle"
|
||||||
|
size="lg"
|
||||||
|
className="shadow-band"
|
||||||
|
>
|
||||||
|
<KeyRound />
|
||||||
|
</IconBadge>
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<h3 className="text-base font-bold text-balance text-navy sm:text-lg">
|
||||||
|
Ein Wechsel des Messdienstleisters bleibt möglich
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 text-sm leading-relaxed text-pretty text-navy/80 sm:text-base">
|
||||||
|
Die AES-Schlüssel der Verbrauchserfassungsgeräte bleiben verfügbar
|
||||||
|
und können dem Gebäudeeigentümer bereitgestellt werden. Dadurch
|
||||||
|
bleibt ein späterer Wechsel des Messdienstleisters technisch
|
||||||
|
möglich.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<WissenRelated
|
||||||
|
to="/wissen/datenschutz-sicherheit"
|
||||||
|
title="Datenschutz und technische Sicherheit"
|
||||||
|
summary="Datenstandort, verschlüsselte Übertragung, Rollen und Zugriffsrechte sowie kontrollierbare Geräteschlüssel."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Section className="pt-0 sm:pt-0 lg:pt-0">
|
||||||
|
<CtaBanner
|
||||||
|
icon={<ShieldCheck />}
|
||||||
|
title="Erfüllt Ihr Gebäude die Anforderungen bereits?"
|
||||||
|
description="Wir prüfen Ausstattung, Fernablesbarkeit und Verbrauchsinformation für Ihr Gebäude konkret."
|
||||||
|
actions={
|
||||||
|
<>
|
||||||
|
<Button asChild variant="inverse" size="lg">
|
||||||
|
<Link to="/kontakt">Kontakt aufnehmen</Link>
|
||||||
|
</Button>
|
||||||
|
<Button asChild variant="inverseOutline" size="lg">
|
||||||
|
<Link to="/konfigurator">Preis berechnen</Link>
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
</WissenArticle>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import type * as React from "react"
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { ArrowRight, ScrollText, ShieldCheck } from "lucide-react"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { Card } from "@/components/ui/card"
|
||||||
|
import { IconBadge } from "@/components/gebos/icon-tile"
|
||||||
|
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||||
|
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||||
|
|
||||||
|
type Article = {
|
||||||
|
icon: React.ReactNode
|
||||||
|
title: string
|
||||||
|
summary: string
|
||||||
|
to: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const articles: Article[] = [
|
||||||
|
{
|
||||||
|
icon: <ScrollText />,
|
||||||
|
title: "Gesetzliche Anforderungen an den Messbetrieb",
|
||||||
|
summary:
|
||||||
|
"Unterjährige Verbrauchsinformation nach § 6a HeizkostenV, Fernablesbarkeit ohne Zugang zur Wohnung und interoperable, OMS-fähige Messtechnik nach § 5 HeizkostenV.",
|
||||||
|
to: "/wissen/gesetzliche-anforderungen",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <ShieldCheck />,
|
||||||
|
title: "Datenschutz und technische Sicherheit",
|
||||||
|
summary:
|
||||||
|
"Datenstandort in Deutschland, AES- und TLS-verschlüsselte Übertragung, Zugriffsrechte nach Rolle und Nutzungszeitraum sowie kontrollierbare Geräteschlüssel.",
|
||||||
|
to: "/wissen/datenschutz-sicherheit",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function WissenPage() {
|
||||||
|
return (
|
||||||
|
<div className="bg-hero-glow">
|
||||||
|
<Container>
|
||||||
|
<Section className="pt-6 sm:pt-7 lg:pt-8">
|
||||||
|
<PageBreadcrumb
|
||||||
|
className="mb-4"
|
||||||
|
items={[{ label: "Startseite", to: "/" }, { label: "Wissen" }]}
|
||||||
|
/>
|
||||||
|
<SectionHeading
|
||||||
|
title="Wissen"
|
||||||
|
lead="Hintergründe zu Messtechnik, Abrechnung und gesetzlichen Vorgaben rund um Wohngebäude."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="mt-10 grid gap-5 lg:grid-cols-2">
|
||||||
|
{articles.map((article) => (
|
||||||
|
<Card key={article.to} className="gap-0 p-7">
|
||||||
|
<IconBadge variant="outline" shape="squircle" size="lg">
|
||||||
|
{article.icon}
|
||||||
|
</IconBadge>
|
||||||
|
<h2 className="mt-5 text-xl font-extrabold tracking-tight text-balance text-navy">
|
||||||
|
{article.title}
|
||||||
|
</h2>
|
||||||
|
<p className="mt-3 text-sm leading-relaxed text-pretty text-muted-foreground">
|
||||||
|
{article.summary}
|
||||||
|
</p>
|
||||||
|
<div className="mt-6 flex-1 content-end">
|
||||||
|
<Button asChild variant="outline">
|
||||||
|
<Link to={article.to}>
|
||||||
|
Mehr erfahren
|
||||||
|
<ArrowRight />
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
import type * as React from "react"
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { ArrowRight } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Card, CardContent } from "@/components/ui/card"
|
||||||
|
import { IconBadge } from "@/components/gebos/icon-tile"
|
||||||
|
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||||
|
import { PageHero } from "@/components/gebos/page-hero"
|
||||||
|
import { Container, Section } from "@/components/gebos/section"
|
||||||
|
|
||||||
|
/** The paragraph of the HeizkostenV a property is cited against. */
|
||||||
|
type LegalSource = {
|
||||||
|
cite: string
|
||||||
|
href: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** One technical property: line icon, title, body, optional legal citation. */
|
||||||
|
type Topic = {
|
||||||
|
icon: React.ReactNode
|
||||||
|
title: string
|
||||||
|
body: string
|
||||||
|
source?: LegalSource
|
||||||
|
}
|
||||||
|
|
||||||
|
const HEIZKOSTENV = "https://www.gesetze-im-internet.de/heizkostenv"
|
||||||
|
|
||||||
|
/** Cited source line, pinned to the card's baseline so rows stay aligned. */
|
||||||
|
function LegalSourceNote({ source }: { source: LegalSource }) {
|
||||||
|
return (
|
||||||
|
<p className="mt-auto pt-4 text-xs text-muted-foreground">
|
||||||
|
Quelle:{" "}
|
||||||
|
<a
|
||||||
|
href={source.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="font-medium text-brand-700 underline-offset-2 transition-colors hover:text-brand-800 hover:underline"
|
||||||
|
>
|
||||||
|
{source.cite}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Property grid: line icon over a navy title, body copy, optional citation. */
|
||||||
|
function TopicCards({
|
||||||
|
items,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
items: Topic[]
|
||||||
|
className?: string
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className={cn("mt-10 grid gap-5", className)}>
|
||||||
|
{items.map((item) => (
|
||||||
|
<Card key={item.title}>
|
||||||
|
<CardContent className="flex flex-1 flex-col">
|
||||||
|
<IconBadge variant="outline" shape="squircle" size="lg">
|
||||||
|
{item.icon}
|
||||||
|
</IconBadge>
|
||||||
|
<h3 className="mt-5 text-base font-bold text-balance text-navy">
|
||||||
|
{item.title}
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 text-sm leading-relaxed text-pretty text-muted-foreground">
|
||||||
|
{item.body}
|
||||||
|
</p>
|
||||||
|
{item.source ? <LegalSourceNote source={item.source} /> : null}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared shell for the /wissen articles: split PageHero with the
|
||||||
|
* Startseite → Wissen → article breadcrumb, then the article's own sections.
|
||||||
|
*/
|
||||||
|
function WissenArticle({
|
||||||
|
breadcrumb,
|
||||||
|
eyebrow,
|
||||||
|
title,
|
||||||
|
tagline,
|
||||||
|
lead,
|
||||||
|
visual,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
/** label of the current page, appended to Startseite → Wissen */
|
||||||
|
breadcrumb: string
|
||||||
|
eyebrow?: React.ReactNode
|
||||||
|
title: React.ReactNode
|
||||||
|
/** short bold subline under the H1 (e.g. "Für den Messbetrieb gebaut.") */
|
||||||
|
tagline?: React.ReactNode
|
||||||
|
lead?: React.ReactNode
|
||||||
|
visual?: React.ReactNode
|
||||||
|
children?: React.ReactNode
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHero
|
||||||
|
breadcrumb={
|
||||||
|
<PageBreadcrumb
|
||||||
|
items={[
|
||||||
|
{ label: "Startseite", to: "/" },
|
||||||
|
{ label: "Wissen", to: "/wissen" },
|
||||||
|
{ label: breadcrumb },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
eyebrow={eyebrow}
|
||||||
|
title={title}
|
||||||
|
lead={
|
||||||
|
<>
|
||||||
|
{tagline ? (
|
||||||
|
<span className="mb-2 block text-lg font-bold text-navy sm:text-xl">
|
||||||
|
{tagline}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
{lead}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
visual={visual}
|
||||||
|
/>
|
||||||
|
<Container>{children}</Container>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Baseline link to the sibling article, closing an article out. */
|
||||||
|
function WissenRelated({
|
||||||
|
to,
|
||||||
|
title,
|
||||||
|
summary,
|
||||||
|
}: {
|
||||||
|
to: string
|
||||||
|
title: string
|
||||||
|
summary: string
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Section className="pt-0 sm:pt-0 lg:pt-0">
|
||||||
|
<Link
|
||||||
|
to={to}
|
||||||
|
className="group flex items-center gap-6 rounded-3xl border border-border bg-card p-6 shadow-card transition-colors hover:border-brand-200 sm:p-8"
|
||||||
|
>
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<p className="text-xs font-bold tracking-[0.14em] text-primary uppercase">
|
||||||
|
Weiterlesen
|
||||||
|
</p>
|
||||||
|
<h2 className="mt-2 text-xl font-extrabold tracking-tight text-balance text-navy">
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
<p className="mt-2 text-sm leading-relaxed text-pretty text-muted-foreground">
|
||||||
|
{summary}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<IconBadge
|
||||||
|
variant="outline"
|
||||||
|
size="lg"
|
||||||
|
className="transition-transform group-hover:translate-x-0.5"
|
||||||
|
>
|
||||||
|
<ArrowRight />
|
||||||
|
</IconBadge>
|
||||||
|
</Link>
|
||||||
|
</Section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { HEIZKOSTENV, TopicCards, WissenArticle, WissenRelated }
|
||||||
|
export type { LegalSource, Topic }
|
||||||
@@ -323,6 +323,21 @@ Setzen Sie Gebos bei Ihren bestehenden Kunden ein, ohne zunächst ein Partnerpro
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Datenschutz & Sicherheit
|
||||||
|
|
||||||
|
Zurückhaltender Vertrauensblock kurz vor dem Abschluss. Nur belegbare Eigenschaften, keine Superlative.
|
||||||
|
|
||||||
|
- Hosting in Deutschland
|
||||||
|
- AES-geschützte Messdaten
|
||||||
|
- TLS-verschlüsselte Übertragung
|
||||||
|
- Rollenbasierte Zugriffsrechte
|
||||||
|
|
||||||
|
**[Mehr zu Datenschutz & Sicherheit]**
|
||||||
|
|
||||||
|
→ Führt auf die Wissensseite Datenschutz & Sicherheit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# Abschluss
|
# Abschluss
|
||||||
|
|
||||||
## Messdienstleistungen müssen nicht kompliziert sein.
|
## Messdienstleistungen müssen nicht kompliziert sein.
|
||||||
|
|||||||
Reference in New Issue
Block a user