Felder Prüfung

This commit is contained in:
Moritz Utcke
2025-03-05 21:33:16 -03:00
parent 9b33755cdd
commit 25da5c9bb0
15 changed files with 506 additions and 561 deletions

View File

@@ -1,91 +1,61 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import { BenutzerClient } from "./types.js"; import { BenutzerClient } from "./types.js";
export let user: BenutzerClient; export let user: BenutzerClient;
</script> </script>
<div id="ansprechpartner" class="bereich-box grid <div
id="ansprechpartner"
class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-8 grid-cols-1 gap-x-4 gap-y-8
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8 sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8 xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
"> "
>
<!-- Anrede * --> <!-- Vorname * -->
<!--
<div class="input-standard order-3 md:order-3 xl:order-3">
<Inputlabel title="Anrede *"></Inputlabel>
<select name="anrede" bind:value={user.anrede}> <div class="input-standard order-1 md:order-1 xl:order-1">
<option disabled selected>bitte auswählen</option> <Inputlabel title="Vorname *"></Inputlabel>
<option value="Herr">Herr</option>
<option value="Frau">Frau</option>
</select>
</div> -->
<input name="vorname" type="text" bind:value={user.vorname} required />
<!-- Vorname * -->
<div class="input-standard order-1 md:order-1 xl:order-1">
<Inputlabel title="Vorname *"></Inputlabel>
<input
name="vorname"
type="text"
bind:value={user.vorname}
required
/>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte Geben Sie hier den Vornamen des Ansprechpartners&nbsp;ein. Bitte Geben Sie hier den Vornamen des Ansprechpartners&nbsp;ein.
</HelpLabel> </HelpLabel>
</div> </div>
</div> </div>
<!-- Nachname * -->
<!-- Nachname * --> <div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="Nachname *"></Inputlabel>
<div class="input-standard order-2 md:order-2 xl:order-2"> <input name="name" type="text" bind:value={user.name} required />
<Inputlabel title="Nachname *"></Inputlabel>
<input
name="name"
type="text"
bind:value={user.name}
required
/>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte Geben Sie hier den Nachnamen des Ansprechpartners&nbsp;ein. Bitte Geben Sie hier den Nachnamen des
</HelpLabel> Ansprechpartners&nbsp;ein.
</div> </HelpLabel>
</div> </div>
</div>
<!-- Telefon & Email * --> <!-- Telefon & Email * -->
<div class="input-standard order-3 md:order-3 xl:order-3"> <div class="input-standard order-3 md:order-3 xl:order-3">
<Inputlabel title="Telefonnummer *"></Inputlabel> <Inputlabel title="Telefonnummer *"></Inputlabel>
<input <input name="telefon" bind:value={user.telefon} type="text" />
name="telefon"
bind:value={user.telefon}
type="text"
/>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte Geben Sie hier die Telefonnummer des Ansprechpartners&nbsp;ein. Bitte Geben Sie hier die Telefonnummer des
</HelpLabel> Ansprechpartners&nbsp;ein.
</div> </HelpLabel>
</div>
</div>
</div> </div>
</div>

View File

