diff --git a/component-library/src/App.tsx b/component-library/src/App.tsx index 544035e..336bd58 100644 --- a/component-library/src/App.tsx +++ b/component-library/src/App.tsx @@ -14,6 +14,9 @@ import HowItWorksPage from "@/pages/how-it-works" import KlarpreisPage from "@/pages/klarpreis" import { SimplePage } from "@/pages/placeholder" 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() { const { pathname } = useLocation() @@ -55,31 +58,14 @@ export default function App() { /> } /> } /> + } /> - } + path="/wissen/gesetzliche-anforderungen" + element={} /> - } + path="/wissen/datenschutz-sicherheit" + element={} />
+ {eyebrow ? ( +

+ {eyebrow} +

+ ) : null}

{title}

diff --git a/component-library/src/components/gebos/trust-panel.tsx b/component-library/src/components/gebos/trust-panel.tsx index 1b4e8b6..3b3d3e0 100644 --- a/component-library/src/components/gebos/trust-panel.tsx +++ b/component-library/src/components/gebos/trust-panel.tsx @@ -10,9 +10,9 @@ type TrustPanelItem = { /** * 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 - * `lg`, so five items settle into 3 + 2 as in the design, with the security - * render alongside and the follow-up link on the baseline underneath. + * as white pills (teal line icon beside a short label), two across from `sm` + * so the labels stay on one line next to the security render, with the + * follow-up link on the baseline underneath. */ function TrustPanel({ title, @@ -31,34 +31,45 @@ function TrustPanel({ return (
-
+
-

+

{title}

-
+
{items.map((item, i) => (
- + {item.icon} - + {item.label}
))}
- {visual ?
{visual}
: 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 */ +
+ {visual} +
+ ) : null}
- {action ?
{action}
: null} + {action ? ( +
{action}
+ ) : null}
) } @@ -72,7 +83,7 @@ function TrustShieldArt({ className }: { className?: string }) { ) } diff --git a/component-library/src/pages/home.tsx b/component-library/src/pages/home.tsx index 63e696b..acfd080 100644 --- a/component-library/src/pages/home.tsx +++ b/component-library/src/pages/home.tsx @@ -4,7 +4,6 @@ import { Calculator, ChevronRight, Lock, - Puzzle, ShieldCheck, Users, } from "lucide-react" @@ -374,7 +373,6 @@ const trustProperties = [ { icon: , label: "AES-geschützte Messdaten" }, { icon: , label: "TLS-verschlüsselte Übertragung" }, { icon: , label: "Rollenbasierte Zugriffsrechte" }, - { icon: , label: "Interoperable Messtechnik" }, ] export default function HomePage() { @@ -647,13 +645,13 @@ export default function HomePage() {
} action={ diff --git a/component-library/src/pages/wissen/datenschutz-sicherheit.tsx b/component-library/src/pages/wissen/datenschutz-sicherheit.tsx new file mode 100644 index 0000000..8ae194e --- /dev/null +++ b/component-library/src/pages/wissen/datenschutz-sicherheit.tsx @@ -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: , + title: "Datenstandort", + body: "Anwendungs- und Messdaten werden in Falkenstein, Deutschland, gehostet.", + }, + { + icon: , + 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: , + 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: , + 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 ( +
+ + + +
+ ) +} + +export default function DatenschutzSicherheitPage() { + return ( + } + > +
+ + +
+ + + +
+ } + title="Fragen zu Datenschutz oder technischer Sicherheit?" + description="Wir gehen Datenhaltung, Datenübertragung und Zugriffsrechte für Ihr Gebäude konkret durch." + actions={ + <> + + + + } + /> +
+
+ ) +} diff --git a/component-library/src/pages/wissen/gesetzliche-anforderungen.tsx b/component-library/src/pages/wissen/gesetzliche-anforderungen.tsx new file mode 100644 index 0000000..1ac28f6 --- /dev/null +++ b/component-library/src/pages/wissen/gesetzliche-anforderungen.tsx @@ -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: , + 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: , + title: "Fernablesbarkeit", + body: "Verbrauchswerte werden ohne Zugang zu den einzelnen Wohnungen ausgelesen und zentral für Verbrauchsinformation und Abrechnung bereitgestellt.", + }, + { + icon: , + 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 ( +
+ + + +
+ ) +} + +export default function GesetzlicheAnforderungenPage() { + return ( + } + > +
+ + + + +
+ + + +
+ } + title="Erfüllt Ihr Gebäude die Anforderungen bereits?" + description="Wir prüfen Ausstattung, Fernablesbarkeit und Verbrauchsinformation für Ihr Gebäude konkret." + actions={ + <> + + + + } + /> +
+
+ ) +} diff --git a/component-library/src/pages/wissen/index.tsx b/component-library/src/pages/wissen/index.tsx new file mode 100644 index 0000000..a198ab7 --- /dev/null +++ b/component-library/src/pages/wissen/index.tsx @@ -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: , + 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: , + 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 ( +
+ +
+ + + +
+ {articles.map((article) => ( + + + {article.icon} + +

+ {article.title} +

+

+ {article.summary} +

+
+ +
+
+ ))} +
+
+
+
+ ) +} diff --git a/component-library/src/pages/wissen/wissen-article.tsx b/component-library/src/pages/wissen/wissen-article.tsx new file mode 100644 index 0000000..6b690fc --- /dev/null +++ b/component-library/src/pages/wissen/wissen-article.tsx @@ -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 ( +

+ Quelle:{" "} + + {source.cite} + +

+ ) +} + +/** Property grid: line icon over a navy title, body copy, optional citation. */ +function TopicCards({ + items, + className, +}: { + items: Topic[] + className?: string +}) { + return ( +
+ {items.map((item) => ( + + + + {item.icon} + +

+ {item.title} +

+

+ {item.body} +

+ {item.source ? : null} +
+
+ ))} +
+ ) +} + +/** + * 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 ( + <> + + } + eyebrow={eyebrow} + title={title} + lead={ + <> + {tagline ? ( + + {tagline} + + ) : null} + {lead} + + } + visual={visual} + /> + {children} + + ) +} + +/** Baseline link to the sibling article, closing an article out. */ +function WissenRelated({ + to, + title, + summary, +}: { + to: string + title: string + summary: string +}) { + return ( +
+ +
+

+ Weiterlesen +

+

+ {title} +

+

+ {summary} +

+
+ + + + +
+ ) +} + +export { HEIZKOSTENV, TopicCards, WissenArticle, WissenRelated } +export type { LegalSource, Topic } diff --git a/seiten/startseite.md b/seiten/startseite.md index 4470c23..33c8dd8 100644 --- a/seiten/startseite.md +++ b/seiten/startseite.md @@ -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 ## Messdienstleistungen müssen nicht kompliziert sein.