This commit is contained in:
Lars Nolden
2026-08-13 15:46:04 +02:00
parent 920b1da4b0
commit 2c1a8ae9b5
178 changed files with 10289 additions and 0 deletions
@@ -0,0 +1,115 @@
import * as React from "react"
import { Container, Section, SectionHeading } from "@/components/gebos/section"
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
import { PageHero } from "@/components/gebos/page-hero"
import { FeatureTile } from "@/components/gebos/icon-tile"
type AudienceFeature = {
icon?: React.ReactNode
/** self-contained visual (asset-kit icon/vector) rendered without IconBadge */
media?: React.ReactNode
title: React.ReactNode
sub?: React.ReactNode
}
function AudienceBreadcrumb({ current }: { current: string }) {
return (
<PageBreadcrumb
items={[{ label: "Für wen?", to: "/fuer-wen" }, { label: current }]}
/>
)
}
/**
* Shared audience page template (tiles 58):
* split PageHero with breadcrumb, feature tile row, closing slot
* (teal CtaBanner or slim repeat-CTA section).
*/
function AudiencePage({
breadcrumb,
title,
tagline,
lead,
actions,
visual,
features,
children,
closing,
}: {
breadcrumb: string
title: React.ReactNode
/** short bold subline under the H1 (e.g. "Bestellen. Montieren. Fertig.") */
tagline?: React.ReactNode
lead?: React.ReactNode
actions?: React.ReactNode
visual?: React.ReactNode
features: AudienceFeature[]
/** additional full-width spec sections between feature row and closing */
children?: React.ReactNode
closing?: React.ReactNode
}) {
return (
<>
<PageHero
breadcrumb={<AudienceBreadcrumb current={breadcrumb} />}
title={title}
lead={
<>
{tagline ? (
<span className="mb-2 block text-lg font-bold text-navy sm:text-xl">
{tagline}
</span>
) : null}
{lead}
</>
}
actions={actions}
visual={visual}
/>
<Container>
<Section className="pt-2 sm:pt-4 lg:pt-6">
<div className="grid grid-cols-2 gap-x-6 gap-y-10 sm:grid-cols-4">
{features.map((feature, i) => (
<FeatureTile
key={i}
icon={feature.icon}
media={feature.media}
title={feature.title}
sub={feature.sub}
/>
))}
</div>
</Section>
{children}
{closing}
</Container>
</>
)
}
/**
* Slim closing section repeating the hero CTAs
* (tiles 7 and 8 close without a gradient band).
*/
function AudienceClosing({
title,
lead,
actions,
}: {
title: React.ReactNode
lead?: React.ReactNode
actions: React.ReactNode
}) {
return (
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading align="center" title={title} lead={lead} />
<div className="mt-7 flex flex-wrap items-center justify-center gap-3">
{actions}
</div>
</Section>
)
}
export { AudiencePage, AudienceClosing }
export type { AudienceFeature }
@@ -0,0 +1,291 @@
import { Link } from "react-router-dom"
import { Euro, Handshake, ReceiptText, ShieldCheck, Wrench } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Section, SectionHeading } from "@/components/gebos/section"
import { CtaBanner } from "@/components/gebos/cta-banner"
import { NumberedList } from "@/components/gebos/process-steps"
import { AssetRender, renders } from "@/components/gebos/site-assets"
import { AudiencePage } from "@/pages/audiences/audience-page"
/**
* Page-local hero composition (05-homeowners kit):
* building render on the right, smoke alarm top-left,
* detached check orb as accent between them.
*/
function HomeownerArt() {
return (
<div className="relative mx-auto aspect-[1.28] w-full max-w-[560px]">
<AssetRender
render={renders.buildingIso}
className="absolute top-[4%] right-0 w-[74%] z-50"
imgClassName="w-full"
loading="eager"
/>
<AssetRender
render={renders.smokeAlarm}
className="absolute top-[8%] left-[2%] w-[26%]"
imgClassName="w-full"
/>
<AssetRender
render={renders.barChart}
alt=""
className="absolute top-[52%] left-[10%] w-[16%] scale-200"
/>
<AssetRender
render={renders.barChart}
alt=""
className="absolute top-[40%] right-[0%] w-[16%] scale-200 z-30"
/>
<AssetRender
render={renders.cubesRound}
alt=""
className="absolute top-[50%] right-[30%] w-[16%] scale-200 z-30"
/>
</div>
)
}
const SELF_INSTALL_STEPS = [
{
title: "Gebäude angeben",
description:
"Sie teilen uns die grundlegenden Informationen zum Gebäude und den Wohnungen mit.",
},
{
title: "Passende Ausstattung zusammenstellen",
description:
"Die benötigten Zähler, Kommunikationskomponenten und gegebenenfalls Rauchwarnmelder werden zusammengestellt.",
},
{
title: "Vorkonfiguriert erhalten",
description:
"Die Geräte werden bereits für Ihr Gebäude vorbereitet geliefert.",
},
{
title: "Montieren",
description:
"Sie selbst, Ihr Hausmeister oder Ihr Fachbetrieb installiert die Geräte.",
},
{
title: "GebOS übernimmt",
description:
"Nach der Inbetriebnahme laufen Datenerfassung und die gebuchten Dienstleistungen über GebOS.",
},
]
const WHY_GEBOS = [
{
title: "Kosten kontrollieren",
text: "Entscheiden Sie selbst, welche Arbeiten Sie übernehmen und welche Sie abgeben möchten.",
},
{
title: "Keine unnötige technische Komplexität",
text: "Die Hardware wird für das jeweilige Gebäude vorbereitet.",
},
{
title: "Bestehenden Handwerker nutzen",
text: "Sie benötigen keinen speziellen GebOS-Installateur.",
},
{
title: "Alles an einem Ort",
text: "UVI, Abrechnung, Geräte und weitere Gebäudedienstleistungen werden zentral verwaltet.",
},
{
title: "Weniger laufender Aufwand",
text: "Nach der Einrichtung werden Verbrauchsdaten automatisch erfasst und verarbeitet.",
},
]
const VARIANT_ROWS = [
["Planung", "gemeinsam mit GebOS", "GebOS"],
["Hardware", "GebOS", "GebOS"],
["Installation", "Kunde / eigener Fachbetrieb", "organisiert durch GebOS"],
["Softwareeinrichtung", "vorbereitet durch GebOS", "GebOS"],
["Laufender Betrieb", "GebOS", "GebOS"],
["Kosten", "möglichst niedrig", "höhere Planungssicherheit und Komfort"],
]
export default function HauseigentuemerPage() {
return (
<AudiencePage
breadcrumb="Hauseigentümer"
title={
<span className="block text-[2.25rem] text-pretty sm:text-[2.75rem]">
Messdienstleistungen für Ihr Mehrfamilienhaus. Einfach organisiert.
</span>
}
lead="UVI, Heizkostenabrechnung und Rauchwarnmelder mit vorkonfigurierter Technik selbst installieren oder als Komplettlösung beauftragen."
actions={
<Button asChild size="lg">
<Link to="/konfigurator">Preis für mein Gebäude berechnen</Link>
</Button>
}
visual={<HomeownerArt />}
features={[
{
icon: <Wrench />,
title: "Selbst installieren",
sub: "Kosten sparen, flexibel bleiben",
},
{
icon: <ShieldCheck />,
title: "Komplettlösung",
sub: "Wir kümmern uns um alles",
},
{
icon: <ReceiptText />,
title: "Transparente Preise",
sub: "Keine versteckten Kosten",
},
{
icon: <Handshake />,
title: "Bestehende Partner",
sub: "Ihre Handwerker bleiben",
},
]}
closing={
<Section className="pt-0 sm:pt-0 lg:pt-0">
<CtaBanner
icon={<Euro />}
title="Welche Lösung passt zu Ihrem Gebäude?"
description="Mit wenigen Angaben zur ersten Preisindikation oder direkt die Komplettlösung anfragen."
actions={
<>
<Button asChild variant="inverse" size="lg">
<Link to="/konfigurator">
Preis für mein Gebäude berechnen
</Link>
</Button>
<Button asChild variant="inverse" size="lg">
<Link to="/kontakt">Komplettlösung anfragen</Link>
</Button>
</>
}
/>
</Section>
}
>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Ihre Entscheidung"
title="Zwei Wege zu GebOS"
/>
<div className="mt-10 grid gap-6 md:grid-cols-2">
<Card className="relative gap-0 overflow-hidden p-7">
<AssetRender
render={renders.drillTool}
className="pointer-events-none absolute -top-2 -right-3 w-28 opacity-90"
/>
<h3 className="pr-24 text-lg font-extrabold tracking-tight text-navy">
Selbst installieren
</h3>
<p className="mt-3 text-sm leading-relaxed text-pretty text-muted-foreground">
Sie möchten Kosten niedrig halten und können die Installation
selbst oder über einen vertrauten Heizungsbauer, Hausmeister
oder anderen Fachbetrieb organisieren? GebOS liefert die
benötigte Technik passend zu Ihrem Gebäude vorkonfiguriert.
</p>
<p className="mt-3 text-sm font-bold leading-relaxed text-navy">
Sie organisieren die Montage. GebOS übernimmt den digitalen
Betrieb.
</p>
<div className="mt-6">
<Button asChild size="sm">
<Link to="/konfigurator">Preis berechnen</Link>
</Button>
</div>
</Card>
<Card className="relative gap-0 overflow-hidden p-7">
<AssetRender
render={renders.shippingBoxMeters}
className="pointer-events-none absolute -top-1 -right-4 w-32"
/>
<h3 className="pr-28 text-lg font-extrabold tracking-tight text-navy">
Komplett installieren lassen
</h3>
<p className="mt-3 text-sm leading-relaxed text-pretty text-muted-foreground">
Sie möchten sich möglichst wenig mit Planung, Beschaffung und
Installation beschäftigen? GebOS organisiert die komplette
Umsetzung für Sie. Von der Ermittlung der benötigten Geräte
über die Installation bis zum laufenden Betrieb erhalten Sie
eine durchgängige Lösung.
</p>
<div className="mt-6">
<Button asChild size="sm" variant="outline">
<Link to="/kontakt">Komplettlösung anfragen</Link>
</Button>
</div>
</Card>
</div>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Schritt für Schritt"
title="So funktioniert die Selbstinstallation"
/>
<NumberedList steps={SELF_INSTALL_STEPS} className="mt-10 max-w-2xl" />
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Ihre Vorteile"
title="Warum GebOS für Hauseigentümer?"
/>
<div className="mt-10 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{WHY_GEBOS.map((item) => (
<Card key={item.title} className="gap-0 p-6">
<h3 className="text-sm font-bold text-navy">{item.title}</h3>
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">
{item.text}
</p>
</Card>
))}
</div>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Im Vergleich"
title="Welche Variante passt zu mir?"
/>
<Card className="mt-10 gap-0 overflow-hidden p-2 sm:p-4">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[30%]" />
<TableHead>Selbst installieren</TableHead>
<TableHead>Komplettlösung</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{VARIANT_ROWS.map(([label, self, full]) => (
<TableRow key={label}>
<TableCell className="font-bold text-navy">
{label}
</TableCell>
<TableCell className="text-muted-foreground">
{self}
</TableCell>
<TableCell className="text-muted-foreground">
{full}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Card>
</Section>
</AudiencePage>
)
}
@@ -0,0 +1,348 @@
import { Link } from "react-router-dom"
import {
Ban,
Euro,
LayoutDashboard,
Package,
Timer,
TrendingUp,
Unlock,
X,
} from "lucide-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Separator } from "@/components/ui/separator"
import { Section, SectionHeading } from "@/components/gebos/section"
import { CtaBanner } from "@/components/gebos/cta-banner"
import { IconBadge } from "@/components/gebos/icon-tile"
import { NumberedList } from "@/components/gebos/process-steps"
import {
AssetRender,
renders,
vectors,
} from "@/components/gebos/site-assets"
import { AudiencePage } from "@/pages/audiences/audience-page"
const deviceExamples = [
"Wärmemengenzähler",
"Warmwasserzähler",
"Kaltwasserzähler",
"Kommunikationsinfrastruktur",
"Rauchwarnmelder",
]
const rolloutSteps = [
{
title: "Portfolio und Objekte erfassen",
description:
"Bei der Auftragserstellung werden die betreffenden Gebäude, Wohnungen und die vorhandene beziehungsweise benötigte Ausstattung erfasst.",
},
{
title: "Gerätebedarf bestimmen",
description: (
<>
Für jedes Objekt wird festgelegt, welche Geräte benötigt werden.
Beispielsweise:
<span className="mt-2 flex flex-wrap gap-1.5">
{deviceExamples.map((device) => (
<Badge key={device} variant="muted">
{device}
</Badge>
))}
</span>
</>
),
},
{
title: "GebOS bereitet den Rollout vor",
description:
"Gebäude und Wohnungen werden im System angelegt und die Hardware wird objektbezogen vorbereitet.",
},
{
title: "Installationsfertig liefern",
description:
"Die Geräte werden passend zum jeweiligen Gebäude beziehungsweise zur jeweiligen Nutzungseinheit ausgeliefert.",
},
{
title: "Bestehende Monteure installieren",
description:
"Eigene Mitarbeiter, Hausmeister oder bestehende Installationspartner können die Montage übernehmen. Eine umfangreiche Softwarekonfiguration vor Ort ist nicht erforderlich.",
},
{
title: "Bewohner einladen",
description:
"Nach der Einrichtung müssen im Wesentlichen noch die relevanten Bewohnerdaten ergänzt beziehungsweise Einladungen zum Mieterportal versendet werden.",
},
]
const noEffortItems = [
{ icon: <Ban />, title: "Keine aufwendige Gerätekonfiguration." },
{ icon: <X />, title: "Keine manuelle Anlage jedes einzelnen Gerätes." },
{
icon: <Unlock />,
title: "Keine spezielle GebOS-Zertifizierung für den Installateur.",
},
]
const portfolioStats = [
{ value: "48", label: "Gebäude" },
{ value: "384", label: "Wohnungen" },
{ value: "1.746", label: "Geräte" },
]
const statusInfos = [
"Auftrag angelegt",
"Hardware vorbereitet",
"Versendet",
"Installation begonnen",
"Installation vollständig",
"Geräte aktiv",
"Bewohner eingeladen",
"Handlungsbedarf",
]
const whyGebos = [
{
title: "Schneller Rollout",
sub: "Standardisierte Abläufe ermöglichen die parallele Umsetzung vieler Objekte.",
},
{
title: "Weniger Administration",
sub: "Gebäudedaten werden möglichst nur einmal erfasst und anschließend weiterverwendet.",
},
{
title: "Vorkonfigurierte Hardware",
sub: "Geräte werden bereits passend zu den jeweiligen Objekten vorbereitet.",
},
{
title: "Bestehende Installationspartner",
sub: "Eigene Hausmeister, technische Mitarbeiter oder externe Fachbetriebe können weiter eingesetzt werden.",
},
{
title: "Zentrale Portfolioübersicht",
sub: "Gebäude, Wohnungen und Geräte lassen sich gemeinsam betrachten.",
},
{
title: "Ein Ansprechpartner",
sub: "Technik und laufende digitale Dienstleistungen greifen ineinander.",
},
]
/** Portfolio/rollout hero per asset kit 06: building, teal bars, consumption ring. */
function PortfolioHeroArt() {
return (
<div className="relative aspect-[1.28] w-full">
<img
src={vectors.tealBars}
alt=""
className="absolute top-[22%] right-0 w-[44%]"
/>
<AssetRender
render={renders.building}
className="absolute inset-x-[8%] top-[4%]"
imgClassName="w-full"
loading="eager"
/>
<img
src={vectors.consumptionRing}
alt=""
className="absolute bottom-[3%] left-[2%] w-[28%]"
/>
</div>
)
}
export default function HausverwaltungenPage() {
return (
<AudiencePage
breadcrumb="Hausverwaltungen"
title="Für Hausverwaltungen"
tagline="Skalieren Sie Ihre Bestände einfach."
lead="Rollout über viele Gebäude mit minimalem Aufwand von der Planung bis zum laufenden Betrieb."
actions={
<>
<Button asChild size="lg">
<Link to="/konfigurator">Portfolio kalkulieren</Link>
</Button>
<Button asChild size="lg" variant="outline">
<Link to="/kontakt">Rollout besprechen</Link>
</Button>
</>
}
visual={<PortfolioHeroArt />}
features={[
{
icon: <Package />,
title: "Vorkonfigurierte Hardware",
},
{
icon: <Timer />,
title: "Wenig Aufwand vor Ort",
},
{
icon: <LayoutDashboard />,
title: "Zentrale Übersicht",
},
{
icon: <TrendingUp />,
title: "Skalierbar für wachsende Portfolios",
},
]}
closing={
<Section className="pt-0 sm:pt-0 lg:pt-0">
<CtaBanner
icon={<Euro />}
title="Wie sieht Ihr Portfolio aus?"
description="Erhalten Sie zunächst mit wenigen Angaben eine Preisindikation für mehrere Gebäude oder sprechen Sie mit uns über vorhandene Messtechnik und den geplanten Rollout."
actions={
<>
<Button asChild variant="inverse" size="lg">
<Link to="/konfigurator">Portfolio kalkulieren</Link>
</Button>
<Button asChild variant="inverse" size="lg">
<Link to="/kontakt">Rollout besprechen</Link>
</Button>
</>
}
/>
</Section>
}
>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
eyebrow="Skalierung"
title="Weniger Projektaufwand pro Gebäude"
lead="Bei einem einzelnen Gebäude sind manuelle Arbeitsschritte überschaubar. Bei dutzenden Gebäuden werden sie zum Problem. GebOS reduziert genau diese wiederkehrenden Aufgaben."
/>
<Card className="mx-auto mt-8 max-w-xl border-l-4 border-l-primary">
<CardContent className="py-6 text-center">
<p className="text-lg font-bold text-balance text-navy">
Objekte einmal erfassen. Geräte vorbereitet erhalten. Montieren.
Betreiben.
</p>
</CardContent>
</Card>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Ablauf"
title="Bestellung und Installation greifen ineinander"
/>
<NumberedList className="mt-10 max-w-2xl" steps={rolloutSteps} />
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
title="Der Monteur montiert. GebOS kümmert sich um den Rest."
lead="Die Installation soll nicht davon abhängen, dass vor Ort ein speziell geschulter GebOS-Techniker verfügbar ist."
/>
<div className="mt-10 grid gap-6 sm:grid-cols-3">
{noEffortItems.map((item, i) => (
<Card key={i}>
<CardContent className="flex flex-col items-center gap-4 py-6 text-center">
<IconBadge variant="soft" shape="squircle" size="lg">
{item.icon}
</IconBadge>
<p className="text-sm font-bold text-balance text-navy">
{item.title}
</p>
</CardContent>
</Card>
))}
</div>
<p className="mt-8 text-center text-base text-muted-foreground">
Damit können bestehende Installationsstrukturen weiter genutzt
werden.
</p>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
eyebrow="Übersicht"
title="Rollout zentral überblicken"
lead="Bei größeren Portfolios reicht es nicht, Geräte lediglich zu installieren. Die Verwaltung muss erkennen können, wo der Rollout steht und wo Handlungsbedarf besteht."
/>
<Card className="mx-auto mt-10 max-w-3xl shadow-card-lg">
<CardContent className="py-6">
<div className="flex flex-wrap items-start justify-between gap-6">
<div className="min-w-0 flex-1">
<p className="text-xs font-bold tracking-[0.14em] text-primary uppercase">
Beispiel
</p>
<h3 className="mt-1 text-xl font-extrabold tracking-tight text-navy">
Portfolio
</h3>
<div className="mt-5 flex flex-wrap gap-x-10 gap-y-4">
{portfolioStats.map((stat) => (
<div key={stat.label}>
<div className="text-3xl font-extrabold tracking-tight text-navy">
{stat.value}
</div>
<div className="text-xs font-medium text-muted-foreground">
{stat.label}
</div>
</div>
))}
</div>
<div className="mt-6 flex flex-wrap gap-2">
<Badge>43 Gebäude aktiv</Badge>
<Badge variant="muted">3 in Installation</Badge>
<Badge variant="destructive">2 mit Handlungsbedarf</Badge>
</div>
</div>
<img
src={vectors.consumptionRing}
alt=""
className="w-36 shrink-0 max-sm:hidden"
/>
</div>
<Separator className="my-6" />
<p className="text-xs font-bold text-muted-foreground">
Mögliche Statusinformationen
</p>
<div className="mt-2.5 flex flex-wrap gap-1.5">
{statusInfos.map((status) => (
<Badge key={status} variant="outline">
{status}
</Badge>
))}
</div>
</CardContent>
</Card>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
title="Warum GebOS für Hausverwaltungen?"
/>
<div className="mt-10 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{whyGebos.map((item) => (
<Card key={item.title}>
<CardContent className="py-5">
<h3 className="text-sm font-bold text-navy">{item.title}</h3>
<p className="mt-1.5 text-sm leading-relaxed text-muted-foreground">
{item.sub}
</p>
</CardContent>
</Card>
))}
</div>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
title="Vom kleinen Bestand bis zum wachsenden Portfolio"
lead="GebOS soll nicht verlangen, dass eine Hausverwaltung zunächst eine eigene Messdienst-Infrastruktur aufbaut. Neue Gebäude können schrittweise ergänzt und nach demselben standardisierten Prozess ausgerollt werden."
/>
</Section>
</AudiencePage>
)
}
@@ -0,0 +1,327 @@
import { Link } from "react-router-dom"
import {
CircleCheck,
GraduationCap,
Package,
PackageX,
Unlock,
Users,
Wrench,
} from "lucide-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { Checklist } from "@/components/gebos/checklist"
import { IconBadge } from "@/components/gebos/icon-tile"
import { ProcessSteps } from "@/components/gebos/process-steps"
import { Section, SectionHeading } from "@/components/gebos/section"
import { AssetRender, renders, vectors } from "@/components/gebos/site-assets"
import { AudiencePage, AudienceClosing } from "@/pages/audiences/audience-page"
const KUNDEN_BEDARFE = [
"UVI",
"Heizkostenabrechnung",
"fernauslesbare Messtechnik",
"Rauchwarnmelder",
]
const KEINE_HUERDEN = [
{
icon: <Unlock />,
title: "Keine verpflichtende Partnerschaft",
},
{
icon: <PackageX />,
title: "Keine Mindestabnahme",
},
{
icon: <GraduationCap />,
title: "Keine verpflichtende GebOS-Vertriebsschulung",
},
{
icon: <Wrench />,
title: "Keine komplizierte Softwareeinrichtung auf der Baustelle",
},
]
const GEBOS_BEREITET_VOR = [
"Gebäudestruktur",
"Wohnungen beziehungsweise Nutzungseinheiten",
"Gerätezuordnung",
"benötigte Hardware",
"Kommunikationsinfrastruktur",
"Softwarestruktur",
]
const SIE_UEBERNEHMEN = [
"fachgerechte Montage",
"gegebenenfalls Austausch vorhandener Geräte",
"Einbau der vorgesehenen Messtechnik",
"Abschluss der Installation",
]
export default function InstallateurePage() {
return (
<AudiencePage
breadcrumb="Installateure & Heizungsbauer"
title={
<>
Für Installateure &amp;
<br />
Heizungsbauer
</>
}
tagline="Bestellen. Montieren. Fertig."
lead="GebOS für Ihre Kunden installieren ohne Partnerprogramm, verpflichtende Zertifizierung oder aufwendige Softwarekonfiguration."
actions={
<Button asChild size="lg">
<Link to="/konfigurator">Gebäude für meinen Kunden konfigurieren</Link>
</Button>
}
visual={
<div className="relative aspect-[1.28] w-full">
<img
src={vectors.checkOrb}
alt=""
className="absolute top-[6%] right-[8%] w-[16%]"
/>
<AssetRender
render={renders.heatMeter}
className="absolute top-[30%] left-[2%] w-[38%]"
imgClassName="w-full"
/>
<AssetRender
render={renders.gateway}
className="absolute top-[24%] right-[16%] w-[46%]"
imgClassName="w-full"
/>
<img
src={vectors.glassCubes}
alt=""
className="absolute right-[1%] bottom-[10%] w-[26%]"
/>
</div>
}
features={[
{
icon: <Unlock />,
title: "Keine Partnerpflichten",
sub: "Keine Mindestmengen",
},
{
icon: <Package />,
title: "Vorkonfigurierte Hardware",
},
{
icon: <Wrench />,
title: "Einfache Installation",
sub: "Keine Softwarekonfiguration",
},
{
icon: <Users />,
title: "Ihre Kunden",
sub: "Bleiben Ihre Kunden",
},
]}
closing={
<AudienceClosing
title="GebOS bei einem Kunden einsetzen?"
lead="Stellen Sie mit wenigen Angaben zunächst die ungefähre Ausstattung und den Preis für das Gebäude zusammen."
actions={
<Button asChild size="lg">
<Link to="/konfigurator">
Gebäude für meinen Kunden konfigurieren
</Link>
</Button>
}
/>
}
>
{/* 1. Ihr Kunde braucht eine Messdienstlösung? */}
<Section className="pt-4 sm:pt-6 lg:pt-8">
<SectionHeading
eyebrow="Ausgangslage"
title="Ihr Kunde braucht eine Messdienstlösung?"
lead="Sie betreuen ein Mehrfamilienhaus und Ihr Kunde benötigt beispielsweise:"
/>
<div className="mt-6 flex flex-wrap gap-2.5">
{KUNDEN_BEDARFE.map((bedarf) => (
<Badge
key={bedarf}
variant="outline"
className="px-4 py-1.5 text-sm font-semibold text-navy"
>
<CircleCheck className="text-primary" />
{bedarf}
</Badge>
))}
</div>
<p className="mt-6 max-w-2xl text-base leading-relaxed text-muted-foreground">
Dann können Sie GebOS einfach für das betreffende Gebäude einsetzen.{" "}
<strong className="font-semibold text-navy">
Sie müssen dafür nicht zunächst Teil eines Partnerprogramms werden.
</strong>
</p>
</Section>
{/* 2. So einfach soll die Installation sein */}
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Ablauf"
title="So einfach soll die Installation sein"
align="center"
/>
<ProcessSteps
className="mt-12"
steps={[
{
media: (
<AssetRender
render={renders.building}
className="flex h-16 items-center justify-center"
imgClassName="h-16 w-auto"
/>
),
title: "Gebäude erfassen",
description:
"Die benötigte Ausstattung wird für das konkrete Objekt zusammengestellt.",
},
{
media: (
<img
src={vectors.packageBox}
alt=""
className="h-16 w-16 object-contain"
/>
),
title: "Geräte bestellen",
description:
"GebOS liefert die zum Gebäude passenden Geräte.",
},
{
media: (
<AssetRender
render={renders.gateway}
className="flex h-16 items-center justify-center"
imgClassName="h-16 w-auto"
/>
),
title: "Vorkonfiguriert erhalten",
description:
"Die Hardware wird bereits objektbezogen vorbereitet.",
},
{
media: (
<AssetRender
render={renders.heatMeter}
className="flex h-16 items-center justify-center"
imgClassName="h-16 w-auto"
/>
),
title: "Montieren",
description: "Sie übernehmen die fachgerechte Installation.",
},
{
media: (
<img
src={vectors.checkOrb}
alt=""
className="h-16 w-16 object-contain"
/>
),
title: "Fertig",
description:
"Die digitale Einrichtung und der laufende Betrieb werden von GebOS übernommen.",
},
]}
/>
</Section>
{/* 3. Kein klassisches Partnerprogramm erforderlich */}
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Ohne Einstiegshürden"
title="Kein klassisches Partnerprogramm erforderlich"
lead="Für die normale Installation von GebOS sollen keine unnötigen Einstiegshürden entstehen."
align="center"
/>
<div className="mt-10 grid gap-5 sm:grid-cols-2 lg:grid-cols-4">
{KEINE_HUERDEN.map((item, i) => (
<Card key={i} className="items-start gap-4 p-6">
<IconBadge variant="soft" shape="squircle">
{item.icon}
</IconBadge>
<p className="text-sm font-bold leading-snug text-navy">
{item.title}
</p>
</Card>
))}
</div>
<p className="mx-auto mt-8 max-w-2xl text-center text-base leading-relaxed text-muted-foreground">
<strong className="font-semibold text-navy">
Der Fachbetrieb bleibt der Fachbetrieb des Kunden.
</strong>{" "}
GebOS stellt das Produkt und die digitale Infrastruktur bereit.
</p>
</Section>
{/* 4. Sie können bei Ihren bestehenden Kunden bleiben */}
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
title="Sie können bei Ihren bestehenden Kunden bleiben"
lead={
<>
GebOS ist besonders interessant, wenn ein Kunde Sie ohnehin mit
Arbeiten an Heizungs-, Wasser- oder Gebäudetechnik beauftragt und
zusätzlich eine Lösung für Messdienstleistungen benötigt. Sie
können die Installation übernehmen, ohne selbst einen
vollständigen Messdienst aufbauen zu müssen.
</>
}
/>
</Section>
{/* 5. Was GebOS vorbereitet / Was Sie übernehmen */}
<Section className="pt-0 sm:pt-0 lg:pt-0">
<div className="grid gap-6 lg:grid-cols-2">
<Card className="gap-0 p-6 sm:p-8">
<h3 className="text-xl font-extrabold tracking-tight text-navy">
Was GebOS vorbereitet
</h3>
<p className="mt-1 text-sm text-muted-foreground">Je nach Auftrag:</p>
<Checklist className="mt-5" items={GEBOS_BEREITET_VOR} />
<p className="mt-5 text-sm leading-relaxed text-muted-foreground">
Damit soll vor Ort möglichst wenig zusätzliche digitale Arbeit
entstehen.
</p>
</Card>
<Card className="gap-0 p-6 sm:p-8">
<h3 className="text-xl font-extrabold tracking-tight text-navy">
Was Sie übernehmen
</h3>
<p className="mt-1 text-sm text-muted-foreground">
Das Handwerk bleibt bei Ihnen:
</p>
<Checklist className="mt-5" items={SIE_UEBERNEHMEN} />
</Card>
</div>
</Section>
{/* 6. Und wenn Sie regelmäßig GebOS installieren? */}
<Section className="pt-0 pb-10 sm:pt-0 sm:pb-12 lg:pt-0 lg:pb-14">
<div className="mx-auto max-w-2xl text-center">
<h2 className="text-2xl font-extrabold tracking-tight text-balance text-navy sm:text-3xl">
Und wenn Sie regelmäßig GebOS installieren?
</h2>
<p className="mt-4 text-base leading-relaxed text-muted-foreground">
Auch dann soll der Einstieg freiwillig bleiben. Für Fachbetriebe mit
größerem Volumen können später zusätzliche Konditionen oder
Leistungen angeboten werden. Das normale Installieren von GebOS
bleibt davon unabhängig.
</p>
</div>
</Section>
</AudiencePage>
)
}
@@ -0,0 +1,271 @@
import { Link } from "react-router-dom"
import { ArrowDown, Code2, Layers, ShieldCheck, Tag } from "lucide-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Section, SectionHeading } from "@/components/gebos/section"
import { Checklist } from "@/components/gebos/checklist"
import {
AssetRender,
renders,
vectors,
} from "@/components/gebos/site-assets"
import { AudiencePage, AudienceClosing } from "@/pages/audiences/audience-page"
const platformRequirements = [
"kompatible Messtechnik",
"Kommunikationsinfrastruktur",
"Gateways",
"sichere Datenerfassung",
"Geräteverwaltung",
"Monitoring",
"Verbrauchsdatenverarbeitung",
"Nutzerportale",
"Schnittstellen",
"laufender technischer Betrieb",
]
const whiteLabelItems = [
"eigenes Branding",
"eigene Kundenbeziehung",
"mandantenfähige Verwaltung",
"Endkundenportale",
"APIs und Datenexporte",
"Geräteverwaltung",
"technischer Support",
]
const platformCapabilities = [
{
title: "Gerätekompatibilität",
sub: "Einbindung unterschiedlicher Zähler- und Gerätetypen auf Basis geeigneter Standards.",
},
{
title: "Gateway-Infrastruktur",
sub: "Zentrale Erfassung und sichere Übertragung der Gerätedaten.",
},
{
title: "Gerätemanagement",
sub: "Verwaltung großer Gerätebestände über Gebäude und Kunden hinweg.",
},
{
title: "Monitoring",
sub: "Probleme und Ausfälle erkennen, bevor daraus manueller Aufwand beim Kunden entsteht.",
},
{
title: "APIs und Integrationen",
sub: "Anbindung an eigene Systeme und bestehende Geschäftsprozesse.",
},
{
title: "Mandantenfähigkeit",
sub: "Kunden und Bestände getrennt innerhalb einer gemeinsamen Plattform verwalten.",
},
{
title: "White Label",
sub: "GebOS-Infrastruktur unter der Marke des Messdienstleisters einsetzen.",
},
]
const businessComponents = [
"Einkaufspreise für Hardware",
"Plattformgebühren",
"Mengenstaffeln",
"wiederkehrende Gebühren",
"White-Label-Konditionen",
"Support- und Servicelevel",
"mögliche Mindestmengen",
]
const stackFlow = ["Ihre Kunden", "Ihr Messdienst", "GebOS Plattform"]
/** Platform hero per asset kit 07: laptop dashboard, glass cubes, cloud support. */
function PlatformHeroArt() {
return (
<div className="relative flex aspect-[1.45] w-full items-center">
<img
src={vectors.cloudSupport}
alt=""
className="absolute top-0 right-0 w-[26%]"
/>
<AssetRender
render={renders.laptopDashboard}
className="mx-auto w-full"
imgClassName="w-full"
loading="eager"
/>
<img
src={vectors.glassCubes}
alt=""
className="absolute bottom-[2%] left-0 w-[24%]"
/>
</div>
)
}
export default function MessdienstleisterPage() {
return (
<AudiencePage
breadcrumb="Messdienstleister"
title="Für Messdienstleister"
tagline="Ihre Services. Unsere Plattform."
lead="Nutzen Sie GebOS als technische Grundlage für Ihren eigenen Messdienst skalierbar und zuverlässig."
actions={
<>
<Button asChild size="lg">
<Link to="/kontakt">Plattform kennenlernen</Link>
</Button>
<Button asChild size="lg" variant="outline">
<Link to="/kontakt">Konditionen anfragen</Link>
</Button>
</>
}
visual={<PlatformHeroArt />}
features={[
{
icon: <Tag />,
title: "White Label",
sub: "Ihr Branding, Ihre Kunden",
},
{
icon: <Code2 />,
title: "Offene APIs",
sub: "Einfach integrieren",
},
{
icon: <Layers />,
title: "Skalierbare Plattform",
sub: "Für jedes Geschäftsmodell",
},
{
icon: <ShieldCheck />,
title: "Zuverlässiger Betrieb",
sub: "Sicher und performant",
},
]}
closing={
<AudienceClosing
title="Möchten Sie GebOS für Ihren Messdienst einsetzen?"
lead="Wir zeigen Ihnen Plattform, technische Möglichkeiten und mögliche Geschäftsmodelle."
actions={
<>
<Button asChild size="lg">
<Link to="/kontakt">Plattform kennenlernen</Link>
</Button>
<Button asChild size="lg" variant="outline">
<Link to="/kontakt">Konditionen anfragen</Link>
</Button>
</>
}
/>
}
>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Infrastruktur"
title="Messdienstleistungen anbieten, ohne die gesamte Plattform selbst zu entwickeln"
lead="Moderne Messdienstleistungen benötigen mehr als einzelne Zähler. Erforderlich sind unter anderem:"
/>
<div className="mt-8 grid max-w-3xl gap-x-10 gap-y-2.5 sm:grid-cols-2">
<Checklist items={platformRequirements.slice(0, 5)} />
<Checklist items={platformRequirements.slice(5)} />
</div>
<p className="mt-8 text-base font-bold text-navy">
GebOS stellt diese Infrastruktur als Plattform bereit.
</p>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
title="Konzentrieren Sie sich auf Ihre Kunden"
lead="Der Messdienstleister betreut seine Kunden und verkauft seine Dienstleistungen. GebOS stellt die technische Infrastruktur im Hintergrund bereit."
/>
<Card className="mx-auto mt-10 max-w-md">
<CardContent className="flex flex-col items-center gap-2.5 py-8">
{stackFlow.map((label) => (
<div
key={label}
className="flex flex-col items-center gap-2.5"
>
<div className="rounded-full border border-border bg-card px-6 py-2.5 text-sm font-bold text-navy shadow-pill">
{label}
</div>
<ArrowDown className="size-4 text-primary" />
</div>
))}
<div className="rounded-full bg-brand-gradient px-6 py-2.5 text-center text-sm font-bold text-white shadow-band">
Hardware · Datenerfassung · Software · Betrieb
</div>
</CardContent>
</Card>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
eyebrow="Ihre Marke"
title="White Label"
lead="GebOS kann als technische Grundlage für Dienstleistungen unter Ihrer eigenen Marke eingesetzt werden. Je nach Geschäftsmodell können unter anderem relevant sein:"
/>
<div className="mt-8 grid max-w-3xl gap-x-10 gap-y-2.5 sm:grid-cols-2">
<Checklist items={whiteLabelItems.slice(0, 4)} />
<Checklist items={whiteLabelItems.slice(4)} />
</div>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
eyebrow="Technik"
title="Technische Plattform"
lead="Für Messdienstleister steht die technische Leistungsfähigkeit deutlich stärker im Vordergrund."
/>
<div className="mt-10 grid gap-5 sm:grid-cols-2 lg:grid-cols-4">
{platformCapabilities.map((item) => (
<Card key={item.title}>
<CardContent className="py-5">
<h3 className="text-sm font-bold text-navy">{item.title}</h3>
<p className="mt-1.5 text-sm leading-relaxed text-muted-foreground">
{item.sub}
</p>
</CardContent>
</Card>
))}
</div>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
eyebrow="Konditionen"
title="Das Geschäftsmodell muss funktionieren"
lead="Eine Plattform für Messdienstleister ist nur interessant, wenn auch der wirtschaftliche Rahmen stimmt. Deshalb werden kommerzielle Konditionen individuell beziehungsweise mengenabhängig vereinbart mit anderen Geschäftsmodellen, Mengenstaffeln und gegebenenfalls White-Label-Konditionen als im öffentlichen Preiskonfigurator."
/>
<div className="mx-auto mt-8 max-w-2xl text-center">
<p className="text-xs font-bold text-muted-foreground">
Mögliche Bestandteile
</p>
<div className="mt-2.5 flex flex-wrap justify-center gap-1.5">
{businessComponents.map((component) => (
<Badge key={component} variant="outline">
{component}
</Badge>
))}
</div>
<p className="mt-6 text-sm text-muted-foreground italic">
Die konkreten Konditionen werden nicht öffentlich auf der Website
dargestellt.
</p>
</div>
</Section>
<Section className="pt-0 sm:pt-0 lg:pt-0">
<SectionHeading
align="center"
title="Gemeinsam skalieren"
lead="GebOS soll insbesondere Messdienstleistern ermöglichen, neue digitale Dienstleistungen anzubieten, ohne dafür eine vollständige eigene Hardware- und Softwareentwicklung aufbauen zu müssen. Der Messdienstleister behält dabei seine Kundenbeziehung und sein eigenes Geschäftsmodell."
/>
</Section>
</AudiencePage>
)
}