save
This commit is contained in:
@@ -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 5–8):
|
||||
* 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 &
|
||||
<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>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
import * as React from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import { ArrowRight, Euro, Plus, X } from "lucide-react"
|
||||
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Checkbox } from "@/components/ui/checkbox"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { Checklist } from "@/components/gebos/checklist"
|
||||
import { DonutIllustration } from "@/components/gebos/illustrations"
|
||||
import { IconBadge } from "@/components/gebos/icon-tile"
|
||||
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||
import { icons, vectors } from "@/components/gebos/site-assets"
|
||||
|
||||
type Heat = "heizkoerper" | "fussbodenheizung" | "gemischt" | "unbekannt"
|
||||
|
||||
type Building = {
|
||||
id: number
|
||||
adresse: string
|
||||
heat: Heat
|
||||
wohnungen: number
|
||||
zimmer: number
|
||||
}
|
||||
|
||||
const HEAT_OPTIONS: { value: Heat; label: string }[] = [
|
||||
{ value: "heizkoerper", label: "Heizkörper" },
|
||||
{ value: "fussbodenheizung", label: "Fußbodenheizung" },
|
||||
{ value: "gemischt", label: "Gemischt" },
|
||||
{ value: "unbekannt", label: "Weiß ich nicht" },
|
||||
]
|
||||
|
||||
const INITIAL_BUILDINGS: Building[] = [
|
||||
{ id: 1, adresse: "", heat: "heizkoerper", wohnungen: 12, zimmer: 3 },
|
||||
{ id: 2, adresse: "", heat: "heizkoerper", wohnungen: 8, zimmer: 3 },
|
||||
{ id: 3, adresse: "", heat: "heizkoerper", wohnungen: 6, zimmer: 3 },
|
||||
]
|
||||
|
||||
const UVI_MONTHLY = 10.5
|
||||
const INSPECTION_MONTHLY = 2.2
|
||||
const RWM_ONE_TIME = 42
|
||||
|
||||
function formatEuro(value: number) {
|
||||
return value.toLocaleString("de-DE", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})
|
||||
}
|
||||
|
||||
function StepCard({
|
||||
step,
|
||||
title,
|
||||
children,
|
||||
}: {
|
||||
step: number
|
||||
title: string
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<Card className="gap-0 p-6 sm:p-7">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-sm font-extrabold text-primary-foreground">
|
||||
{step}
|
||||
</span>
|
||||
<h3 className="text-lg font-extrabold tracking-tight text-navy">
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="mt-5">{children}</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default function ConfiguratorPage() {
|
||||
const [uvi, setUvi] = React.useState(true)
|
||||
const [rwm, setRwm] = React.useState(true)
|
||||
const [buildings, setBuildings] = React.useState<Building[]>(INITIAL_BUILDINGS)
|
||||
const [email, setEmail] = React.useState("")
|
||||
const nextId = React.useRef(INITIAL_BUILDINGS.length + 1)
|
||||
|
||||
const updateBuilding = (id: number, patch: Partial<Building>) => {
|
||||
setBuildings((prev) => prev.map((b) => (b.id === id ? { ...b, ...patch } : b)))
|
||||
}
|
||||
|
||||
const addBuilding = () => {
|
||||
setBuildings((prev) => [
|
||||
...prev,
|
||||
{ id: nextId.current++, adresse: "", heat: "heizkoerper", wohnungen: 8, zimmer: 3 },
|
||||
])
|
||||
}
|
||||
|
||||
const removeBuilding = (id: number) => {
|
||||
setBuildings((prev) => (prev.length > 1 ? prev.filter((b) => b.id !== id) : prev))
|
||||
}
|
||||
|
||||
const totalBuildings = buildings.length
|
||||
const totalUnits = buildings.reduce((sum, b) => sum + (b.wohnungen || 0), 0)
|
||||
const sensors = buildings.reduce(
|
||||
(sum, b) => sum + Math.round((b.wohnungen || 0) * (b.zimmer || 0) * 0.92),
|
||||
0
|
||||
)
|
||||
const smokeDetectors = buildings.reduce(
|
||||
(sum, b) => sum + Math.round((b.wohnungen || 0) * ((b.zimmer || 0) + 0.7)),
|
||||
0
|
||||
)
|
||||
const monthly =
|
||||
(uvi ? UVI_MONTHLY : 0) + (uvi || rwm ? INSPECTION_MONTHLY : 0)
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Section className="pt-6 sm:pt-7 lg:pt-8">
|
||||
<div className="relative">
|
||||
<PageBreadcrumb
|
||||
className="mb-4"
|
||||
items={[
|
||||
{ label: "Startseite", to: "/" },
|
||||
{ label: "Konfigurator" },
|
||||
]}
|
||||
/>
|
||||
<SectionHeading
|
||||
title="Konfigurator"
|
||||
lead="In 4 Schritten zur Preisindikation."
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute -top-6 right-0 hidden items-end lg:flex"
|
||||
>
|
||||
<img src={vectors.euroOrb} alt="" className="w-40" />
|
||||
<img
|
||||
src={vectors.consumptionRing}
|
||||
alt=""
|
||||
className="-mb-3 -ml-6 w-44"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 grid items-start gap-8 lg:grid-cols-[minmax(0,1fr)_380px]">
|
||||
{/* Left column: steps */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<StepCard step={1} title="Leistungen wählen">
|
||||
<div className="flex flex-col gap-4">
|
||||
<label className="flex cursor-pointer items-start gap-3">
|
||||
<Checkbox
|
||||
checked={uvi}
|
||||
onCheckedChange={(v) => setUvi(v === true)}
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<span>
|
||||
<span className="block text-sm font-bold text-navy">UVI</span>
|
||||
<span className="block text-sm text-muted-foreground">
|
||||
Unterjährige Verbrauchsinformation inklusive Messtechnik
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<label className="flex cursor-pointer items-start gap-3">
|
||||
<Checkbox
|
||||
checked={rwm}
|
||||
onCheckedChange={(v) => setRwm(v === true)}
|
||||
className="mt-0.5"
|
||||
/>
|
||||
<span>
|
||||
<span className="block text-sm font-bold text-navy">
|
||||
Rauchwarnmelder
|
||||
</span>
|
||||
<span className="block text-sm text-muted-foreground">
|
||||
Rauchwarnmelder inklusive digitaler Dienstleistungen
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</StepCard>
|
||||
|
||||
<StepCard step={2} title="Gebäude angeben">
|
||||
<div className="flex flex-col gap-5">
|
||||
{buildings.map((b, i) => (
|
||||
<div
|
||||
key={b.id}
|
||||
className="rounded-xl border border-border bg-brand-50/40 p-4 sm:p-5"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-sm font-bold text-navy">
|
||||
Gebäude {i + 1}
|
||||
</div>
|
||||
{buildings.length > 1 ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="size-7 text-muted-foreground"
|
||||
aria-label={`Gebäude ${i + 1} entfernen`}
|
||||
onClick={() => removeBuilding(b.id)}
|
||||
>
|
||||
<X />
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mt-3 grid gap-3 sm:grid-cols-2">
|
||||
<div className="flex flex-col gap-1.5 sm:col-span-2">
|
||||
<Label htmlFor={`adresse-${b.id}`}>
|
||||
Adresse{" "}
|
||||
<span className="font-normal text-muted-foreground">
|
||||
(optional)
|
||||
</span>
|
||||
</Label>
|
||||
<Input
|
||||
id={`adresse-${b.id}`}
|
||||
placeholder="Venloer Straße 123, 50823 Köln"
|
||||
value={b.adresse}
|
||||
onChange={(e) =>
|
||||
updateBuilding(b.id, { adresse: e.target.value })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5 sm:col-span-2">
|
||||
<Label htmlFor={`heat-${b.id}`}>Wärmeverteilung</Label>
|
||||
<Select
|
||||
value={b.heat}
|
||||
onValueChange={(v) =>
|
||||
updateBuilding(b.id, { heat: v as Heat })
|
||||
}
|
||||
>
|
||||
<SelectTrigger id={`heat-${b.id}`} className="w-full">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{HEAT_OPTIONS.map((opt) => (
|
||||
<SelectItem key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<Label htmlFor={`wohnungen-${b.id}`}>Wohnungen</Label>
|
||||
<Input
|
||||
id={`wohnungen-${b.id}`}
|
||||
type="number"
|
||||
min={1}
|
||||
value={b.wohnungen}
|
||||
onChange={(e) =>
|
||||
updateBuilding(b.id, {
|
||||
wohnungen: Math.max(
|
||||
0,
|
||||
Math.round(Number(e.target.value) || 0)
|
||||
),
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<Label htmlFor={`zimmer-${b.id}`}>Ø Zimmer</Label>
|
||||
<Input
|
||||
id={`zimmer-${b.id}`}
|
||||
type="number"
|
||||
min={1}
|
||||
value={b.zimmer}
|
||||
onChange={(e) =>
|
||||
updateBuilding(b.id, {
|
||||
zimmer: Math.max(0, Number(e.target.value) || 0),
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="self-start"
|
||||
onClick={addBuilding}
|
||||
>
|
||||
<Plus /> Gebäude hinzufügen
|
||||
</Button>
|
||||
</div>
|
||||
</StepCard>
|
||||
|
||||
<StepCard step={3} title="Preis sehen">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Sofortige erste Preisindikation.
|
||||
</p>
|
||||
<Accordion type="single" collapsible className="mt-3">
|
||||
<AccordionItem value="annahmen" className="border-b-0">
|
||||
<AccordionTrigger className="text-sm font-bold text-navy">
|
||||
Wie wurde dieser Preis berechnet?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="text-sm text-muted-foreground">
|
||||
<p>
|
||||
Für diese Schätzung gehen wir aufgrund Ihrer Angaben von
|
||||
ungefähr{" "}
|
||||
<strong className="text-navy">
|
||||
{sensors} Heizsensoren und {smokeDetectors}{" "}
|
||||
Rauchwarnmeldern
|
||||
</strong>{" "}
|
||||
aus.
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
Bei Gebäuden mit durchschnittlich drei Zimmern verwenden
|
||||
wir eine typische Geräteausstattung als
|
||||
Berechnungsgrundlage.
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
Die endgültige Anzahl wird bei der detaillierten
|
||||
Konfiguration der Wohnungen bestimmt und ersetzt diese
|
||||
Schätzwerte.
|
||||
</p>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</StepCard>
|
||||
|
||||
<StepCard step={4} title="Konfiguration speichern">
|
||||
<form
|
||||
onSubmit={(e) => e.preventDefault()}
|
||||
className="flex flex-col gap-3"
|
||||
>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<Label htmlFor="config-email">E-Mail-Adresse</Label>
|
||||
<Input
|
||||
id="config-email"
|
||||
type="email"
|
||||
placeholder="name@unternehmen.de"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<Button type="submit" className="self-start">
|
||||
Konfiguration speichern & fortsetzen
|
||||
</Button>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Sie erhalten einen persönlichen Link (gebos.de/konfiguration/…)
|
||||
zu Ihrer Konfiguration – sofort weitermachen, später
|
||||
zurückkehren oder den Link intern weitergeben.
|
||||
</p>
|
||||
</form>
|
||||
</StepCard>
|
||||
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Button type="button">Jetzt Preis berechnen</Button>
|
||||
<Button variant="outline" asChild>
|
||||
<Link to="/so-funktionierts">So funktioniert der Konfigurator</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right column: sticky summary */}
|
||||
<div className="lg:sticky lg:top-24">
|
||||
<Card className="gap-0 p-6 shadow-card-lg sm:p-7">
|
||||
<h3 className="text-base font-extrabold tracking-tight text-navy">
|
||||
Ihre vorläufige Konfiguration
|
||||
</h3>
|
||||
<div className="mt-4 flex flex-col gap-1">
|
||||
<div className="text-2xl font-extrabold tracking-tight text-navy">
|
||||
{totalBuildings}{" "}
|
||||
{totalBuildings === 1 ? "Gebäude" : "Gebäude"}
|
||||
</div>
|
||||
<div className="text-2xl font-extrabold tracking-tight text-navy">
|
||||
{totalUnits} {totalUnits === 1 ? "Wohnung" : "Wohnungen"}
|
||||
</div>
|
||||
</div>
|
||||
{uvi || rwm ? (
|
||||
<>
|
||||
<Separator className="my-4" />
|
||||
<p className="text-xs font-bold tracking-[0.14em] text-muted-foreground uppercase">
|
||||
Voraussichtlich benötigt
|
||||
</p>
|
||||
<ul className="mt-2 flex flex-col gap-1.5 text-sm text-navy">
|
||||
{uvi ? (
|
||||
<li className="font-semibold">
|
||||
ca. {sensors} Heizsensoren
|
||||
</li>
|
||||
) : null}
|
||||
{rwm ? (
|
||||
<li className="font-semibold">
|
||||
ca. {smokeDetectors} Rauchwarnmelder
|
||||
</li>
|
||||
) : null}
|
||||
</ul>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<div className="mt-5 rounded-xl bg-brand-gradient p-4 text-white shadow-band">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div className="text-2xl font-extrabold tracking-tight">
|
||||
ca. {formatEuro(monthly)}{"\u00A0"}€
|
||||
</div>
|
||||
<div className="text-sm text-white/80">
|
||||
je Wohnung / Monat
|
||||
</div>
|
||||
</div>
|
||||
<IconBadge variant="glass" size="lg">
|
||||
<Euro />
|
||||
</IconBadge>
|
||||
</div>
|
||||
{rwm ? (
|
||||
<div className="mt-3 border-t border-white/20 pt-2 text-xs text-white/80">
|
||||
+ {formatEuro(RWM_ONE_TIME)}{"\u00A0"}€ je Wohnung einmalig
|
||||
(RWM-Hardware)
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="mt-5 flex items-start gap-4">
|
||||
<DonutIllustration className="w-16 shrink-0" />
|
||||
<p className="text-xs leading-relaxed text-muted-foreground">
|
||||
Die erste Berechnung ist eine unverbindliche Preisindikation.
|
||||
Der genaue Preis ergibt sich aus der vollständigen
|
||||
Objektkonfiguration.
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Was ist in der Schätzung enthalten? */}
|
||||
<Section className="pt-0 sm:pt-0 lg:pt-0">
|
||||
<SectionHeading
|
||||
title="Was ist in der Schätzung enthalten?"
|
||||
lead="Je nach gewähltem Paket beispielsweise:"
|
||||
/>
|
||||
<div className="mt-8 grid gap-6 lg:grid-cols-2">
|
||||
<Card
|
||||
className={
|
||||
"gap-0 p-6 transition-opacity sm:p-8" +
|
||||
(uvi ? "" : " opacity-50")
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<img src={icons.uvi} alt="" className="size-14" />
|
||||
<h3 className="text-xl font-extrabold tracking-tight text-navy">
|
||||
UVI
|
||||
</h3>
|
||||
</div>
|
||||
<Checklist
|
||||
className="mt-5"
|
||||
items={[
|
||||
"geschätzte benötigte Messtechnik",
|
||||
"GebOS Plattform",
|
||||
"Datenerfassung",
|
||||
"Unterjährige Verbrauchsinformation",
|
||||
"laufender digitaler Betrieb",
|
||||
]}
|
||||
/>
|
||||
</Card>
|
||||
<Card
|
||||
className={
|
||||
"gap-0 p-6 transition-opacity sm:p-8" +
|
||||
(rwm ? "" : " opacity-50")
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<img src={icons.smokeAlarm} alt="" className="size-14" />
|
||||
<h3 className="text-xl font-extrabold tracking-tight text-navy">
|
||||
Rauchwarnmelder
|
||||
</h3>
|
||||
</div>
|
||||
<Checklist
|
||||
className="mt-5"
|
||||
items={[
|
||||
"geschätzte Anzahl Rauchwarnmelder",
|
||||
"Verwaltung der Geräte",
|
||||
"gebuchte digitale Dienstleistungen",
|
||||
]}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Stufe 2 – So geht es weiter */}
|
||||
<Section className="pt-0 pb-16 sm:pt-0 sm:pb-20 lg:pt-0 lg:pb-24">
|
||||
<SectionHeading
|
||||
eyebrow="So geht es weiter"
|
||||
title="Erst schätzen. Dann genau konfigurieren."
|
||||
lead="Der vollständige Konfigurator beginnt nicht wieder bei null. Die bereits erfassten Informationen werden übernommen – und die bisherigen Annahmen schrittweise durch echte Daten ersetzt."
|
||||
/>
|
||||
<div className="mt-8 flex flex-col gap-3">
|
||||
<div className="flex flex-wrap items-center gap-2.5">
|
||||
<Badge variant="muted" className="px-3.5 py-1.5 text-sm">
|
||||
Geschätzt: 72 Heizsensoren
|
||||
</Badge>
|
||||
<ArrowRight className="size-4 text-primary" aria-hidden="true" />
|
||||
<Badge className="px-3.5 py-1.5 text-sm">
|
||||
Konfiguriert: 68 Heizsensoren
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2.5">
|
||||
<Badge variant="muted" className="px-3.5 py-1.5 text-sm">
|
||||
Geschätzt: 96 Rauchwarnmelder
|
||||
</Badge>
|
||||
<ArrowRight className="size-4 text-primary" aria-hidden="true" />
|
||||
<Badge className="px-3.5 py-1.5 text-sm">
|
||||
Konfiguriert: 103 Rauchwarnmelder
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="mt-10 max-w-2xl gap-0 p-6 sm:p-8">
|
||||
<p className="text-xs font-bold tracking-[0.14em] text-primary uppercase">
|
||||
Finales Ergebnis
|
||||
</p>
|
||||
<h3 className="mt-2 text-xl font-extrabold tracking-tight text-navy">
|
||||
Ihre GebOS-Konfiguration
|
||||
</h3>
|
||||
<p className="mt-1 text-sm font-semibold text-navy">
|
||||
3 Gebäude · 26 Wohnungen
|
||||
</p>
|
||||
<Separator className="my-4" />
|
||||
<dl className="flex flex-col gap-3 text-sm">
|
||||
<div>
|
||||
<dt className="font-bold text-navy">UVI</dt>
|
||||
<dd className="text-muted-foreground">
|
||||
68 Heizsensoren / Messgeräte, weitere benötigte Messtechnik
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="font-bold text-navy">Rauchwarnmelder</dt>
|
||||
<dd className="text-muted-foreground">103 Rauchwarnmelder</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="font-bold text-navy">Infrastruktur</dt>
|
||||
<dd className="text-muted-foreground">
|
||||
technisch ausgelegte Gateway- und Kommunikationsinfrastruktur
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<Separator className="my-4" />
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
Ihr Preis ist dann keine grobe Hochrechnung auf Basis von
|
||||
Durchschnittswerten mehr, sondern ein Preis auf Grundlage der
|
||||
tatsächlichen Objektkonfiguration.
|
||||
</p>
|
||||
<div className="mt-5">
|
||||
<Button type="button">Angebot anfordern</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<p className="mt-8 max-w-2xl text-sm leading-relaxed text-muted-foreground">
|
||||
Ihre Daten werden im gesamten Prozess weiterverwendet:
|
||||
Preisschätzung → Konfiguration → Bestellung → Gerätevorbereitung →
|
||||
Installation → laufender Betrieb.
|
||||
</p>
|
||||
</Section>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
import * as React from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import { Building2, House, LineChart, Wrench } from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { Checklist } from "@/components/gebos/checklist"
|
||||
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||
import {
|
||||
AssetRender,
|
||||
renders,
|
||||
vectors,
|
||||
} from "@/components/gebos/site-assets"
|
||||
|
||||
type AudienceKey =
|
||||
| "hauseigentuemer"
|
||||
| "hausverwaltung"
|
||||
| "messdienstleister"
|
||||
| "installateur"
|
||||
|
||||
const AUDIENCES: Record<
|
||||
AudienceKey,
|
||||
{
|
||||
select: string
|
||||
tab: string
|
||||
tabIcon: React.ReactNode
|
||||
headline: string
|
||||
text: string
|
||||
bullets: string[]
|
||||
cta: string
|
||||
href: string
|
||||
}
|
||||
> = {
|
||||
hauseigentuemer: {
|
||||
select: "Hauseigentümer",
|
||||
tab: "Hauseigentümer",
|
||||
tabIcon: <House />,
|
||||
headline: "Messdienstleistungen für Ihr Mehrfamilienhaus",
|
||||
text: "Installieren Sie vorkonfigurierte Technik selbst beziehungsweise mit Ihrem bestehenden Fachbetrieb – oder überlassen Sie GebOS die komplette Umsetzung.",
|
||||
bullets: [
|
||||
"einfache Installation",
|
||||
"transparente Kosten",
|
||||
"zuverlässiger laufender Betrieb",
|
||||
"eigene Fachbetriebe weiter nutzen",
|
||||
"wahlweise Selbstinstallation oder Komplettlösung",
|
||||
],
|
||||
cta: "GebOS für Hauseigentümer",
|
||||
href: "/fuer-wen/hauseigentuemer",
|
||||
},
|
||||
hausverwaltung: {
|
||||
select: "Hausverwaltung",
|
||||
tab: "Hausverwaltungen",
|
||||
tabIcon: <Building2 />,
|
||||
headline: "Viele Gebäude. Ein einfacher Rollout.",
|
||||
text: "Erfassen Sie Ihre Objekte einmal, erhalten Sie vorkonfigurierte Hardware und nutzen Sie bestehende Mitarbeiter oder Installationspartner für die Montage.",
|
||||
bullets: [
|
||||
"standardisierter Rollout",
|
||||
"vorkonfigurierte Geräte",
|
||||
"wenig Softwarearbeit vor Ort",
|
||||
"zentrale Portfolioverwaltung",
|
||||
"geringer administrativer Aufwand",
|
||||
"schnelle Erweiterung um weitere Gebäude",
|
||||
],
|
||||
cta: "GebOS für Hausverwaltungen",
|
||||
href: "/fuer-wen/hausverwaltungen",
|
||||
},
|
||||
messdienstleister: {
|
||||
select: "Messdienstleister",
|
||||
tab: "Messdienstleister",
|
||||
tabIcon: <LineChart />,
|
||||
headline: "Ihre Messdienstleistung. Unsere Infrastruktur.",
|
||||
text: "Nutzen Sie GebOS als technische Grundlage für Ihre eigenen Dienstleistungen – mit Hardware, Plattform, Gerätemanagement und optionalem White Label.",
|
||||
bullets: [
|
||||
"technische Plattform",
|
||||
"Gerätekompatibilität",
|
||||
"Skalierbarkeit",
|
||||
"APIs und Integrationen",
|
||||
"White Label",
|
||||
"individuelles Geschäftsmodell",
|
||||
],
|
||||
cta: "GebOS für Messdienstleister",
|
||||
href: "/fuer-wen/messdienstleister",
|
||||
},
|
||||
installateur: {
|
||||
select: "Installateur & Heizungsbauer",
|
||||
tab: "Installateure",
|
||||
tabIcon: <Wrench />,
|
||||
headline: "Bestellen. Montieren. Fertig.",
|
||||
text: "Setzen Sie GebOS bei Ihren bestehenden Kunden ein, ohne zunächst ein Partnerprogramm durchlaufen zu müssen.",
|
||||
bullets: [
|
||||
"kein verpflichtender Partnerstatus",
|
||||
"keine Mindestabnahme",
|
||||
"vorkonfigurierte Hardware",
|
||||
"keine aufwendige Softwarekonfiguration",
|
||||
"bestehende Kundenbeziehung bleibt erhalten",
|
||||
],
|
||||
cta: "GebOS für Installateure",
|
||||
href: "/fuer-wen/installateure",
|
||||
},
|
||||
}
|
||||
|
||||
const AUDIENCE_KEYS = Object.keys(AUDIENCES) as AudienceKey[]
|
||||
|
||||
/**
|
||||
* Page-local hero composition (04-for-whom kit):
|
||||
* building portfolio render, teal growth bars behind right,
|
||||
* consumption ring in front at the lower left.
|
||||
*/
|
||||
function ForWhomArt() {
|
||||
return (
|
||||
<div className="relative mx-auto aspect-[1.28] w-full max-w-[560px]">
|
||||
<img
|
||||
src={vectors.tealBars}
|
||||
alt=""
|
||||
className="absolute top-[16%] right-0 w-[38%]"
|
||||
/>
|
||||
<AssetRender
|
||||
render={renders.building}
|
||||
className="absolute inset-x-[6%] top-[6%]"
|
||||
imgClassName="w-full"
|
||||
loading="eager"
|
||||
/>
|
||||
<img
|
||||
src={vectors.consumptionRing}
|
||||
alt=""
|
||||
className="absolute bottom-[2%] left-[2%] w-[30%] drop-shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function ForWhomPage() {
|
||||
const [audience, setAudience] = React.useState<AudienceKey>("hausverwaltung")
|
||||
const active = AUDIENCES[audience]
|
||||
|
||||
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: "Für wen?" },
|
||||
]}
|
||||
/>
|
||||
<SectionHeading
|
||||
eyebrow="Finden Sie die passende Lösung"
|
||||
title="Für wen ist GebOS?"
|
||||
lead="GebOS wird von unterschiedlichen Kundengruppen eingesetzt. Wählen Sie aus, was am besten zu Ihnen passt."
|
||||
/>
|
||||
|
||||
<div className="mt-8 flex flex-wrap items-center gap-3">
|
||||
<Label htmlFor="audience-select" className="text-muted-foreground">
|
||||
Ich bin …
|
||||
</Label>
|
||||
<Select
|
||||
value={audience}
|
||||
onValueChange={(value) => setAudience(value as AudienceKey)}
|
||||
>
|
||||
<SelectTrigger id="audience-select" className="w-64">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{AUDIENCE_KEYS.map((key) => (
|
||||
<SelectItem key={key} value={key}>
|
||||
{AUDIENCES[key].select}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 grid items-center gap-10 lg:grid-cols-[1.05fr_0.95fr] lg:gap-6">
|
||||
<Card className="max-w-xl gap-0 p-7">
|
||||
<h2 className="text-xl font-extrabold tracking-tight text-balance text-navy sm:text-2xl">
|
||||
{active.headline}
|
||||
</h2>
|
||||
<p className="mt-3 text-sm leading-relaxed text-pretty text-muted-foreground">
|
||||
{active.text}
|
||||
</p>
|
||||
<p className="mt-5 text-sm font-bold text-navy">
|
||||
Besonders wichtig für Sie:
|
||||
</p>
|
||||
<Checklist items={active.bullets} className="mt-3" />
|
||||
<div className="mt-6">
|
||||
<Button asChild>
|
||||
<Link to={active.href}>{active.cta}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
<ForWhomArt />
|
||||
</div>
|
||||
|
||||
<Tabs
|
||||
value={audience}
|
||||
onValueChange={(value) => setAudience(value as AudienceKey)}
|
||||
className="mt-12"
|
||||
>
|
||||
<TabsList>
|
||||
{AUDIENCE_KEYS.map((key) => (
|
||||
<TabsTrigger key={key} value={key}>
|
||||
{AUDIENCES[key].tabIcon}
|
||||
{AUDIENCES[key].tab}
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</Section>
|
||||
</Container>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
import { Link } from "react-router-dom"
|
||||
import {
|
||||
ArrowRight,
|
||||
Building2,
|
||||
Calculator,
|
||||
HardHat,
|
||||
House,
|
||||
Network,
|
||||
} from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||
import { PageHero } from "@/components/gebos/page-hero"
|
||||
import { HeroArt } from "@/components/gebos/hero-art"
|
||||
import { FeatureTile, IconBadge } from "@/components/gebos/icon-tile"
|
||||
import { ProcessSteps, NumberedList } from "@/components/gebos/process-steps"
|
||||
import { Checklist } from "@/components/gebos/checklist"
|
||||
import { CtaBanner } from "@/components/gebos/cta-banner"
|
||||
import {
|
||||
AssetRender,
|
||||
icons,
|
||||
renders,
|
||||
vectors,
|
||||
} from "@/components/gebos/site-assets"
|
||||
|
||||
const features = [
|
||||
{
|
||||
media: <img src={icons.uvi} alt="" className="size-14" loading="lazy" />,
|
||||
title: "UVI",
|
||||
sub: "Monatliche Verbrauchsinformation",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.billing} alt="" className="size-14" loading="lazy" />
|
||||
),
|
||||
title: "Heizkosten\u00adabrechnung",
|
||||
sub: "Jährlich korrekt abrechnen",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.smokeAlarm} alt="" className="size-14" loading="lazy" />
|
||||
),
|
||||
title: "Rauchwarnmelder",
|
||||
sub: "Sicher überwacht, zentral verwaltet",
|
||||
},
|
||||
{
|
||||
media: <img src={icons.radio} alt="" className="size-14" loading="lazy" />,
|
||||
title: "Fernauslesbare Messtechnik",
|
||||
sub: "Automatisch erfasst, sicher übertragen",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.portal} alt="" className="size-14" loading="lazy" />
|
||||
),
|
||||
title: "Portale & Verwaltung",
|
||||
sub: "Alle Daten und Geräte im Blick",
|
||||
},
|
||||
]
|
||||
|
||||
const operationsScope = [
|
||||
{
|
||||
media: <img src={icons.uvi} alt="" className="size-12" loading="lazy" />,
|
||||
title: "Unterjährige Verbrauchsinformation",
|
||||
text: "Verbrauchsdaten werden automatisch erfasst und die regelmäßigen Verbrauchsinformationen für die Bewohner bereitgestellt.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.billing} alt="" className="size-12" loading="lazy" />
|
||||
),
|
||||
title: "Heizkostenabrechnung",
|
||||
text: "Die erfassten Verbrauchsdaten bilden die Grundlage für die jährliche Heizkostenabrechnung.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.smokeAlarm} alt="" className="size-12" loading="lazy" />
|
||||
),
|
||||
title: "Rauchwarnmelder",
|
||||
text: "Rauchwarnmelder können gemeinsam mit der übrigen Gebäudetechnik geplant, installiert und zentral verwaltet werden.",
|
||||
},
|
||||
{
|
||||
media: <img src={icons.radio} alt="" className="size-12" loading="lazy" />,
|
||||
title: "Fernauslesbare Messtechnik",
|
||||
text: "Wärme- und Wasserverbrauch werden über kompatible Geräte automatisch erfasst.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<AssetRender
|
||||
render={renders.gateway}
|
||||
className="flex size-12 items-center justify-center"
|
||||
imgClassName="w-12"
|
||||
/>
|
||||
),
|
||||
title: "Gateway und Datenübertragung",
|
||||
text: "Die Messdaten werden zentral gesammelt und an GebOS übertragen.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.portal} alt="" className="size-12" loading="lazy" />
|
||||
),
|
||||
title: "Portale und Verwaltung",
|
||||
text: "Gebäude, Wohnungen, Geräte und Verbrauchsdaten werden zentral verwaltet. Bewohner erhalten Zugriff auf die für sie vorgesehenen Informationen.",
|
||||
},
|
||||
]
|
||||
|
||||
function StepMedia({ src }: { src: string }) {
|
||||
return (
|
||||
<span className="flex size-16 items-center justify-center">
|
||||
<img src={src} alt="" className="size-16" loading="lazy" />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
const processSteps = [
|
||||
{
|
||||
media: <StepMedia src={vectors.uviBadge} />,
|
||||
title: "Gebäude erfassen",
|
||||
description: "Daten zum Gebäude und den Wohnungen erfassen.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<AssetRender
|
||||
render={renders.building}
|
||||
className="flex size-16 items-center justify-center"
|
||||
imgClassName="w-16"
|
||||
/>
|
||||
),
|
||||
title: "Gerätebedarf bestimmen",
|
||||
description: "GebOS ermittelt die benötigte Ausstattung automatisch.",
|
||||
},
|
||||
{
|
||||
media: <StepMedia src={vectors.packageBox} />,
|
||||
title: "Vorkonfiguriert liefern",
|
||||
description: "Hardware wird für Ihr Objekt vorbereitet geliefert.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<AssetRender
|
||||
render={renders.heatMeter}
|
||||
className="flex size-16 items-center justify-center"
|
||||
imgClassName="w-16"
|
||||
/>
|
||||
),
|
||||
title: "Geräte montieren",
|
||||
description: "Montage vor Ort – ohne aufwendige Softwarekonfiguration.",
|
||||
},
|
||||
{
|
||||
media: <StepMedia src={vectors.wirelessOrb} />,
|
||||
title: "Automatisch betreiben",
|
||||
description: "GebOS übernimmt Daten, Services und laufenden Betrieb.",
|
||||
},
|
||||
]
|
||||
|
||||
const lessEffort = [
|
||||
{
|
||||
vector: vectors.packageBox,
|
||||
title: "Vorkonfigurierte Hardware",
|
||||
text: "Geräte werden passend zum jeweiligen Gebäude und zur vorgesehenen Nutzung vorbereitet.",
|
||||
},
|
||||
{
|
||||
vector: vectors.checkOrb,
|
||||
title: "Keine aufwendige Einrichtung auf der Baustelle",
|
||||
text: "Der Installateur kann sich auf die fachgerechte Montage konzentrieren.",
|
||||
},
|
||||
{
|
||||
vector: vectors.checkOrb,
|
||||
title: "Bestehende Fachbetriebe nutzen",
|
||||
text: "Kein spezieller GebOS-Partner erforderlich – eigene Hausmeister, Heizungsbauer oder bestehende Installationspartner können weiterhin eingesetzt werden.",
|
||||
},
|
||||
{
|
||||
vector: vectors.checkOrb,
|
||||
title: "Weniger doppelte Dateneingabe",
|
||||
text: "Informationen aus Bestellung und Konfiguration werden für den späteren Betrieb weiterverwendet.",
|
||||
},
|
||||
]
|
||||
|
||||
const systemTasks = [
|
||||
{
|
||||
media: <img src={icons.uvi} alt="" className="size-10" loading="lazy" />,
|
||||
title: "UVI",
|
||||
text: "Regelmäßige Verbrauchsinformation für Bewohner.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.billing} alt="" className="size-10" loading="lazy" />
|
||||
),
|
||||
title: "Heizkostenabrechnung",
|
||||
text: "Verbrauchsdaten strukturiert erfassen und für die jährliche Abrechnung nutzen.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<img src={icons.smokeAlarm} alt="" className="size-10" loading="lazy" />
|
||||
),
|
||||
title: "Rauchwarnmelder",
|
||||
text: "Rauchwarnmelder gemeinsam mit der übrigen Gebäudetechnik planen und verwalten.",
|
||||
},
|
||||
{
|
||||
media: <img src={icons.radio} alt="" className="size-10" loading="lazy" />,
|
||||
title: "Messtechnik und Infrastruktur",
|
||||
text: "Fernauslesbare Zähler, Sensoren und Kommunikationsinfrastruktur für den laufenden Betrieb.",
|
||||
},
|
||||
]
|
||||
|
||||
const audiences = [
|
||||
{
|
||||
icon: <House />,
|
||||
name: "Hauseigentümer",
|
||||
headline: "Messdienstleistungen für Ihr Mehrfamilienhaus",
|
||||
text: "Installieren Sie vorkonfigurierte Technik selbst beziehungsweise mit Ihrem bestehenden Fachbetrieb – oder überlassen Sie GebOS die komplette Umsetzung.",
|
||||
points: [
|
||||
"einfache Installation",
|
||||
"transparente Kosten",
|
||||
"zuverlässiger laufender Betrieb",
|
||||
],
|
||||
cta: "GebOS für Hauseigentümer",
|
||||
to: "/fuer-wen/hauseigentuemer",
|
||||
},
|
||||
{
|
||||
icon: <Building2 />,
|
||||
name: "Hausverwaltungen",
|
||||
headline: "Viele Gebäude. Ein einfacher Rollout.",
|
||||
text: "Erfassen Sie Ihre Objekte einmal, erhalten Sie vorkonfigurierte Hardware und nutzen Sie bestehende Mitarbeiter oder Installationspartner für die Montage.",
|
||||
points: [
|
||||
"standardisierter Rollout",
|
||||
"vorkonfigurierte Geräte",
|
||||
"zentrale Portfolioverwaltung",
|
||||
],
|
||||
cta: "GebOS für Hausverwaltungen",
|
||||
to: "/fuer-wen/hausverwaltungen",
|
||||
},
|
||||
{
|
||||
icon: <Network />,
|
||||
name: "Messdienstleister",
|
||||
headline: "Ihre Messdienstleistung. Unsere Infrastruktur.",
|
||||
text: "Nutzen Sie GebOS als technische Grundlage für Ihre eigenen Dienstleistungen – mit Hardware, Plattform, Gerätemanagement und optionalem White Label.",
|
||||
points: ["technische Plattform", "Skalierbarkeit", "APIs und White Label"],
|
||||
cta: "GebOS für Messdienstleister",
|
||||
to: "/fuer-wen/messdienstleister",
|
||||
},
|
||||
{
|
||||
icon: <HardHat />,
|
||||
name: "Installateure & Heizungsbauer",
|
||||
headline: "Bestellen. Montieren. Fertig.",
|
||||
text: "Setzen Sie GebOS bei Ihren bestehenden Kunden ein, ohne zunächst ein Partnerprogramm durchlaufen zu müssen.",
|
||||
points: [
|
||||
"kein verpflichtender Partnerstatus",
|
||||
"keine Mindestabnahme",
|
||||
"vorkonfigurierte Hardware",
|
||||
],
|
||||
cta: "GebOS für Installateure",
|
||||
to: "/fuer-wen/installateure",
|
||||
},
|
||||
]
|
||||
|
||||
const scaleFlows = [
|
||||
{
|
||||
vector: vectors.tealBars,
|
||||
label: "1 Gebäude",
|
||||
sub: "Ein Eigentümer kann ein Mehrfamilienhaus konfigurieren.",
|
||||
steps: [
|
||||
{ title: "GebOS konfigurieren" },
|
||||
{ title: "Installieren" },
|
||||
{ title: "Betreiben" },
|
||||
],
|
||||
},
|
||||
{
|
||||
vector: vectors.consumptionRing,
|
||||
label: "50 Gebäude",
|
||||
sub: "Eine Hausverwaltung kann denselben Prozess auf viele Gebäude übertragen.",
|
||||
steps: [
|
||||
{ title: "Nach demselben Prozess konfigurieren" },
|
||||
{ title: "Rollout organisieren" },
|
||||
{ title: "Zentral betreiben" },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const priceFlow = [
|
||||
{ title: "Wenige Angaben" },
|
||||
{ title: "Erste Preisindikation" },
|
||||
{ title: "Konfiguration speichern" },
|
||||
{ title: "Gebäude vollständig konfigurieren" },
|
||||
{ title: "Genauer Preis" },
|
||||
]
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title={
|
||||
<>
|
||||
Messdienstleistungen
|
||||
<br className="hidden sm:block" />{" "}
|
||||
<span className="text-primary">einfach</span> gemacht.
|
||||
</>
|
||||
}
|
||||
lead="Unterjährige Verbrauchsinformation (UVI), Heizkostenabrechnung und Rauchwarnmelder – von der vorkonfigurierten Hardware bis zum laufenden Betrieb."
|
||||
actions={
|
||||
<>
|
||||
<Button asChild size="lg">
|
||||
<Link to="/konfigurator">Preis berechnen</Link>
|
||||
</Button>
|
||||
<Button asChild variant="outline" size="lg">
|
||||
<Link to="/so-funktionierts">So funktioniert GebOS</Link>
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
visual={<HeroArt />}
|
||||
/>
|
||||
|
||||
<Container>
|
||||
<Section className="pt-0">
|
||||
<div className="rounded-2xl border border-border bg-card p-6 shadow-card sm:p-8">
|
||||
<div className="grid grid-cols-2 gap-x-4 gap-y-8 sm:grid-cols-3 lg:grid-cols-5">
|
||||
{features.map((feature) => (
|
||||
<FeatureTile key={feature.sub} {...feature} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Das System"
|
||||
title="Alles, was für den laufenden Messbetrieb benötigt wird"
|
||||
lead="GebOS verbindet Messtechnik, Datenerfassung und Software zu einem durchgängigen System. Statt einzelne Komponenten selbst zusammenzustellen und miteinander zu verbinden, erhalten Sie eine Lösung, bei der Bestellung, Hardware, Konfiguration und laufender Betrieb zusammenspielen."
|
||||
/>
|
||||
<div className="mt-12 grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{operationsScope.map((item) => (
|
||||
<Card key={item.title} className="p-6 gap-0">
|
||||
<CardContent className="flex h-full flex-col items-start gap-3 p-0">
|
||||
{item.media}
|
||||
<h3 className="text-base font-bold text-navy">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
{item.text}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Der Prozess"
|
||||
title="So funktioniert GebOS"
|
||||
lead="Von der Bestellung bis zum laufenden Betrieb – GebOS verbindet Bestellung, Konfiguration und Installation miteinander."
|
||||
/>
|
||||
<ProcessSteps steps={processSteps} className="mt-12" />
|
||||
<p className="mt-10 text-center text-base font-semibold italic text-navy">
|
||||
„Bestellung, Konfiguration und Installation greifen ineinander.“
|
||||
</p>
|
||||
<div className="mt-6 flex justify-center">
|
||||
<Button asChild size="lg">
|
||||
<Link to="/konfigurator">Preis für mein Gebäude berechnen</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Installation"
|
||||
title="Weniger Aufwand vor Ort"
|
||||
lead="Die Installation eines Messsystems sollte nicht daran scheitern, dass vor Ort komplizierte Software eingerichtet oder jedes Gerät manuell zugeordnet werden muss. GebOS bereitet die digitale Struktur bereits vor der Installation vor."
|
||||
/>
|
||||
<div className="mt-12 grid gap-5 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{lessEffort.map((item) => (
|
||||
<Card key={item.title} className="p-6 gap-0">
|
||||
<CardContent className="flex h-full flex-col items-start gap-3 p-0">
|
||||
<img
|
||||
src={item.vector}
|
||||
alt=""
|
||||
className="size-12"
|
||||
loading="lazy"
|
||||
/>
|
||||
<h3 className="text-base font-bold text-navy">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
{item.text}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Leistungen"
|
||||
title="Ein System für mehrere Aufgaben"
|
||||
lead="GebOS bündelt wiederkehrende Mess- und Gebäudedienstleistungen auf einer gemeinsamen technischen Grundlage."
|
||||
/>
|
||||
<Card className="mt-12 divide-y divide-border p-0 gap-0">
|
||||
{systemTasks.map((task) => (
|
||||
<div
|
||||
key={task.title}
|
||||
className="flex flex-col gap-3 p-5 sm:flex-row sm:items-center sm:gap-5 sm:px-7"
|
||||
>
|
||||
{task.media}
|
||||
<div className="min-w-0 flex-1">
|
||||
<h3 className="text-sm font-bold text-navy">{task.title}</h3>
|
||||
<p className="mt-0.5 text-sm leading-relaxed text-muted-foreground">
|
||||
{task.text}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
asChild
|
||||
variant="link"
|
||||
className="h-auto shrink-0 self-start p-0 sm:self-center"
|
||||
>
|
||||
<Link to="/loesungen">
|
||||
Mehr erfahren
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</Card>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Skalierung"
|
||||
title="Vom einzelnen Mehrfamilienhaus bis zum Portfolio"
|
||||
lead="GebOS ist so aufgebaut, dass derselbe grundlegende Prozess sowohl für ein einzelnes Gebäude als auch für größere Bestände funktioniert. Neue Objekte werden nach einem einheitlichen Schema ergänzt und ausgerollt."
|
||||
/>
|
||||
<Card className="mt-12 p-0 gap-0 overflow-hidden">
|
||||
<div className="grid divide-y divide-border sm:grid-cols-2 sm:divide-x sm:divide-y-0">
|
||||
{scaleFlows.map((flow) => (
|
||||
<div key={flow.label} className="flex flex-col gap-5 p-6 sm:p-8">
|
||||
<div className="flex items-center gap-4">
|
||||
<img
|
||||
src={flow.vector}
|
||||
alt=""
|
||||
className="size-14"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div>
|
||||
<h3 className="text-xl font-extrabold tracking-tight text-navy">
|
||||
{flow.label}
|
||||
</h3>
|
||||
<p className="mt-0.5 text-sm text-muted-foreground">
|
||||
{flow.sub}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<NumberedList steps={flow.steps} className="mt-1" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
eyebrow="Preis"
|
||||
title="Was kostet GebOS?"
|
||||
lead="Mit dem GebOS-Konfigurator erhalten Sie bereits mit wenigen Angaben eine erste Preisindikation."
|
||||
/>
|
||||
<div className="mt-10 grid items-start gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<div>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
Dafür werden zunächst nur grundlegende Informationen benötigt,
|
||||
beispielsweise:
|
||||
</p>
|
||||
<Checklist
|
||||
className="mt-4"
|
||||
items={[
|
||||
"gewünschte Leistungen",
|
||||
"Anzahl der Gebäude",
|
||||
"Anzahl der Wohnungen",
|
||||
"Art der Wärmeverteilung",
|
||||
"durchschnittliche Anzahl der Zimmer",
|
||||
]}
|
||||
/>
|
||||
<p className="mt-4 text-sm leading-relaxed text-muted-foreground">
|
||||
Auf Basis dieser Angaben schätzt GebOS die voraussichtlich
|
||||
benötigte Geräteanzahl und berechnet einen ungefähren Preis.
|
||||
</p>
|
||||
<h3 className="mt-8 text-lg font-extrabold tracking-tight text-navy">
|
||||
Erst schätzen. Dann genau konfigurieren.
|
||||
</h3>
|
||||
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">
|
||||
Der Schnellkonfigurator arbeitet bewusst mit Annahmen. Für
|
||||
einen genauen Preis können Sie die Konfiguration anschließend
|
||||
speichern und Ihre Gebäude detailliert erfassen. Die bereits
|
||||
eingegebenen Daten werden übernommen.
|
||||
</p>
|
||||
<Button asChild size="lg" className="mt-6">
|
||||
<Link to="/konfigurator">Preis berechnen</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Card className="p-6 gap-0 sm:p-8">
|
||||
<CardContent className="p-0">
|
||||
<div className="flex items-center gap-4">
|
||||
<img
|
||||
src={vectors.euroOrb}
|
||||
alt=""
|
||||
className="size-14"
|
||||
loading="lazy"
|
||||
/>
|
||||
<h3 className="text-base font-bold text-navy">
|
||||
In fünf Schritten zum genauen Preis
|
||||
</h3>
|
||||
</div>
|
||||
<NumberedList steps={priceFlow} className="mt-6" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<p className="mt-5 text-xs leading-relaxed text-muted-foreground italic">
|
||||
Die erste Berechnung ist eine unverbindliche Preisindikation.
|
||||
Die tatsächliche Ausstattung und der genaue Preis ergeben sich
|
||||
aus der vollständigen Objektkonfiguration.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Zielgruppen"
|
||||
title="Für wen ist GebOS?"
|
||||
lead="GebOS wird von unterschiedlichen Kundengruppen eingesetzt. Wählen Sie aus, was am besten zu Ihnen passt."
|
||||
/>
|
||||
<div className="mt-12 grid gap-5 sm:grid-cols-2">
|
||||
{audiences.map((audience) => (
|
||||
<Card key={audience.to} className="p-6 gap-0 sm:p-7">
|
||||
<CardContent className="flex h-full flex-col items-start gap-3 p-0">
|
||||
<div className="flex items-center gap-3">
|
||||
<IconBadge variant="soft" shape="squircle" size="lg">
|
||||
{audience.icon}
|
||||
</IconBadge>
|
||||
<span className="text-xs font-bold tracking-wide text-primary uppercase">
|
||||
{audience.name}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-lg font-extrabold tracking-tight text-navy">
|
||||
{audience.headline}
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
{audience.text}
|
||||
</p>
|
||||
<p className="mt-1 text-xs font-bold tracking-wide text-navy uppercase">
|
||||
Besonders wichtig für Sie
|
||||
</p>
|
||||
<Checklist items={audience.points} className="mb-2" />
|
||||
<Button asChild variant="outline" className="mt-auto">
|
||||
<Link to={audience.to}>{audience.cta}</Link>
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<CtaBanner
|
||||
icon={<Calculator />}
|
||||
title="Messdienstleistungen müssen nicht kompliziert sein."
|
||||
description="Gebäude erfassen, passende Technik erhalten, montieren und anschließend zentral betreiben."
|
||||
actions={
|
||||
<>
|
||||
<Button asChild variant="inverse" size="lg">
|
||||
<Link to="/konfigurator">Preis berechnen</Link>
|
||||
</Button>
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="border-white/40 bg-transparent text-white hover:bg-white/10 hover:text-white"
|
||||
>
|
||||
<Link to="/so-funktionierts">So funktioniert GebOS</Link>
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Section>
|
||||
</Container>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
import type { ReactNode } from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import { Calculator, ChevronRight } from "lucide-react"
|
||||
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { CtaBanner } from "@/components/gebos/cta-banner"
|
||||
import { ProcessSteps } from "@/components/gebos/process-steps"
|
||||
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||
import {
|
||||
AssetRender,
|
||||
renders,
|
||||
vectors,
|
||||
} from "@/components/gebos/site-assets"
|
||||
|
||||
function StepMedia({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="flex h-16 items-end justify-center gap-1">{children}</div>
|
||||
)
|
||||
}
|
||||
|
||||
const steps = [
|
||||
{
|
||||
media: (
|
||||
<StepMedia>
|
||||
<img src={vectors.uviBadge} alt="" className="w-16" />
|
||||
</StepMedia>
|
||||
),
|
||||
title: "Gebäude erfassen",
|
||||
description:
|
||||
"Bei der Konfiguration werden Gebäude, Wohnungen und die benötigten Leistungen erfasst.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<StepMedia>
|
||||
<AssetRender render={renders.building} imgClassName="w-16" />
|
||||
</StepMedia>
|
||||
),
|
||||
title: "Gerätebedarf bestimmen",
|
||||
description:
|
||||
"Auf Basis der Gebäudedaten wird ermittelt, welche Messtechnik, Rauchwarnmelder und weiteren Komponenten benötigt werden.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<StepMedia>
|
||||
<img src={vectors.packageBox} alt="" className="w-16" />
|
||||
</StepMedia>
|
||||
),
|
||||
title: "Vorkonfiguriert liefern",
|
||||
description:
|
||||
"Gebäude, Wohnungen und Geräte werden bereits vorbereitet. Die Hardware wird objektbezogen und installationsfertig geliefert.",
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<StepMedia>
|
||||
<AssetRender render={renders.heatMeter} imgClassName="w-12" />
|
||||
<AssetRender render={renders.gateway} imgClassName="w-9" />
|
||||
</StepMedia>
|
||||
),
|
||||
title: "Geräte montieren",
|
||||
description: (
|
||||
<>
|
||||
Die Geräte müssen vor Ort im Wesentlichen nur noch fachgerecht montiert
|
||||
werden.{" "}
|
||||
<strong className="font-bold text-navy">
|
||||
Keine aufwendige Softwarekonfiguration bei der Installation.
|
||||
</strong>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
media: (
|
||||
<StepMedia>
|
||||
<img src={vectors.wirelessOrb} alt="" className="w-16" />
|
||||
</StepMedia>
|
||||
),
|
||||
title: "Automatisch betreiben",
|
||||
description:
|
||||
"Nach der Installation übernimmt GebOS die laufende Datenerfassung und die gebuchten digitalen Dienstleistungen.",
|
||||
},
|
||||
]
|
||||
|
||||
const journey = [
|
||||
"Besucher versteht GebOS",
|
||||
"identifiziert seinen Anwendungsfall",
|
||||
"berechnet einen ungefähren Preis",
|
||||
"speichert seine Konfiguration",
|
||||
"ergänzt die tatsächlichen Gebäudedaten",
|
||||
"erhält den genauen Preis",
|
||||
"erteilt den Auftrag",
|
||||
"GebOS bereitet Gebäude und Geräte vor",
|
||||
"vorkonfigurierte Hardware wird geliefert",
|
||||
"Montage vor Ort",
|
||||
"automatischer laufender Betrieb",
|
||||
]
|
||||
|
||||
export default function HowItWorksPage() {
|
||||
return (
|
||||
<>
|
||||
<div className="bg-hero-glow">
|
||||
<Container>
|
||||
<Section className="pt-6 pb-10 sm:pt-7 sm:pb-12 lg:pt-8 lg:pb-14">
|
||||
<PageBreadcrumb
|
||||
className="mb-4 justify-center"
|
||||
items={[
|
||||
{ label: "Startseite", to: "/" },
|
||||
{ label: "So funktioniert’s" },
|
||||
]}
|
||||
/>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
title="So funktioniert GebOS"
|
||||
lead="Von der Bestellung bis zum laufenden Betrieb. GebOS verbindet Bestellung, Konfiguration und Installation miteinander."
|
||||
/>
|
||||
<Card className="mt-10 gap-0 p-8 sm:mt-12 sm:p-10">
|
||||
<ProcessSteps steps={steps} />
|
||||
</Card>
|
||||
<p className="mx-auto mt-10 max-w-xl text-center text-sm font-medium text-muted-foreground italic">
|
||||
„Bestellung, Konfiguration und Installation greifen ineinander.“
|
||||
</p>
|
||||
</Section>
|
||||
</Container>
|
||||
</div>
|
||||
<Container>
|
||||
<Section>
|
||||
<SectionHeading
|
||||
align="center"
|
||||
eyebrow="Gesamtprozess"
|
||||
title="Der Gesamtprozess aus Kundensicht"
|
||||
lead="Website, Konfigurator und operativer Rollout sind keine getrennten Systeme – sie bauen aufeinander auf."
|
||||
/>
|
||||
<div className="mx-auto mt-10 flex max-w-4xl flex-wrap items-center justify-center gap-x-1.5 gap-y-3">
|
||||
{journey.map((station, i) => (
|
||||
<span key={station} className="flex items-center gap-1.5">
|
||||
<Badge variant="outline" className="bg-card">
|
||||
{station}
|
||||
</Badge>
|
||||
{i < journey.length - 1 ? (
|
||||
<ChevronRight
|
||||
aria-hidden="true"
|
||||
className="size-4 shrink-0 text-brand-400"
|
||||
/>
|
||||
) : null}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="mx-auto mt-10 max-w-2xl text-center">
|
||||
<p className="text-base font-bold text-navy sm:text-lg">
|
||||
Der Konfigurator ist der Beginn des
|
||||
GebOS-Bestell- und Rolloutprozesses.
|
||||
</p>
|
||||
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">
|
||||
Die einmal eingegebenen Gebäudedaten werden nicht erneut erfasst,
|
||||
sondern durch den gesamten Prozess weiterverwendet.
|
||||
</p>
|
||||
<p className="mt-6 font-mono text-xs tracking-wide text-muted-foreground uppercase">
|
||||
Preisschätzung → Konfiguration → Bestellung → Gerätevorbereitung →
|
||||
Installation → Betrieb
|
||||
</p>
|
||||
</div>
|
||||
</Section>
|
||||
</Container>
|
||||
<Container>
|
||||
<Section className="pt-0">
|
||||
<CtaBanner
|
||||
icon={<Calculator />}
|
||||
title="Was kostet GebOS für Ihr Gebäude?"
|
||||
description="Mit wenigen Angaben erhalten Sie eine erste Preisindikation."
|
||||
actions={
|
||||
<Button variant="inverse" size="lg" asChild>
|
||||
<Link to="/konfigurator">Preis berechnen</Link>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</Section>
|
||||
</Container>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import { ClipboardCheck, Euro, House, ShieldCheck, Tag, Users2, Wifi } from "lucide-react"
|
||||
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { Container, Section } from "@/components/gebos/section"
|
||||
import { PageHero } from "@/components/gebos/page-hero"
|
||||
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||
import { HeroVisual } from "@/components/gebos/hero-visual"
|
||||
import { IconBadge } from "@/components/gebos/icon-tile"
|
||||
import { PriceCard } from "@/components/gebos/price-card"
|
||||
import {
|
||||
SensorCubesIllustration,
|
||||
SmokeDetectorIllustration,
|
||||
} from "@/components/gebos/illustrations"
|
||||
|
||||
const trustItems = [
|
||||
{ icon: ClipboardCheck, label: ["Klare", "Vertragsstruktur"] },
|
||||
{ icon: ShieldCheck, label: ["Keine versteckten", "Gebühren"] },
|
||||
{ icon: Users2, label: ["Rabatte für", "große Objekte"] },
|
||||
] as const
|
||||
|
||||
export default function KlarpreisPage() {
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
breadcrumb={
|
||||
<PageBreadcrumb
|
||||
items={[
|
||||
{ label: "Startseite", to: "/" },
|
||||
{ label: "GebOS Klarpreis" },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
title={
|
||||
<>
|
||||
GebOS <span className="text-primary">Klarpreis</span>
|
||||
</>
|
||||
}
|
||||
lead="Drei sauber getrennte Leistungen. Einfache Preise. Keine Überraschungen."
|
||||
extra={
|
||||
<div className="inline-flex items-center gap-3 rounded-full border border-border bg-card px-4 py-2 text-sm text-muted-foreground shadow-pill">
|
||||
<IconBadge variant="soft" size="sm">
|
||||
<House />
|
||||
</IconBadge>
|
||||
<span>Ideal für Wohngebäude, Hausverwaltungen und Bestandshalter.</span>
|
||||
</div>
|
||||
}
|
||||
visual={
|
||||
<HeroVisual
|
||||
media={<SmokeDetectorIllustration className="mx-auto w-48" />}
|
||||
chipTitle="Inspektion OK"
|
||||
chipSub="Letzte Prüfung 06.05.2024"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Container>
|
||||
<Section className="pt-0">
|
||||
<div className="grid gap-6 lg:grid-cols-3">
|
||||
<PriceCard
|
||||
title="RWM-Hardware"
|
||||
cadence="Einmalig"
|
||||
price="42,00 €"
|
||||
unit="je Wohnung einmalig"
|
||||
allocation={{ label: "Nicht umlagefähig", tone: "negative" }}
|
||||
description="Rauchwarnmelder inklusive Montage und Eigentumsübertragung."
|
||||
media={<SmokeDetectorIllustration />}
|
||||
/>
|
||||
<PriceCard
|
||||
title="Ferninspektion"
|
||||
cadence="Monatlich"
|
||||
price="2,20 €"
|
||||
unit="je Wohnung / Monat"
|
||||
allocation={{ label: "Grundsätzlich umlagefähig", tone: "positive" }}
|
||||
description="Regelmäßige Prüfung, Nachweise, Meldungen und Support."
|
||||
media={
|
||||
<div className="relative">
|
||||
<SmokeDetectorIllustration />
|
||||
<Wifi className="absolute -right-1 top-1 size-5 text-primary" />
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<PriceCard
|
||||
title={
|
||||
<span className="text-[1.15rem] whitespace-nowrap">
|
||||
UVI-Komplettbetrieb
|
||||
</span>
|
||||
}
|
||||
cadence="Monatlich"
|
||||
price="10,50 €"
|
||||
unit="je Wohnung / Monat"
|
||||
allocation={{ label: "Grundsätzlich umlagefähig", tone: "positive" }}
|
||||
description="Sensoren, Daten, Portal und Verbrauchsinformation inklusive."
|
||||
media={<SensorCubesIllustration />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 grid gap-6 lg:grid-cols-[1.4fr_1fr]">
|
||||
{/* total band */}
|
||||
<div className="flex flex-wrap items-center gap-6 rounded-2xl bg-brand-gradient p-6 shadow-band sm:flex-nowrap sm:p-7">
|
||||
<IconBadge variant="glass" size="xl">
|
||||
<Euro />
|
||||
</IconBadge>
|
||||
<div>
|
||||
<div className="font-semibold text-white/80">
|
||||
Gesamtkosten laufend
|
||||
</div>
|
||||
<div className="mt-1 flex flex-wrap items-baseline gap-x-3">
|
||||
<span className="text-4xl font-extrabold tracking-tight text-white">
|
||||
12,70 €
|
||||
</span>
|
||||
<span className="text-sm text-white/75">
|
||||
je Wohnung / Monat
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
className="hidden self-stretch bg-white/25 sm:block"
|
||||
/>
|
||||
<div className="flex items-center gap-3">
|
||||
<IconBadge variant="glass" size="sm">
|
||||
<Tag />
|
||||
</IconBadge>
|
||||
<p className="max-w-56 text-sm leading-snug text-white/80">
|
||||
Alle laufenden Leistungen klar gebündelt – ohne versteckte
|
||||
Zusatzkosten.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* trust card */}
|
||||
<div className="grid grid-cols-3 divide-x divide-border rounded-2xl bg-card p-6 shadow-card">
|
||||
{trustItems.map(({ icon: Icon, label }) => (
|
||||
<div
|
||||
key={label[1]}
|
||||
className="flex flex-col items-center justify-center gap-2.5 px-2 text-center"
|
||||
>
|
||||
<IconBadge variant="soft" size="lg" shape="circle">
|
||||
<Icon />
|
||||
</IconBadge>
|
||||
<div className="text-sm leading-snug font-bold text-navy">
|
||||
{label[0]}
|
||||
<br />
|
||||
{label[1]}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
</Container>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import type * as React from "react"
|
||||
|
||||
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||
import {
|
||||
PageBreadcrumb,
|
||||
type Crumb,
|
||||
} from "@/components/gebos/page-breadcrumb"
|
||||
|
||||
/**
|
||||
* Minimal content page (Unternehmen / Kontakt) and stand-in while
|
||||
* full pages are being built.
|
||||
*/
|
||||
function SimplePage({
|
||||
title,
|
||||
lead,
|
||||
breadcrumb,
|
||||
children,
|
||||
}: {
|
||||
title: React.ReactNode
|
||||
lead?: React.ReactNode
|
||||
breadcrumb?: Crumb[]
|
||||
children?: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<div className="bg-hero-glow">
|
||||
<Container>
|
||||
<Section className={breadcrumb ? "pt-6 sm:pt-7 lg:pt-8" : undefined}>
|
||||
{breadcrumb ? (
|
||||
<PageBreadcrumb className="mb-4" items={breadcrumb} />
|
||||
) : null}
|
||||
<SectionHeading title={title} lead={lead} />
|
||||
{children}
|
||||
</Section>
|
||||
</Container>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export { SimplePage }
|
||||
@@ -0,0 +1,132 @@
|
||||
import { Link } from "react-router-dom"
|
||||
import { ArrowRight, Euro } from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { CtaBanner } from "@/components/gebos/cta-banner"
|
||||
import { Container, Section, SectionHeading } from "@/components/gebos/section"
|
||||
import { PageBreadcrumb } from "@/components/gebos/page-breadcrumb"
|
||||
import {
|
||||
AssetRender,
|
||||
renders,
|
||||
vectors,
|
||||
} from "@/components/gebos/site-assets"
|
||||
|
||||
const solutions = [
|
||||
{
|
||||
title: "UVI",
|
||||
sub: "Monatliche Verbrauchsinformation",
|
||||
description:
|
||||
"Verbrauchsdaten werden automatisch erfasst und die regelmäßigen Verbrauchsinformationen für die Bewohner bereitgestellt.",
|
||||
illustration: (
|
||||
<div className="relative">
|
||||
<AssetRender render={renders.gateway} imgClassName="w-28" />
|
||||
<img
|
||||
src={vectors.glassCubes}
|
||||
alt=""
|
||||
className="absolute -top-3 -right-8 w-14"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Heizkostenabrechnung",
|
||||
sub: "Verbrauchsdaten korrekt abrechnen",
|
||||
description:
|
||||
"Verbrauchsdaten strukturiert erfassen und für die jährliche Abrechnung nutzen.",
|
||||
illustration: <img src={vectors.consumptionRing} alt="" className="w-28" />,
|
||||
},
|
||||
{
|
||||
title: "Rauchwarnmelder",
|
||||
sub: "Sicher überwacht, zentral verwaltet",
|
||||
description:
|
||||
"Rauchwarnmelder gemeinsam mit der übrigen Gebäudetechnik planen und verwalten.",
|
||||
illustration: <AssetRender render={renders.smokeAlarm} imgClassName="w-28" />,
|
||||
},
|
||||
]
|
||||
|
||||
export default function SolutionsPage() {
|
||||
return (
|
||||
<>
|
||||
<div className="bg-hero-glow">
|
||||
<Container>
|
||||
<Section className="pt-6 pb-10 sm:pt-7 sm:pb-12 lg:pt-8 lg:pb-14">
|
||||
<PageBreadcrumb
|
||||
className="mb-4"
|
||||
items={[
|
||||
{ label: "Startseite", to: "/" },
|
||||
{ label: "Lösungen" },
|
||||
]}
|
||||
/>
|
||||
<SectionHeading
|
||||
title="Unsere Lösungen"
|
||||
lead="Drei sauber getrennte Leistungen. Perfekt zusammenspielend."
|
||||
/>
|
||||
<div className="mt-10 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{solutions.map((s) => (
|
||||
<Card key={s.title} className="gap-0 p-6 sm:p-7">
|
||||
<h3 className="text-xl font-extrabold tracking-tight text-navy">
|
||||
{s.title}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">{s.sub}</p>
|
||||
<div className="my-6 flex h-32 flex-1 items-center justify-center">
|
||||
{s.illustration}
|
||||
</div>
|
||||
<p className="text-sm leading-relaxed text-muted-foreground">
|
||||
{s.description}
|
||||
</p>
|
||||
<Button
|
||||
variant="link"
|
||||
className="mt-3 self-start px-0"
|
||||
asChild
|
||||
>
|
||||
<Link to="/loesungen">
|
||||
Mehr erfahren
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
<Card className="mt-6 flex-col items-start gap-4 p-5 sm:flex-row sm:items-center sm:p-6">
|
||||
<AssetRender
|
||||
render={renders.gateway}
|
||||
className="shrink-0"
|
||||
imgClassName="w-14"
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<h3 className="text-sm font-bold text-navy">
|
||||
Messtechnik und Infrastruktur
|
||||
</h3>
|
||||
<p className="mt-0.5 text-sm leading-relaxed text-muted-foreground">
|
||||
Fernauslesbare Zähler, Sensoren und
|
||||
Kommunikationsinfrastruktur für den laufenden Betrieb.
|
||||
</p>
|
||||
</div>
|
||||
<Button variant="link" className="shrink-0 px-0 sm:px-4" asChild>
|
||||
<Link to="/loesungen">
|
||||
Mehr erfahren
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
</Card>
|
||||
</Section>
|
||||
</Container>
|
||||
</div>
|
||||
<Container>
|
||||
<Section className="pt-0">
|
||||
<CtaBanner
|
||||
icon={<Euro />}
|
||||
title="Jetzt Preis für Ihr Gebäude berechnen"
|
||||
description="In wenigen Minuten zur ersten Preisindikation."
|
||||
actions={
|
||||
<Button variant="inverse" size="lg" asChild>
|
||||
<Link to="/konfigurator">Preis berechnen</Link>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</Section>
|
||||
</Container>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user