Postleitzahlen Suche und e2e Tests

This commit is contained in:
Moritz Utcke
2024-01-13 19:27:31 +07:00
parent cee4953715
commit 3e9b312354
23 changed files with 417 additions and 91 deletions

View File

@@ -17,7 +17,7 @@ export default defineConfig({
output: "server",
vite: {
optimizeDeps: {
exclude: ["@ibcornelsen/api"]
exclude: ["@ibcornelsen/api", "@ibcornelsen/database"]
}
},
adapter: node({

View File

@@ -1,8 +1,17 @@
import { defineConfig } from 'cypress'
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
supportFile: false
baseUrl: "http://localhost:3000",
supportFile: false,
viewportHeight: 900,
viewportWidth: 1660,
},
})
component: {
devServer: {
framework: "svelte",
bundler: "vite",
},
},
});

View File

@@ -1,5 +0,0 @@
describe('The Home page.', () => {
it("successfully loads", () => {
cy.visit("/")
})
})

View File

@@ -0,0 +1,112 @@
import fuelList from "#components/Ausweis/fuelList";
import { faker } from "@faker-js/faker";
import { Enums } from "@ibcornelsen/database/client";
describe("Verbrauchsausweis erstellen Schritt 1", () => {
it("erstellt einen neuen Verbrauchsausweis Wohngebäude.", () => {
cy.visit("/verbrauchsausweis");
cy.wait(1000);
// Wir überprüfen, ob alle Ausstelgründe vorhanden sind, diese sollten genau so viele sein wie in der Datenbank vorhanden sind.
cy.get("input[name='ausstellgrund']")
.should("have.length", Object.values(Enums.Ausstellgrund).length)
.eq(
faker.number.int({
min: 0,
max: Object.values(Enums.Ausstellgrund).length - 1,
})
)
.check();
// Jetzt Füllen wir das Baujahr vom Gebäude aus.
cy.get("input[name='baujahr_gebaeude']")
.should("have.attr", "type", "number")
.type(
faker.number.int({ min: 1900, max: 2021 }).toString() +
"{enter}",
{ delay: 50 }
);
// Jetzt Füllen wir das Baujahr der Heizung aus.
cy.get("input[name='baujahr_heizung']")
.should("have.attr", "type", "number")
.type(
faker.number.int({ min: 1900, max: 2021 }).toString() +
"{enter}",
{ delay: 50 }
);
// Anzahl Einheiten
cy.get("input[name='einheiten']")
.should("have.attr", "type", "number")
.type(faker.number.int({ min: 1, max: 5 }).toString());
// Sanierungsstatus
cy.get("select[name='saniert']").select(
Math.random() > 0.5 ? "true" : "false"
);
// Adresse
cy.get("input[name='adresse']").type(faker.location.streetAddress());
// Postleitzahl
cy.get("input[name='plz']").type(
faker.location.zipCode({
format: "#####",
})
);
// TODO: Ort - Dieser wird aus der Datenbank abgefragt, wir müssen also warten, bis der Dropdown da ist.
// Flaeche
cy.get("input[name='flaeche']")
.should("have.attr", "type", "number")
.type(faker.number.int({ min: 50, max: 1000 }).toString());
// Keller
cy.get("select[name='keller']").find("option:not([disabled])").should("have.length", Object.values(Enums.Heizungsstatus).length).parent().select(faker.number.int({
max: Object.values(Enums.Heizungsstatus).length,
min: 1
}));
// Dachgeschoss
cy.get("select[name='dachgeschoss']").find("option:not([disabled])").should("have.length", Object.values(Enums.Heizungsstatus).length).parent().select(faker.number.int({
max: Object.values(Enums.Heizungsstatus).length,
min: 1
}));
// Brennstoff und Einheit 1
const brennstoffKombo = fuelList[faker.number.int({ min: 0, max: fuelList.length - 1 })];
cy.get("select[name='brennstoff_1']").select(brennstoffKombo[0]);
cy.get("select[name='einheit_1']").select(brennstoffKombo[1]);
// Verbrauchszeitraum
cy.get("select[name='energieverbrauch_zeitraum_monat']").select(faker.number.int({ min: 1, max: 12 }).toString());
cy.get("select[name='energieverbrauch_zeitraum_jahr']").select(faker.number.int({ min: 2018, max: 2019 }).toString());
// Verbrauch
cy.get("input[name='verbrauch_1']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
cy.get("input[name='verbrauch_2']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
cy.get("input[name='verbrauch_3']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
const zusaetzlicheHeizquelle = Math.random() > 0.5;
if (zusaetzlicheHeizquelle) {
cy.get("input[name='zusaetzliche_heizquelle']").check();
// Brennstoff und Einheit 2
const brennstoffKombo2 = fuelList[faker.number.int({ min: 0, max: fuelList.length - 1 })];
cy.get("select[name='brennstoff_2']").select(brennstoffKombo2[0]);
cy.get("select[name='einheit_2']").select(brennstoffKombo2[1]);
// Verbrauch
cy.get("input[name='verbrauch_4']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
cy.get("input[name='verbrauch_5']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
cy.get("input[name='verbrauch_6']").type(faker.number.int({ min: 4000, max: 15000 }).toString());
}
});
});

View File

@@ -0,0 +1,38 @@
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME } from "#lib/constants";
import {faker} from "@faker-js/faker";
describe('Benutzer Authentifizierung', () => {
// Wir generieren uns einen zufälligen Nutzer
const email = faker.internet.email()
const password = faker.internet.password()
const name = faker.person.firstName()
const surname = faker.person.lastName()
it("erstellt einen Nutzer und leitet auf die Login Seite weiter", () => {
cy.visit("/auth/signup")
cy.get('input[name="email"]').type(email)
cy.get('input[name="passwort"]').type(password)
cy.get('input[name="vorname"]').type(name)
cy.get('input[name="name"]').type(surname)
cy.get('button[type="submit"]').click()
cy.url().should("include", "/auth/login")
})
it("meldet einen Nutzer an und leitet auf die Startseite weiter", () => {
cy.visit("/auth/login")
cy.get('input[name="email"]').type(email)
cy.get('input[name="passwort"]').type(password)
cy.get('button[type="submit"]').click()
cy.url().should("include", "/user")
// Wir sollten nun einen Access Token und Refresh Token in unseren Cookies sehen.
cy.getCookie(API_ACCESS_TOKEN_COOKIE_NAME).should("exist")
cy.getCookie(API_REFRESH_TOKEN_COOKIE_NAME).should("exist")
})
})

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Components App</title>
</head>
<body>
<div data-cy-root></div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
// ***********************************************************
// This example support/component.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
import { mount } from 'cypress/svelte'
// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount
}
}
}
Cypress.Commands.add('mount', mount)
// Example use:
// cy.mount(MyComponent)

View File

@@ -58,12 +58,13 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@faker-js/faker": "^8.3.1",
"@types/body-scroll-lock": "^3.1.2",
"@types/js-cookie": "^3.0.6",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
"cypress": "^13.6.1",
"cypress": "^13.6.2",
"eslint": "~8.15.0",
"eslint-config-prettier": "8.1.0",
"prettier": "^2.8.8",

View File

@@ -27,6 +27,7 @@
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
<label class="radio-inline">
<input
name="ausstellgrund"
type="radio"
value={ausstellgrund}
bind:group={ausweis.ausstellgrund}
@@ -45,7 +46,7 @@
</HelpLabel>
<div>
<TagInput
name="IGheizung"
name="baujahr_heizung"
type="number"
onlyUnique={true}
onFocusIn={() => {
@@ -80,7 +81,7 @@
</HelpLabel>
<div>
<TagInput
name="IGbaujahr"
name="baujahr_gebaeude"
type="number"
onlyUnique={true}
onFocusIn={() => {
@@ -113,10 +114,8 @@
</HelpLabel>
<div>
<input
id="IGanzahl"
name="IGanzahl"
class=" "
type="text"
name="einheiten"
type="number"
required
autocomplete="off"
data-msg="Pflichtfeld"
@@ -135,8 +134,7 @@
</HelpLabel>
<div>
<select
id="IGsan"
name="IGsan"
name="saniert"
class=""
required
bind:value={gebaeude.saniert}

View File

@@ -57,7 +57,7 @@
</HelpLabel>
<input
type="checkbox"
class="IGzus1verbrauch1"
name="zusaetzliche_heizquelle"
bind:checked={ausweis.zusaetzliche_heizquelle}
/>
</div>
@@ -90,8 +90,8 @@
<b>Koks:</b> Stark kohlenstoffhaltiger Brennstoff.<br /><br />
</HelpLabel>
<div>
<select name="energietraeger_1" required bind:value={ausweis.brennstoff_1}>
<option>Bitte auswählen</option>
<select name="brennstoff_1" required bind:value={ausweis.brennstoff_1}>
<option disabled>Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option>
{/each}
@@ -111,7 +111,7 @@
required
bind:value={ausweis.einheit_1}
>
<option>Bitte auswählen</option>
<option disabled>Bitte auswählen</option>
{#each (fuelMap.hasOwnProperty(ausweis.brennstoff_1) ? fuelMap[ausweis.brennstoff_1] : []) as unit}
<option value={unit}>{unit}</option>
{/each}
@@ -123,12 +123,12 @@
<Label>Brennstoff *</Label>
<div>
<select
name="energietraeger_2"
name="brennstoff_2"
bind:value={ausweis.brennstoff_2}
disabled={!ausweis.zusaetzliche_heizquelle}
required
>
<option> Bitte auswählen</option>
<option disabled> Bitte auswählen</option>
{#each Object.keys(fuelMap) as fuel}
<option value={fuel}>{fuel}</option>
{/each}
@@ -145,7 +145,7 @@
bind:value={ausweis.einheit_2}
required
>
<option>Bitte auswählen</option>
<option disabled>Bitte auswählen</option>
{#each (fuelMap.hasOwnProperty(ausweis.brennstoff_2) ? fuelMap[ausweis.brennstoff_2] : []) as unit}
<option value={unit}>{unit}</option>
{/each}
@@ -207,7 +207,7 @@
<div class="column">
<span>bis</span>
<input
class=""
value={moment(ausweis.startdatum)
.add("1", "year")
.format("MM.Y")}
@@ -217,7 +217,7 @@
<div class="column">
<span>bis</span>
<input
class=""
value={moment(ausweis.startdatum)
.add("2", "years")
.format("MM.Y")}
@@ -227,7 +227,7 @@
<div class="column">
<span>bis</span>
<input
class=""
value={moment(ausweis.startdatum)
.add("3", "years")
.format("MM.Y")}
@@ -239,7 +239,7 @@
<div class="column">
<span>Verbrauch</span>
<input
name="energieverbrauch_1_heizquelle_1"
name="verbrauch_1"
type="number"
class:linked={abweichung.indexOf(1) > -1}
bind:value={ausweis.verbrauch_1}
@@ -249,7 +249,7 @@
<div class="column">
<span>Verbrauch</span>
<input
name="energieverbrauch_2_heizquelle_1"
name="verbrauch_2"
type="number"
class:linked={abweichung.indexOf(2) > -1}
bind:value={ausweis.verbrauch_2}
@@ -259,7 +259,7 @@
<div class="column">
<span>Verbrauch</span>
<input
name="energieverbrauch_3_heizquelle_1"
name="verbrauch_3"
type="number"
class:linked={abweichung.indexOf(3) > -1}
bind:value={ausweis.verbrauch_3}
@@ -271,7 +271,7 @@
<div class="column">
<span>Verbrauch</span>
<input
name="energieverbrauch_1_heizquelle_2"
name="verbrauch_4"
type="number"
bind:value={ausweis.verbrauch_4}
class:linked={abweichung.indexOf(4) > -1}
@@ -281,7 +281,7 @@
<div class="column">
<span>Verbrauch</span>
<input
name="energieverbrauch_2_heizquelle_2"
name="verbrauch_5"
type="number"
bind:value={ausweis.verbrauch_5}
class:linked={abweichung.indexOf(5) > -1}
@@ -291,7 +291,7 @@
<div class="column">
<span>Verbrauch</span>
<input
name="energieverbrauch_3_heizquelle_2"
name="verbrauch_6"
type="number"
bind:value={ausweis.verbrauch_6}
class:linked={abweichung.indexOf(6) > -1}

View File

@@ -61,7 +61,7 @@ const valid = await validateAccessTokenServer(Astro)
Profil
</a>
) : (
<a class="headerButton" href="/login">
<a class="headerButton" href="/auth/login">
Login
</a>
)

View File

@@ -76,7 +76,8 @@
{/each}
{/if}
<input
type="text"
type="number"
{name}
bind:value={tag}
on:keydown={onKeydown}
on:focusin={onFocusIn}

View File

@@ -1,6 +1,8 @@
<script lang="ts">
import type { ZIPInformation } from "src/lib/ZIPInformation";
import Label from "./Label.svelte";
import { client } from "src/trpc";
import type { inferProcedureOutput } from "@trpc/server";
import type { AppRouter } from "@ibcornelsen/api";
export let name: string;
export let readonly: boolean = false;
@@ -9,21 +11,22 @@
let hideZipDropdown: boolean = true;
let zipCodes: ZIPInformation[] = [];
let zipCodes: inferProcedureOutput<AppRouter["v1"]["postleitzahlen"]> = [];
async function fetchZipCodeInformation() {
const result = await fetch(`/api/zip?zip=${zip}`, {
method: "GET",
headers: {
"authorization": "Basic " + btoa("user@ib-cornelsen.de:test")
if (!zip || (zip.length < 2)) {
return
}
}).then(r => r.json());
if (result.success === true) {
zipCodes = result.data;
if (zipCodes.length > 0) {
try {
const result = await client.v1.postleitzahlen.query({ plz: zip });
if (result.length > 0) {
zipCodes = result;
hideZipDropdown = false;
}
} catch(e) {
console.error(e);
}
}
@@ -65,12 +68,12 @@
/>
<div class="absolute top-[calc(100%+4px)] left-0 w-full bg-white py-2 shadow-md rounded-lg" hidden={hideZipDropdown}>
{#each zipCodes as {zip: z, city: c}}
{#each zipCodes as zipCode}
<div class="hover:bg-gray-100 cursor-pointer px-2 py-0.5" tabindex="-1" on:click={() => {
zip = z;
city = c;
zip = zipCode.plz;
city = zipCode.stadt;
hideZipDropdown = true;
}}>{z}, {c}</div>
}}>{zipCode.plz}, {zipCode.stadt}</div>
{/each}
</div>
</div>

View File

@@ -0,0 +1,68 @@
import moment from "moment";
import csv from "csvtojson";
import * as fs from "fs";
const start = moment().set("year", 2019).set("month", 8).set("date", 1);
const end = moment().set("year", 2022).set("month", 10).set("date", 1);
let current = start.clone();
do {
const lastYearString = current.clone().startOf("month").format("YYYYMMDD");
const nextYearString = current
.clone()
.subtract(1, "month")
.add(1, "year")
.endOf("month")
.format("YYYYMMDD");
const filename = `KF_${lastYearString}_${nextYearString}.csv`;
const url =
"https://opendata.dwd.de/climate_environment/CDC/derived_germany/techn/monthly/climate_correction_factor/recent/";
const response = await fetch(`${url}${filename}`);
if (response.status !== 200) {
console.error(`Could not fetch ${url}${filename}`);
process.exit(1);
}
const parser = csv({
noheader: false,
output: "json",
delimiter: ";",
});
const data: {
DatAnf: string;
DatEnd: string;
PLZ: string;
KF: string;
}[] = await parser.fromString(await response.text());
const year = current.year();
const month = current.month();
const json = JSON.parse(fs.readFileSync("./test.json", "utf-8"));
fs.writeFileSync(
"./test.json",
JSON.stringify(
[
...json,
...data.map((row) => [
year,
month,
parseFloat(row.KF),
row.PLZ,
]),
],
null,
2
)
);
console.log(`Wrote ${year}-${month} to file.`);
} while (current.add(1, "month").isBefore(end));

View File

@@ -28,6 +28,9 @@
ausweisart: Enums.Ausweisart.VerbrauchsausweisWohnen
} as VerbrauchsausweisWohnen;
console.log(Enums);
async function ausweisSpeichern() {
// Um einen Ausweis zu speichern müssen wir eingeloggt sein, andernfalls wird die API den call ablehnen.
// Wir prüfen also ob wir eingeloggt sind und leiten den Nutzer ggf. auf die Login Seite weiter.
@@ -207,7 +210,7 @@
<ZipSearch
bind:zip={gebaeude.plz}
bind:city={gebaeude.ort}
name="zip"
name="plz"
/>
</div>
@@ -251,14 +254,14 @@
<Label>Keller *</Label>
<div>
<select
name="keller_beheizt"
name="keller"
required
bind:value={ausweis.keller_beheizt}
bind:value={gebaeude.keller}
>
<option>Bitte auswählen</option>
<option value={false}>nicht vorhanden</option>
<option value={false}>unbeheizt</option>
<option value={true}>beheizt</option>
<option disabled>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>
</div>
@@ -267,11 +270,11 @@
<div class="form-group col-md-4">
<Label>Dachgeschoss *</Label>
<div>
<select name="dachgeschoss" required>
<option>Bitte auswählen</option>
<option value="dnein">nicht vorhanden</option>
<option value="dub">unbeheizt</option>
<option value="dbh">beheizt</option>
<select name="dachgeschoss" bind:value={gebaeude.dachgeschoss} required>
<option disabled>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>
</div>

View File

@@ -7,7 +7,8 @@
export let redirect: string | null = null;
async function login() {
async function login(e: SubmitEvent) {
e.preventDefault()
const response = await loginClient(email, passwort)
if (response === null) {
@@ -31,7 +32,7 @@
<div style="width:50%;margin: 0 auto">
<h1>Login</h1>
<div class="flex flex-col gap-4">
<form class="flex flex-col gap-4" on:submit={login}>
<div>
<h4>Email</h4>
<input
@@ -49,15 +50,15 @@
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
type="password"
placeholder="********"
name="password"
name="passwort"
bind:value={passwort}
required
/>
</div>
<button class="button" on:click={login}>Einloggen</button>
<button type="submit" >Einloggen</button>
<div class="flex-row justify-between" style="margin-top: 10px">
<a href="/signup?redirect={redirect}">Registrieren</a>
<a href="/auth/signup?redirect={redirect}">Registrieren</a>
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
</div>
</div>
</form>
</div>

View File

@@ -9,7 +9,8 @@
export let redirect: string | null = null;
async function login() {
async function login(e: SubmitEvent) {
e.preventDefault()
try {
const response = await client.v1.benutzer.erstellen.mutate({
email,
@@ -23,7 +24,7 @@
return
}
window.location.href = "/login";
window.location.href = "/auth/login";
} catch (e) {
addNotification({
message: "Ups...",
@@ -38,13 +39,14 @@
<div style="width:50%;margin: 0 auto">
<h1>Registrieren:</h1>
<div class="flex flex-col gap-4">
<form class="flex flex-col gap-4" on:submit={login}>
<div class="flex flex-row gap-4 w-full">
<div class="w-1/2">
<h4>Vorname</h4>
<input
type="text"
placeholder="Vorname"
name="vorname"
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
bind:value={vorname}
required
@@ -55,6 +57,7 @@
<input
type="text"
placeholder="Nachname"
name="name"
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
bind:value={name}
required
@@ -66,6 +69,7 @@
<input
type="text"
placeholder="Email"
name="email"
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
bind:value={email}
required
@@ -76,19 +80,20 @@
<input
type="password"
placeholder="********"
name="passwort"
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
bind:value={passwort}
required
/>
</div>
<button class="button" on:click={login}
<button type="submit" class="button"
>Registrieren</button
>
<div class="flex-row justify-between" style="margin-top: 10px">
<a
href="/login?redirect={redirect}">Einloggen</a
href="/auth/login?redirect={redirect}">Einloggen</a
>
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
</div>
</div>
</form>
</div>

View File

@@ -156,8 +156,7 @@
</HelpLabel>
<div>
<input
name="IGort"
name="ort"
readonly={true}
bind:value={gebaeude.ort}
type="text"
@@ -174,7 +173,7 @@
</HelpLabel>
<div>
<input
name="IGflaeche"
name="flaeche"
maxlength="4"
type="number"
required
@@ -191,14 +190,14 @@
<Label>Keller *</Label>
<div>
<select
name="IGkeller"
name="keller"
required
bind:value={gebaeude.keller}
>
<option>Bitte auswählen</option>
<option value={false}>nicht vorhanden</option>
<option value={false}>unbeheizt</option>
<option value={true}>beheizt</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>
</div>
@@ -207,11 +206,11 @@
<div class="form-group col-md-4">
<Label>Dachgeschoss *</Label>
<div>
<select name="IGdach" class="" required>
<select name="dachgeschoss" required>
<option>Bitte auswählen</option>
<option value="dnein">nicht vorhanden</option>
<option value="dub">unbeheizt</option>
<option value="dbh">beheizt</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>
</div>

View File

@@ -1,6 +1,6 @@
---
import LoginModule from "../modules/LoginModule.svelte";
import Layout from "../layouts/Layout.astro";
import LoginModule from "../../modules/LoginModule.svelte";
import Layout from "../../layouts/Layout.astro";
import { validateAccessTokenServer } from "src/server/lib/validateAccessToken";
const valid = await validateAccessTokenServer(Astro)

View File

@@ -1,6 +1,6 @@
---
import RegisterModule from "../modules/RegisterModule.svelte";
import Layout from "../layouts/Layout.astro";
import RegisterModule from "../../modules/RegisterModule.svelte";
import Layout from "../../layouts/Layout.astro";
const redirect = Astro.url.searchParams.get("redirect");
---