Add optional room areas

This commit is contained in:
Julian Appel 2026-09-27 20:00:03 +02:00
parent a6500e2b26
commit dce31ee143
26 changed files with 3669 additions and 78 deletions

View file

@ -4,6 +4,10 @@ import React, { type FormEvent, useState } from "react";
import type { BuildingDto, CreateRoomInput, RoomDto } from "../types";
import { FloorSelectOptions, type FloorOption } from "./floor-select-options";
import { FormModal } from "./form-modal";
import {
formatOptionalRoomAreaInput,
parseRoomAreaInput,
} from "../utils/room-area";
interface RoomModalProps {
/** When given, the floor select groups floors by building. */
@ -36,14 +40,21 @@ export function RoomModal({
const [floorId, setFloorId] = useState(
initialRoom?.floorId ?? initialValues?.floorId ?? ""
);
const [areaText, setAreaText] = useState(() =>
formatOptionalRoomAreaInput(
initialRoom ? initialRoom.areaM2 : initialValues?.areaM2
)
);
const parsedArea = parseRoomAreaInput(areaText);
async function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
if (!roomNumber.trim() || !roomName.trim()) return;
if (!roomNumber.trim() || !roomName.trim() || !parsedArea.ok) return;
await onSave({
floorId: floorId || undefined,
roomNumber: roomNumber.trim(),
roomName: roomName.trim(),
areaM2: parsedArea.value,
});
}
@ -52,7 +63,7 @@ export function RoomModal({
isSaving={isSaving}
onClose={onClose}
onSubmit={handleSubmit}
submitDisabled={!roomNumber.trim() || !roomName.trim()}
submitDisabled={!roomNumber.trim() || !roomName.trim() || !parsedArea.ok}
submitLabel={initialRoom ? "Änderungen speichern" : "Raum anlegen"}
title={initialRoom ? "Raum bearbeiten" : "Raum hinzufügen"}
>
@ -90,6 +101,27 @@ export function RoomModal({
<FloorSelectOptions buildings={buildings} floors={floors} />
</select>
</div>
<div className="col-12 col-md-6">
<label className="form-label" htmlFor="room-area">
Fläche [m²]
</label>
<input
aria-describedby="room-area-help"
aria-invalid={!parsedArea.ok}
className={`form-control${parsedArea.ok ? "" : " is-invalid"}`}
id="room-area"
inputMode="decimal"
onChange={(event) => setAreaText(event.target.value)}
placeholder="z. B. 23,45"
type="text"
value={areaText}
/>
<div className={parsedArea.ok ? "form-text" : "invalid-feedback"} id="room-area-help">
{parsedArea.ok
? "Optionale Netto-Raumfläche; Eingabe mit Dezimalkomma."
: parsedArea.error}
</div>
</div>
</div>
{initialRoom && onDelete ? (
<div className="border-top mt-4 pt-3">