diff --git a/component-library/src/pages/configurator.tsx b/component-library/src/pages/configurator.tsx
index a2f7faf..2b42db7 100644
--- a/component-library/src/pages/configurator.tsx
+++ b/component-library/src/pages/configurator.tsx
@@ -1,11 +1,10 @@
import * as React from "react"
import { Link, useSearchParams } from "react-router-dom"
-import { Check, Plus, X } from "lucide-react"
+import { Ban, Check, CircleCheck, Euro, Plus, X } from "lucide-react"
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"
@@ -22,6 +21,7 @@ import {
type RenderAsset,
} from "@/components/solenos/site-assets"
import { cn } from "@/lib/utils"
+import { useAnimatedNumber } from "@/lib/use-animated-number"
type Heat = "heizkoerper" | "fussbodenheizung" | "gemischt" | "unbekannt"
@@ -49,6 +49,21 @@ const INITIAL_BUILDING: Building = {
zimmer: 3,
}
+/** Grundpreise je Wohnung / Monat – wie in der Klarpreis-Liste. */
+const UVI_MONTHLY = 10.5
+const INSPECTION_MONTHLY = 2.2
+/** RWM-Hardware je Wohnung einmalig – ohne Montage, die eine eigene Position ist. */
+const RWM_ONE_TIME = 30
+/** Montage durch SolenOS: je neuem Melder und je Wohnung mit Messtechnik. */
+const INSTALL_PER_RWM = 10
+const INSTALL_PER_UNIT = 10
+
+function formatEuro(value: number) {
+ return value.toLocaleString("de-DE", {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ })
+}
/**
* Keeps a partially edited number field empty instead of snapping it to 0, so
@@ -167,7 +182,8 @@ function StepCard({
}
/**
- * Selectable service tile (step 1) — the active option carries a brand border.
+ * Selectable service tile (step 1) — the whole tile is the toggle, the switch
+ * mirrors the state. The active option carries a brand border.
*/
function ServiceOption({
id,
@@ -183,48 +199,47 @@ function ServiceOption({
description: string
}) {
return (
-
- Leistung in Schritt 1 auswählen, um sie in den Leistungsumfang
- aufzunehmen.
+ Leistung in Schritt 1 auswählen, um sie in den Preis aufzunehmen.
)}
)
}
+/**
+ * One position of the price indication: figure, cadence and whether the
+ * position can be passed on to tenants (umlagefähig). Wording follows the
+ * Klarpreis price list.
+ */
+type Position = {
+ label: string
+ amount: number
+ unit: string
+ note?: string
+ allocatable: boolean
+ /** A deselected position stays on the card as a faint zero. */
+ active: boolean
+}
+
+function PriceRow({
+ label,
+ amount,
+ unit,
+ note,
+ allocatable,
+ active,
+}: Position) {
+ const shown = useAnimatedNumber(amount)
+
+ return (
+
-
+
{install ? "SolenOS montiert" : "Selbstmontage"}
@@ -407,7 +535,7 @@ export default function ConfiguratorPage() {
className="mt-1 text-sm text-muted-foreground"
>
{install
- ? "SolenOS übernimmt Montage und Softwarekonfiguration. Der geprüfte Gesamtpreis folgt mit dem verbindlichen Angebot."
+ ? "SolenOS übernimmt Montage und Softwarekonfiguration – die Montage erscheint als eigene Position."
: "Sie, Ihr Hausmeister oder Ihr Fachbetrieb montieren. Eine Softwarekonfiguration vor Ort ist nicht erforderlich."}
-
-
- {install
- ? "Montage durch SolenOS"
- : "Montage durch Sie oder Ihren Fachbetrieb"}
-
-
-
-
-
- Geprüfter Gesamtpreis nach Detailkonfiguration
-
-
- Wir veröffentlichen keine ungeprüften Preiswerte. Nach der
- manuellen Prüfung erhalten Sie ein verbindliches
- Gesamtangebot mit der erforderlichen Gateway-Infrastruktur,
- den gewählten Leistungen und der gewählten Montagevariante.
-
- {/* Vollständiger Leistungsumfang des späteren Gesamtangebots */}
+ {/* Was ist in dem Preis enthalten? */}
-
+