@@ -48,7 +48,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required required
data-cy="ausstellgrund" data-cy="ausstellgrund"
> >
<option disabled selected value={null}>Bitte auswählen</option> <option disabled selected value>Bitte auswählen</option>
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]} {#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
<option value={ausstellgrund}>{name}</option> <option value={ausstellgrund}>{name}</option>
{/each} {/each}
@@ -72,7 +72,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required required
bind:value={aufnahme.gebaeudetyp} bind:value={aufnahme.gebaeudetyp}
> >
<option disabled selected value={null}>Bitte auswählen</option> <option disabled selected value>Bitte auswählen</option>
{#if ausweisart==Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen} {#if ausweisart==Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
<option value="Einfamilienhaus">Einfamilienhaus</option> <option value="Einfamilienhaus">Einfamilienhaus</option>
@@ -224,7 +224,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
required required
bind:value={aufnahme.saniert} bind:value={aufnahme.saniert}
> >
<option disabled selected value={null}>Bitte auswählen</option> <option disabled selected value>Bitte auswählen</option>
<option value={true}>saniert</option> <option value={true}>saniert</option>
<option value={false}>unsaniert</option> <option value={false}>unsaniert</option>
</select> </select>

View File

@@ -1,104 +1,105 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import ZipSearch from "#components/PlzSuche.svelte"; import ZipSearch from "#components/PlzSuche.svelte";
import { Enums } from "#lib/client/prisma.js" import { Enums } from "#lib/client/prisma.js";
import { AufnahmeClient, ObjektClient } from "./types.js"; import { AufnahmeClient, ObjektClient } from "./types.js";
export let aufnahme: AufnahmeClient; export let aufnahme: AufnahmeClient;
export let objekt: ObjektClient; export let objekt: ObjektClient;
export let ausweisart: Enums.Ausweisart; export let ausweisart: Enums.Ausweisart;
</script> </script>
<div id="gebaeudedaten" class="bereich-box grid <div
id="gebaeudedaten"
class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-8 grid-cols-1 gap-x-4 gap-y-8
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8 sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8 xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
"> "
>
<!-- Straße, Hausnummer * -->
<!-- Straße, Hausnummer * --> <div class="input-standard order-1 md:order-1 xl:order-1">
<Inputlabel title="Straße, Hausnummer *"></Inputlabel>
<div class="input-standard order-1 md:order-1 xl:order-1"> <input
<Inputlabel title="Straße, Hausnummer *"></Inputlabel> name="adresse"
data-test="adresse"
<input type="text"
name="adresse" autocomplete="off"
data-test="adresse" required
type="text" data-msg-minlength="min. 5 Zeichen"
autocomplete="off" data-msg-maxlength="max. 40 Zeichen"
required bind:value={objekt.adresse}
data-msg-minlength="min. 5 Zeichen"
data-msg-maxlength="max. 40 Zeichen"
bind:value={objekt.adresse}
/>
<div class="help-label">
<HelpLabel>
Straße und Hausnummer des betrachteten Gebäudes. Die Angaen werden auf dem Energieausweis vermerkt.
</HelpLabel>
</div>
</div>
<!-- PLZ / ORT -->
<div class="grid grid-cols-[2fr_6fr] gap-x-4 order-2 md:order-2 xl:order-2 relative">
<div class="input-noHelp">
<Inputlabel title="PLZ *"></Inputlabel>
<ZipSearch
bind:zip={objekt.plz}
bind:city={objekt.ort}
name="plz"
/>
</div>
<div class="input-standard">
<Inputlabel title="Ort *"></Inputlabel>
<input
name="ort"
data-test="ort"
readonly={false}
bind:value={objekt.ort}
type="text"
/> />
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte geben Sie die PLZ des betrachteten Gebäudes ein, der Ort wird dann angezeigt und kann ausgewählt werden. Straße und Hausnummer des betrachteten Gebäudes. Die Angaen
Die Angaen werden auf dem Energieausweis vermerkt. werden auf dem Energieausweis vermerkt.
</HelpLabel> </HelpLabel>
</div> </div>
</div> </div>
<!-- PLZ / ORT -->
<div
class="grid grid-cols-[2fr_6fr] gap-x-4 order-2 md:order-2 xl:order-2 relative"
>
<div class="input-noHelp">
<Inputlabel title="PLZ *"></Inputlabel>
</div> <ZipSearch
bind:zip={objekt.plz}
bind:city={objekt.ort}
name="plz"
/>
</div>
{#if ausweisart=="VerbrauchsausweisWohnen"} <div class="input-standard">
<!-- Wohnfläche m² * --> <Inputlabel title="Ort *"></Inputlabel>
<div class="input-standard order-3 md:order-3 xl:order-3"> <input
<Inputlabel title="Wohnfläche m² *"></Inputlabel> name="ort"
data-test="ort"
readonly={false}
required
bind:value={objekt.ort}
type="text"
/>
<input <div class="help-label">
name="flaeche" <HelpLabel>
data-test="flaeche" Bitte geben Sie die PLZ des betrachteten Gebäudes ein, der
maxlength="4" Ort wird dann angezeigt und kann ausgewählt werden. Die
type="number" Angaen werden auf dem Energieausweis vermerkt.
required </HelpLabel>
autocomplete="off" </div>
data-rule-minlength="2" </div>
data-msg-minlength="min. 2 Zeichen" </div>
bind:value={aufnahme.flaeche}
/>
<div class="help-label"> {#if ausweisart == "VerbrauchsausweisWohnen"}
<!-- Wohnfläche m² * -->
<div class="input-standard order-3 md:order-3 xl:order-3">
<Inputlabel title="Wohnfläche m² *"></Inputlabel>
<input
name="flaeche"
data-test="flaeche"
maxlength="4"
type="number"
required
autocomplete="off"
data-rule-minlength="2"
data-msg-minlength="min. 2 Zeichen"
bind:value={aufnahme.flaeche}
/>
<div class="help-label">
<HelpLabel> <HelpLabel>
Bitte geben Sie hier die beheizte Wohnfläche in m² ein. Bitte geben Sie hier die beheizte Wohnfläche in m² ein.
Dabei handelt es sich um die Wohnfläche abzüglich Dabei handelt es sich um die Wohnfläche abzüglich
@@ -106,91 +107,92 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
befinden. (Balkone, Terassen,etc.). befinden. (Balkone, Terassen,etc.).
</HelpLabel> </HelpLabel>
</div> </div>
</div> </div>
{/if}
{/if} <!-- Dachgeschoss *-->
<!-- Dachgeschoss *--> <div class="input-standard order-4 md:order-2 xl:order-4">
<Inputlabel title="Dachgeschoss *"></Inputlabel>
<div class="input-standard order-4 md:order-2 xl:order-4"> <select
<Inputlabel title="Dachgeschoss *"></Inputlabel> name="dachgeschoss"
data-test="dachgeschoss"
<select bind:value={aufnahme.dachgeschoss}
name="dachgeschoss" required
data-test="dachgeschoss" >
bind:value={aufnahme.dachgeschoss} <option disabled selected value>Bitte auswählen</option>
required <option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
> >nicht vorhanden</option
<option disabled selected value={null}>Bitte auswählen</option> >
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option> <option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option> <option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
</select> </select>
<div class="help-label">
<HelpLabel>
Bei Obergeschoss mit vorhandenen Dachschrägen oder ausgebautem Dachgeschoss beheizt auswählen.
Bei Kaltdächern oder unausgebautem Dachgeschoss bitte unbeheizt auswählen. Bei Flachdächern wird nicht vorhanden ausgewählt.
</HelpLabel>
</div>
</div>
<!-- Keller * -->
<div class="input-standard order-4 md:order-2 xl:order-4">
<Inputlabel title="Keller *"></Inputlabel>
<select
name="keller"
data-test="keller"
required
bind:value={aufnahme.keller}
>
<option disabled selected value={false}>Bitte auswählen</option>
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
</select>
<div class="help-label">
<HelpLabel>
Diese Angabe hat folgenden Einfluss.<br>
<b>Keller beheizt:<br>Nutzfläche = Wohnfläche x 1,35.</b>
<b>Keller unbeheizt:<br>Nutzfläche = Wohnfläche x 1,2.</b>
Dies ist nur zulässig wenn die Nutzfläche unbekannt ist. Geben Sie diese daher unbedingt im nächsten Feld ein wenn bekannt.
</HelpLabel>
</div>
</div>
<!-- Gesamtfläche * -->
<div class="input-standard order-6 md:order-6 xl:order-6">
<Inputlabel title="Nutzfläche m² *"></Inputlabel>
<input
name="nutzflaeche"
data-test="nutzflaeche"
maxlength="4"
type="number"
required
autocomplete="off"
data-rule-minlength="2"
data-msg-minlength="min. 2 Zeichen"
bind:value={aufnahme.nutzflaeche}
/>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte geben Sie hier die beheizte Gesamtfläche in m² ein Bei Obergeschoss mit vorhandenen Dachschrägen oder ausgebautem
(wenn bekannt). Dabei handelt es sich um die Wohnfläche + Dachgeschoss beheizt auswählen. Bei Kaltdächern oder
weiterer Flächen innerhalb des Gebäudes (z.B. Fläche des unausgebautem Dachgeschoss bitte unbeheizt auswählen. Bei
beheizten Kellers). <b>Diese Fläche wird dann im Energieausweis Flachdächern wird nicht vorhanden ausgewählt.
als energetische Nutzfläche (An) ausgewiesen.</b> </HelpLabel>
</HelpLabel> </div>
</div> </div>
<!-- Keller * -->
<div class="input-standard order-4 md:order-2 xl:order-4">
<Inputlabel title="Keller *"></Inputlabel>
<select
name="keller"
data-test="keller"
required
bind:value={aufnahme.keller}
>
<option disabled selected value>Bitte auswählen</option>
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
>nicht vorhanden</option
>
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
</select>
<div class="help-label">
<HelpLabel>
Diese Angabe hat folgenden Einfluss.<br />
<b>Keller beheizt:<br />Nutzfläche = Wohnfläche x 1,35.</b>
<b>Keller unbeheizt:<br />Nutzfläche = Wohnfläche x 1,2.</b>
Dies ist nur zulässig wenn die Nutzfläche unbekannt ist. Geben Sie
diese daher unbedingt im nächsten Feld ein wenn bekannt.
</HelpLabel>
</div>
</div>
<!-- Gesamtfläche * -->
<div class="input-standard order-6 md:order-6 xl:order-6">
<Inputlabel title="Nutzfläche m² *"></Inputlabel>
<input
name="nutzflaeche"
data-test="nutzflaeche"
maxlength="4"
type="number"
required
bind:value={aufnahme.nutzflaeche}
/>
<div class="help-label">
<HelpLabel>
Bitte geben Sie hier die beheizte Gesamtfläche in m² ein (wenn
bekannt). Dabei handelt es sich um die Wohnfläche + weiterer
Flächen innerhalb des Gebäudes (z.B. Fläche des beheizten
Kellers). <b
>Diese Fläche wird dann im Energieausweis als energetische
Nutzfläche (An) ausgewiesen.</b
>
</HelpLabel>
</div>
</div>
</div> </div>
</div>

View File

@@ -1,137 +1,123 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import { AufnahmeClient } from "./types.js"; import { AufnahmeClient } from "./types.js";
export let aufnahme: AufnahmeClient; export let aufnahme: AufnahmeClient;
</script> </script>
<div id="lueftungundleerstand" class="bereich-box grid <div
id="lueftungundleerstand"
class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-8 grid-cols-1 gap-x-4 gap-y-8
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8 sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8 xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
"> "
>
<!-- Gebäudeteil -->
<div class="grid grid-cols-2 gap-x-4 order-2 md:order-2 xl:order-2">
<div class="input-standard">
<Inputlabel title="Gebäudeteil *"></Inputlabel>
<select
name="gebaeudeteil"
data-test="gebaeudeteil"
bind:value={aufnahme.gebaeudeteil}
required
>
<option disabled selected value>Bitte auswählen</option>
<option value="Gesamtgebäude">Gesamtgebäude</option>
<option value="Wohnen">Wohnen</option>
</select>
<!-- Gebäudeteil --> <div class="help-label">
<HelpLabel>
Bitte geben Sie hier den Gebäudeteil ein. In den meisten
Fällen handelt es sich um das Gesamtgebäude. Sollte es sich
allerdings um ein Gebäude mit mehr als 10% Gewerbeanteil
handeln, so sollten 2 Ausweise erstellt werden. In diesem
Fall wählen Sie Gebäudeteil 'Wohnen' bzw. Gebäudeteil
'Gewerbe'.
</HelpLabel>
</div>
</div>
<div class="grid grid-cols-2 gap-x-4 order-2 md:order-2 xl:order-2"> <div class="input-standard">
<Inputlabel title="Leerstand in %"></Inputlabel>
<div class="input-standard"> <input
<Inputlabel title="Gebäudeteil *"></Inputlabel> name="leerstand"
data-test="leerstand"
<select maxlength="2"
name="gebaeudeteil" type="number"
data-test="gebaeudeteil" bind:value={aufnahme.leerstand}
bind:value={aufnahme.gebaeudeteil} />
required
>
<option disabled selected value={null}>Bitte auswählen</option>
<option value="Gesamtgebäude">Gesamtgebäude</option>
<option value="Wohnen">Wohnen</option>
</select>
<div class="help-label">
<HelpLabel>
Bitte geben Sie hier den Gebäudeteil ein. In den meisten
Fällen handelt es sich um das Gesamtgebäude. Sollte es sich
allerdings um ein Gebäude mit mehr als 10% Gewerbeanteil
handeln, so sollten 2 Ausweise erstellt werden. In diesem
Fall wählen Sie Gebäudeteil 'Wohnen' bzw. Gebäudeteil
'Gewerbe'.
</HelpLabel>
</div>
</div>
<div class="input-standard"> <div class="help-label">
<Inputlabel title="Leerstand in %"></Inputlabel>
<input
name="leerstand"
data-test="leerstand"
maxlength="2"
type="number"
bind:value={aufnahme.leerstand}
/>
<div class="help-label">
<HelpLabel> <HelpLabel>
Bitte geben Sie hier den Leerstand in % des Gesamtzeitraumes Bitte geben Sie hier den Leerstand in % des Gesamtzeitraumes
(3 Jahre) ein. Zum Beispiel 4 Monate Leerstand in 36 Monaten (3 Jahre) ein. Zum Beispiel 4 Monate Leerstand in 36 Monaten
wären dann ca. 11%. wären dann ca. 11%.
</HelpLabel> </HelpLabel>
</div>
</div> </div>
</div> </div>
</div> <!-- Lüftung -->
<!-- Lüftung --> <div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="Lüftung durch *"></Inputlabel>
<div class="input-standard order-2 md:order-2 xl:order-2"> <select
<Inputlabel title="ftung durch *"></Inputlabel> name="lueftung"
data-test="lueftung"
<select required
name="lueftung" bind:value={aufnahme.lueftung}
data-test="lueftung" >
required <option disabled selected value>Bitte auswählen</option>
bind:value={aufnahme.lueftung} <option value="Fensterlueftung">Fensterlüftung</option>
> <option value="Schachtlueftung">Schachtlüftung</option>
<option disabled selected value={null}>Bitte auswählen</option> <option value="LueftungsanlageOhneWaermerueckgewinnung"
<option value="Fensterlueftung">Fensterlüftung</option> >Lüftungsanlage ohne Wärmerückgewinnung</option
<option value="Schachtlueftung">Schachtlüftung</option> >
<option value="LueftungsanlageOhneWaermerueckgewinnung" <option value="LueftungsanlageMitWaermerueckgewinnung"
>Lüftungsanlage ohne Wärmerückgewinnung</option >Lüftungsanlage mit Wärmerückgewinnung</option
> >
<option value="LueftungsanlageMitWaermerueckgewinnung" </select>
>Lüftungsanlage mit Wärmerückgewinnung</option
>
</select>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte geben Sie hier den Gebäudeteil ein. In den meisten Bitte geben Sie hier den Gebäudeteil ein. In den meisten Fällen
Fällen handelt es sich um das Gesamtgebäude. Sollte es sich handelt es sich um das Gesamtgebäude. Sollte es sich allerdings
allerdings um ein Gebäude mit mehr als 10% Gewerbeanteil um ein Gebäude mit mehr als 10% Gewerbeanteil Bitte geben Sie
Bitte geben Sie hier ein ob über die Fenster natürlich hier ein ob über die Fenster natürlich belüftet wird oder über
belüftet wird oder über eine Lüftungsanlage. eine Lüftungsanlage.
</HelpLabel> </HelpLabel>
</div> </div>
</div> </div>
<!-- Kühlung --> <!-- Kühlung -->
<div class="input-standard order-2 md:order-2 xl:order-2"> <div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="Anlage Kühlung *"></Inputlabel> <Inputlabel title="Anlage Kühlung *"></Inputlabel>
<select <select
name="kuehlung" name="kuehlung"
data-test="kuehlung" data-test="kuehlung"
required required
bind:value={aufnahme.kuehlung} bind:value={aufnahme.kuehlung}
> >
<option disabled selected value={null}>Bitte auswählen</option> <option disabled selected value>Bitte auswählen</option>
<option value="1">vorhanden</option> <option value="1">vorhanden</option>
<option value="0">nicht vorhanden</option> <option value="0">nicht vorhanden</option>
</select> </select>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>
Bitte geben Sie an ob das Gebäude im Sommer zusätzlich Bitte geben Sie an ob das Gebäude im Sommer zusätzlich gekühlt
gekühlt wird. wird.
</HelpLabel> </HelpLabel>
</div> </div>
</div>
</div> </div>
</div>

View File

@@ -236,7 +236,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
bind:value={aufnahme.brennstoff_1} bind:value={aufnahme.brennstoff_1}
required required
> >
<option disabled selected >Bitte auswählen</option> <option disabled selected value>Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel} {#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option> <option value={fuel}>{fuel}</option>
{/each} {/each}
@@ -276,7 +276,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
disabled={!aufnahme.brennstoff_1} disabled={!aufnahme.brennstoff_1}
required required
> >
<option disabled selected>Bitte auswählen</option> <option disabled selected value>Bitte auswählen</option>
{#each fuelMap.hasOwnProperty(aufnahme.brennstoff_1) ? fuelMap[aufnahme.brennstoff_1] : [] as unit} {#each fuelMap.hasOwnProperty(aufnahme.brennstoff_1) ? fuelMap[aufnahme.brennstoff_1] : [] as unit}
<option value={unit}>{unit}</option> <option value={unit}>{unit}</option>
{/each} {/each}

View File

@@ -1,203 +1,188 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte";
import HelpLabel from "#components/labels/HelpLabel.svelte"; export let ausweis;
import Inputlabel from "#components/labels/InputLabel.svelte";
export let ausweis; $: {
if (!ausweis.warmwasser_enthalten) {
$: { ausweis.warmwasser_anteil_bekannt = false;
if (!ausweis.warmwasser_enthalten) { }
ausweis.warmwasser_anteil_bekannt = false;
} }
}
</script> </script>
<div id="warmwasser" class="bereich-box grid <div
id="warmwasser"
class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-8 grid-cols-1 gap-x-4 gap-y-8
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8 sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8 xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
"> "
>
<div class="input-standard order-1 md:order-1 xl:order-1"> <div class="input-standard order-1 md:order-1 xl:order-1">
<Inputlabel title="Warmwasser im Verbrauch enthalten"></Inputlabel> <Inputlabel title="Warmwasser im Verbrauch enthalten"></Inputlabel>
<div class="input-row items-center gap-2"> <div class="input-row items-center gap-2">
<div
<div class="grid grid-cols-[25px_max-content] items-center justify-items-start"> class="grid grid-cols-[25px_max-content] items-center justify-items-start"
<input >
id="warmwasser_enthalten" <input
type="checkbox" id="warmwasser_enthalten"
class="checkbox" type="checkbox"
name="warmwasser_enthalten" class="checkbox"
data-test="warmwasser_enthalten" name="warmwasser_enthalten"
bind:checked={ausweis.warmwasser_enthalten} data-test="warmwasser_enthalten"
/> bind:checked={ausweis.warmwasser_enthalten}
<label for="warmwasser_enthalten" class="cursor-pointer">Ja</label> />
</div> <label for="warmwasser_enthalten" class="cursor-pointer"
>Ja</label
<div class="grid grid-cols-[25px_max-content] items-center justify-items-start"> >
<input
id="warmwasser_anteil_bekannt"
type="checkbox"
class="checkbox"
name="warmwasser_anteil_bekannt"
data-test="warmwasser_anteil_bekannt"
bind:checked={ausweis.warmwasser_anteil_bekannt}
disabled={!ausweis.warmwasser_enthalten}
/>
<label for="warmwasser_anteil_bekannt" class="cursor-pointer">Anteil bekannt</label>
</div>
</div>
<div class="help-label">
<HelpLabel>
TEXT FEHLT
</HelpLabel>
</div>
</div>
<!-- % Anteil Warmwasser -->
<div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="% Anteil Warmwasser"></Inputlabel>
<input
name="anteil_warmwasser_1"
data-test="anteil_warmwasser_1"
maxlength="2"
type="number"
bind:value={ausweis.anteil_warmwasser_1}
disabled={!ausweis.warmwasser_anteil_bekannt ||
!ausweis.warmwasser_enthalten}
autocomplete="off"
/>
<div class="help-label">
<HelpLabel>
Wenn bekannt geben Sie den Anteil der Warmwasser-Versorgung
hier ein. Standardmäßig wird ein Anteil von 18% angenommen.
</HelpLabel>
</div> </div>
</div>
<div
<!--zusätzliche Heizquelle --> class="grid grid-cols-[25px_max-content] items-center justify-items-start"
>
<div class="input-standard order-3 md:order-3 xl:order-3"> <input
<Inputlabel title="zusätzliche Heizquelle"></Inputlabel> id="warmwasser_anteil_bekannt"
type="checkbox"
<input class="checkbox"
name="anteil_warmwasser_2" name="warmwasser_anteil_bekannt"
data-test="anteil_warmwasser_2" data-test="warmwasser_anteil_bekannt"
maxlength="3" bind:checked={ausweis.warmwasser_anteil_bekannt}
type="number" disabled={!ausweis.warmwasser_enthalten}
autocomplete="off" />
bind:value={ausweis.anteil_warmwasser_2} <label for="warmwasser_anteil_bekannt" class="cursor-pointer"
disabled={!ausweis.zusaetzliche_heizquelle || >Anteil bekannt</label
!ausweis.warmwasser_anteil_bekannt || >
!ausweis.warmwasser_enthalten} </div>
/> </div>
<div class="help-label"> <div class="help-label">
<HelpLabel> <HelpLabel>TEXT FEHLT</HelpLabel>
Wenn bekannt geben Sie den Anteil der Warmwasser-Versorgung
von der zusätzlichen Heizquelle hier ein. Standardmäßig wird
ein Anteil von 18% angenommen.
</HelpLabel>
</div> </div>
</div>
<!-- % Anteil Warmwasser -->
<div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="% Anteil Warmwasser"></Inputlabel>
<input
name="anteil_warmwasser_1"
data-test="anteil_warmwasser_1"
maxlength="2"
type="number"
bind:value={ausweis.anteil_warmwasser_1}
disabled={!ausweis.warmwasser_anteil_bekannt ||
!ausweis.warmwasser_enthalten}
autocomplete="off"
/>
<div class="help-label">
<HelpLabel>
Wenn bekannt geben Sie den Anteil der Warmwasser-Versorgung hier
ein. Standardmäßig wird ein Anteil von 18% angenommen.
</HelpLabel>
</div>
</div>
<!--zusätzliche Heizquelle -->
<div class="input-standard order-3 md:order-3 xl:order-3">
<Inputlabel title="zusätzliche Heizquelle"></Inputlabel>
<input
name="anteil_warmwasser_2"
data-test="anteil_warmwasser_2"
maxlength="3"
type="number"
autocomplete="off"
bind:value={ausweis.anteil_warmwasser_2}
disabled={!ausweis.zusaetzliche_heizquelle ||
!ausweis.warmwasser_anteil_bekannt ||
!ausweis.warmwasser_enthalten}
/>
<div class="help-label">
<HelpLabel>
Wenn bekannt geben Sie den Anteil der Warmwasser-Versorgung von
der zusätzlichen Heizquelle hier ein. Standardmäßig wird ein
Anteil von 18% angenommen.
</HelpLabel>
</div>
</div>
<!--Alternative Energieversorgungssyteme -->
<div
class="input-standard order-4 md:order-4 xl:order-4 sm:col-span-2 items-center"
>
<Inputlabel title="Alternative Energieversorgungssyteme"></Inputlabel>
<div class="input-row items-center gap-2 lg:gap-20 xl:gap-24">
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_heizung"
type="checkbox"
name="alternative_heizung"
data-test="alternative_heizung"
bind:checked={ausweis.alternative_heizung}
value="Heizung"
/>
<label
for="alternative_heizung"
class="checkbox-inline cursor-pointer">Heizung</label
>
</div>
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_warmwasser"
type="checkbox"
name="alternative_warmwasser"
data-test="alternative_warmwasser"
bind:checked={ausweis.alternative_warmwasser}
value="Warmwasser"
/>
<label
for="alternative_warmwasser"
class="checkbox-inline cursor-pointer">Warmwasser</label
>
</div>
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_lueftung"
type="checkbox"
name="alternative_lueftung"
data-test="alternative_lueftung"
bind:checked={ausweis.alternative_lueftung}
value="Lüftung"
/>
<label
for="alternative_lueftung"
class="checkbox-inline cursor-pointer">Lüftung</label
>
</div>
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_kuehlung"
type="checkbox"
name="alternative_kuehlung"
data-test="alternative_kuehlung"
bind:checked={ausweis.alternative_kuehlung}
value="Kühlung"
/>
<label
for="alternative_kuehlung"
class="checkbox-inline cursor-pointer">Kühlung</label
>
</div>
</div>
<div class="help-label">
<HelpLabel></HelpLabel>
</div>
</div>
</div> </div>
<!--Alternative Energieversorgungssyteme -->
<div class="input-standard order-4 md:order-4 xl:order-4 sm:col-span-2 items-center">
<Inputlabel title="Alternative Energieversorgungssyteme"></Inputlabel>
<div class="input-row items-center gap-2 lg:gap-20 xl:gap-24">
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_heizung"
type="checkbox"
name="alternative_heizung"
data-test="alternative_heizung"
bind:checked={ausweis.alternative_heizung}
value="Heizung"
/>
<label for="alternative_heizung" class="checkbox-inline cursor-pointer">Heizung</label>
</div>
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_warmwasser"
type="checkbox"
name="alternative_warmwasser"
data-test="alternative_warmwasser"
bind:checked={ausweis.alternative_warmwasser}
value="Warmwasser"
/>
<label for="alternative_warmwasser" class="checkbox-inline cursor-pointer">Warmwasser</label>
</div>
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_lueftung"
type="checkbox"
name="alternative_lueftung"
data-test="alternative_lueftung"
bind:checked={ausweis.alternative_lueftung}
value="Lüftung"
/>
<label for="alternative_lueftung" class="checkbox-inline cursor-pointer">Lüftung</label>
</div>
<div class="grid grid-cols-[max-content_40px] gap-2 items-center">
<input
id="alternative_kuehlung"
type="checkbox"
name="alternative_kuehlung"
data-test="alternative_kuehlung"
bind:checked={ausweis.alternative_kuehlung}
value="Kühlung"
/>
<label for="alternative_kuehlung" class="checkbox-inline cursor-pointer">Kühlung</label>
</div>
</div>
<div class="help-label">
<HelpLabel>
</HelpLabel>
</div>
</div>
</div>

View File

@@ -6,25 +6,28 @@
async function showTicketPopup() { async function showTicketPopup() {
const success = await dialogs.modal(TicketPopup); const success = await dialogs.modal(TicketPopup);
if (success) { console.log(success);
if (success === true) {
dialogs.alert({ dialogs.alert({
title: "Ticket erstellt", title: "Ticket erstellt",
text: "Ihr Support Ticket wurde erfolgreich erstellt. Wir werden uns schnellstmöglich um ihre Angelegenheit kümmern. Vielen Dank für ihre Geduld.", text: "Ihr Support Ticket wurde erfolgreich erstellt. Wir werden uns schnellstmöglich um ihre Angelegenheit kümmern. Vielen Dank für ihre Geduld.",
dismissButtonText: "Schließen", dismissButtonText: "Schließen",
dismissButtonClass: "btn btn-primary", dismissButtonClass: "button",
dialogClass: "modal-box", dialogClass: "bg-white rounded-lg p-4",
headerClass: "bg-base-100 text-center", headerClass: "bg-base-100 text-center",
titleClass: "text-base-content text-xl font-medium", titleClass: "text-base-content text-xl font-medium",
dividerClass: "hidden", dividerClass: "hidden",
footerClass: "bg-base-100 justify-center gap-4 mt-4", footerClass: "bg-base-100 justify-center gap-4 mt-4",
}); });
} else { } else if (success === false) {
dialogs.alert({ dialogs.alert({
title: "Ticket erstellen fehlgeschlagen", title: "Ticket erstellen fehlgeschlagen",
text: "Leider ist beim erstellen des Tickets ein Fehler aufgetreten. Bitte versuchen sie es später erneut oder kontaktieren sie uns direkt per email unter info@ib-cornelsen.de.", text: "Leider ist beim erstellen des Tickets ein Fehler aufgetreten. Bitte versuchen sie es später erneut oder kontaktieren sie uns direkt per email unter info@ib-cornelsen.de.",
dismissButtonText: "Schließen", dismissButtonText: "Schließen",
dismissButtonClass: "btn btn-error", dismissButtonClass: "button",
dialogClass: "modal-box", dialogClass: "bg-white rounded-lg p-4",
headerClass: "bg-base-100 text-center", headerClass: "bg-base-100 text-center",
titleClass: "text-base-content text-xl font-medium", titleClass: "text-base-content text-xl font-medium",
dividerClass: "hidden", dividerClass: "hidden",
@@ -35,7 +38,7 @@
</script> </script>
<button <button
class="btn btn-primary fixed bottom-0 right-8 rounded-b-none rounded-t-xl w-48 h-12 text-xl hover:h-14 transition-all" class="fixed bottom-0 right-8 rounded-b-none rounded-t-xl w-48 h-12 text-xl hover:h-14 transition-all bg-primary text-primary-content font-bold"
on:click={showTicketPopup} on:click={showTicketPopup}
>Support Ticket</button >Support Ticket</button
> >

View File

@@ -44,9 +44,7 @@
<h4>Kategorie *</h4> <h4>Kategorie *</h4>
<select class="select select-bordered" bind:value={category}> <select class="select select-bordered" bind:value={category}>
<option value={null} disabled selected>Bitte Auswählen</option> <option value={null} disabled selected>Bitte Auswählen</option>
<option value="Verständnisproblem">Verständnisproblem</option>
<option value="Technischer Fehler">Technischer Fehler</option> <option value="Technischer Fehler">Technischer Fehler</option>
<option value="Feature anfordern">Feature anfordern</option>
<option value="Fehlende Funktionalität" <option value="Fehlende Funktionalität"
>Fehlende Funktionalität</option >Fehlende Funktionalität</option
> >

View File

@@ -1,5 +1,12 @@
--- ---
import { BenutzerClient } from "#components/Ausweis/types";
import HeaderLogin from "#components/design/header/HeaderLogin.svelte"; import HeaderLogin from "#components/design/header/HeaderLogin.svelte";
export type Props = {
user: BenutzerClient | null
}
const { user } = Astro.props;
--- ---
<header id="header" class="hidden sm:block"> <header id="header" class="hidden sm:block">
@@ -63,7 +70,7 @@ lg:px-0 lg:gap-x-4">
<div class="w-full justify-self-center"> <div class="w-full justify-self-center">
<HeaderLogin client:load /> <HeaderLogin {user} client:load />
</div> </div>

View File

@@ -1,8 +1,11 @@
<script lang="ts"> <script lang="ts">
import { BenutzerClient } from "#components/Ausweis/types.js";
import { loginClient } from "#lib/login.js"; import { loginClient } from "#lib/login.js";
import { CrossCircled } from "radix-svelte-icons"; import { CrossCircled } from "radix-svelte-icons";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
export let user: BenutzerClient | null;
let email: string; let email: string;
let passwort: string; let passwort: string;
@@ -24,6 +27,7 @@
id="card-login" id="card-login"
class="rounded-none lg:rounded-lg lg:card lg:box lg:ring-2 border-t-2 lg:border-none border-gray-500/50 ring-gray-500/50 xs:px-2 md:px-4 py-2" class="rounded-none lg:rounded-lg lg:card lg:box lg:ring-2 border-t-2 lg:border-none border-gray-500/50 ring-gray-500/50 xs:px-2 md:px-4 py-2"
> >
{#if !user}
<form on:submit={login}> <form on:submit={login}>
<div class="grid grid-cols-[1fr] xs:grid-cols-[2fr_2fr_1fr] gap-2"> <div class="grid grid-cols-[1fr] xs:grid-cols-[2fr_2fr_1fr] gap-2">
<input <input
@@ -82,6 +86,19 @@
</div> </div>
</div> </div>
</form> </form>
{:else}
<div class="flex flex-row gap-4 items-center">
<img src={user.profilbild || "/images/profile-placeholder.png"} class="w-14 h-14 rounded-full border">
<div class="flex flex-col">
<span class="text-base font-bold">{user.vorname} {user.name}</span>
<span class="text-black text-opacity-50">{user.email}</span>
<div class="flex flex-row gap-4">
<a href="/dashboard" class="text-sm">Dashboard</a>
<a href="/auth/logout" class="text-sm">Ausloggen</a>
</div>
</div>
</div>
{/if}
</div> </div>
<style lang="postcss"> <style lang="postcss">

View File

@@ -6,6 +6,9 @@ import Header from "#components/design/header/Header.astro";
import Footer from "#components/design/footer/Footer.astro"; import Footer from "#components/design/footer/Footer.astro";
import SidebarLeft from "#components/design/sidebars/SidebarLeft.astro"; import SidebarLeft from "#components/design/sidebars/SidebarLeft.astro";
import { NotificationWrapper } from "@ibcornelsen/ui"; import { NotificationWrapper } from "@ibcornelsen/ui";
import { getCurrentUser } from "#lib/server/user";
const user = await getCurrentUser(Astro)
export interface Props { export interface Props {
title: string; title: string;
@@ -115,7 +118,7 @@ const { title } = Astro.props;
</head> </head>
<body> <body>
<Header /> <Header {user} />
<main <main
class="w-full p-0 grid class="w-full p-0 grid

View File

@@ -6,6 +6,10 @@ import Footer from "#components/design/footer/Footer.astro";
import SidebarLeft from "#components/design/sidebars/SidebarLeft.astro"; import SidebarLeft from "#components/design/sidebars/SidebarLeft.astro";
import SidebarRight from "#components/design/sidebars/SidebarRight.astro"; import SidebarRight from "#components/design/sidebars/SidebarRight.astro";
import { NotificationWrapper } from "@ibcornelsen/ui"; import { NotificationWrapper } from "@ibcornelsen/ui";
import TicketButton from "#components/Tickets/TicketButton.svelte";
import { getCurrentUser } from "#lib/server/user";
const user = await getCurrentUser(Astro);
export interface Props { export interface Props {
title: string; title: string;
@@ -94,7 +98,7 @@ window.addEventListener("scroll", (event) => {
<body> <body>
<Header /> <Header {user} />
<main id="main" <main id="main"
class="w-full p-0 grid class="w-full p-0 grid
@@ -119,6 +123,7 @@ window.addEventListener("scroll", (event) => {
<Footer /> <Footer />
<NotificationWrapper client:load /> <NotificationWrapper client:load />
<TicketButton client:load></TicketButton>
</body> </body>
</html> </html>

View File

@@ -6,8 +6,6 @@
import Rechnungsadresse from "#components/Ausweis/Rechnungsadresse.svelte"; import Rechnungsadresse from "#components/Ausweis/Rechnungsadresse.svelte";
import type { Bezahlmethoden } from "#lib/client/prisma.js"; import type { Bezahlmethoden } from "#lib/client/prisma.js";
import { Enums } from "#lib/client/prisma.js"; import { Enums } from "#lib/client/prisma.js";
import { dialogs } from "svelte-dialogs";
import LoginDialog from "#components/LoginDialog.svelte";
import { import {
API_ACCESS_TOKEN_COOKIE_NAME, API_ACCESS_TOKEN_COOKIE_NAME,
PRICES, PRICES,
@@ -31,8 +29,7 @@
import { addNotification } from "#components/Notifications/shared.js"; import { addNotification } from "#components/Notifications/shared.js";
import NotificationWrapper from "#components/Notifications/NotificationWrapper.svelte"; import NotificationWrapper from "#components/Notifications/NotificationWrapper.svelte";
import { nachweisSpeichern } from "#client/lib/nachweisSpeichern.js"; import { nachweisSpeichern } from "#client/lib/nachweisSpeichern.js";
import { EnterFullScreen } from "radix-svelte-icons";
export let user: Partial<BenutzerClient>; export let user: Partial<BenutzerClient>;
export let ausweis: VerbrauchsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient;
export let aufnahme: AufnahmeClient; export let aufnahme: AufnahmeClient;

View File

@@ -1,7 +1,6 @@
import { z } from "zod"; import { z } from "zod";
import { TicketsSchema, prisma } from "#lib/server/prisma"; import { TicketsSchema, prisma } from "#lib/server/prisma.js";
import { defineApiRoute } from "astro-typesafe-api/server"; import { defineApiRoute } from "astro-typesafe-api/server";
import { maybeAuthorizationMiddleware } from "#lib/middleware/authorization.js";
import { UUidWithPrefix } from "#components/Ausweis/types.js"; import { UUidWithPrefix } from "#components/Ausweis/types.js";
export const PUT = defineApiRoute({ export const PUT = defineApiRoute({
@@ -26,37 +25,9 @@ export const PUT = defineApiRoute({
output: z.object({ output: z.object({
uid: UUidWithPrefix, uid: UUidWithPrefix,
}), }),
middleware: maybeAuthorizationMiddleware, async fetch(input, ctx) {
async fetch(input, ctx, user) {
if (user === null) {
// Der Benutzer ist nicht authentifiziert.
// Wir erstellen das Ticket anonym.
const ticket = await prisma.tickets.create({
data: {
beschreibung: input.beschreibung,
email: input.email,
titel: input.titel,
metadata: input.metadata,
},
select: {
uid: true,
},
});
return {
uid: ticket.uid,
};
}
// Der Benutzer ist authentifiziert.
// Wir verlinken den Benutzer und das Ticket.
const ticket = await prisma.tickets.create({ const ticket = await prisma.tickets.create({
data: { data: {
benutzer: {
connect: {
id: user.id,
},
},
beschreibung: input.beschreibung, beschreibung: input.beschreibung,
email: input.email, email: input.email,
titel: input.titel, titel: input.titel,

View File

@@ -5,4 +5,5 @@ Astro.cookies.delete(API_ACCESS_TOKEN_COOKIE_NAME);
Astro.cookies.delete(API_REFRESH_TOKEN_COOKIE_NAME); Astro.cookies.delete(API_REFRESH_TOKEN_COOKIE_NAME);
Astro.cookies.delete(API_UID_COOKIE_NAME); Astro.cookies.delete(API_UID_COOKIE_NAME);
return Astro.redirect("/auth/login"); return Astro.redirect("/auth/login");
--- ---