Postleitzahlen Suche und e2e Tests
This commit is contained in:
@@ -17,7 +17,7 @@ export default defineConfig({
|
|||||||
output: "server",
|
output: "server",
|
||||||
vite: {
|
vite: {
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: ["@ibcornelsen/api"]
|
exclude: ["@ibcornelsen/api", "@ibcornelsen/database"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
adapter: node({
|
adapter: node({
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { defineConfig } from 'cypress'
|
import { defineConfig } from "cypress";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
e2e: {
|
e2e: {
|
||||||
baseUrl: 'http://localhost:3000',
|
baseUrl: "http://localhost:3000",
|
||||||
supportFile: false
|
supportFile: false,
|
||||||
|
viewportHeight: 900,
|
||||||
|
viewportWidth: 1660,
|
||||||
},
|
},
|
||||||
})
|
|
||||||
|
component: {
|
||||||
|
devServer: {
|
||||||
|
framework: "svelte",
|
||||||
|
bundler: "vite",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
describe('The Home page.', () => {
|
|
||||||
it("successfully loads", () => {
|
|
||||||
cy.visit("/")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
112
cypress/e2e/VerbrauchsausweisWohnen/erstellen.cy.ts
Normal file
112
cypress/e2e/VerbrauchsausweisWohnen/erstellen.cy.ts
Normal 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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
38
cypress/e2e/auth/index.cy.ts
Normal file
38
cypress/e2e/auth/index.cy.ts
Normal 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")
|
||||||
|
})
|
||||||
|
})
|
||||||
5
cypress/fixtures/example.json
Normal file
5
cypress/fixtures/example.json
Normal 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"
|
||||||
|
}
|
||||||
37
cypress/support/commands.ts
Normal file
37
cypress/support/commands.ts
Normal 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>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
12
cypress/support/component-index.html
Normal file
12
cypress/support/component-index.html
Normal 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>
|
||||||
39
cypress/support/component.ts
Normal file
39
cypress/support/component.ts
Normal 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)
|
||||||
@@ -58,12 +58,13 @@
|
|||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@faker-js/faker": "^8.3.1",
|
||||||
"@types/body-scroll-lock": "^3.1.2",
|
"@types/body-scroll-lock": "^3.1.2",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/uuid": "^9.0.1",
|
"@types/uuid": "^9.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
||||||
"@typescript-eslint/parser": "^5.59.6",
|
"@typescript-eslint/parser": "^5.59.6",
|
||||||
"cypress": "^13.6.1",
|
"cypress": "^13.6.2",
|
||||||
"eslint": "~8.15.0",
|
"eslint": "~8.15.0",
|
||||||
"eslint-config-prettier": "8.1.0",
|
"eslint-config-prettier": "8.1.0",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
|
{#each Object.entries(Enums.Ausstellgrund) as [name, ausstellgrund]}
|
||||||
<label class="radio-inline">
|
<label class="radio-inline">
|
||||||
<input
|
<input
|
||||||
|
name="ausstellgrund"
|
||||||
type="radio"
|
type="radio"
|
||||||
value={ausstellgrund}
|
value={ausstellgrund}
|
||||||
bind:group={ausweis.ausstellgrund}
|
bind:group={ausweis.ausstellgrund}
|
||||||
@@ -45,7 +46,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<TagInput
|
<TagInput
|
||||||
name="IGheizung"
|
name="baujahr_heizung"
|
||||||
type="number"
|
type="number"
|
||||||
onlyUnique={true}
|
onlyUnique={true}
|
||||||
onFocusIn={() => {
|
onFocusIn={() => {
|
||||||
@@ -80,7 +81,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<TagInput
|
<TagInput
|
||||||
name="IGbaujahr"
|
name="baujahr_gebaeude"
|
||||||
type="number"
|
type="number"
|
||||||
onlyUnique={true}
|
onlyUnique={true}
|
||||||
onFocusIn={() => {
|
onFocusIn={() => {
|
||||||
@@ -113,10 +114,8 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
id="IGanzahl"
|
name="einheiten"
|
||||||
name="IGanzahl"
|
type="number"
|
||||||
class=" "
|
|
||||||
type="text"
|
|
||||||
required
|
required
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
data-msg="Pflichtfeld"
|
data-msg="Pflichtfeld"
|
||||||
@@ -135,8 +134,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
id="IGsan"
|
name="saniert"
|
||||||
name="IGsan"
|
|
||||||
class=""
|
class=""
|
||||||
required
|
required
|
||||||
bind:value={gebaeude.saniert}
|
bind:value={gebaeude.saniert}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="IGzus1verbrauch1"
|
name="zusaetzliche_heizquelle"
|
||||||
bind:checked={ausweis.zusaetzliche_heizquelle}
|
bind:checked={ausweis.zusaetzliche_heizquelle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,8 +90,8 @@
|
|||||||
<b>Koks:</b> Stark kohlenstoffhaltiger Brennstoff.<br /><br />
|
<b>Koks:</b> Stark kohlenstoffhaltiger Brennstoff.<br /><br />
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select name="energietraeger_1" required bind:value={ausweis.brennstoff_1}>
|
<select name="brennstoff_1" required bind:value={ausweis.brennstoff_1}>
|
||||||
<option>Bitte auswählen</option>
|
<option disabled>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}
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
required
|
required
|
||||||
bind:value={ausweis.einheit_1}
|
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}
|
{#each (fuelMap.hasOwnProperty(ausweis.brennstoff_1) ? fuelMap[ausweis.brennstoff_1] : []) as unit}
|
||||||
<option value={unit}>{unit}</option>
|
<option value={unit}>{unit}</option>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -123,12 +123,12 @@
|
|||||||
<Label>Brennstoff *</Label>
|
<Label>Brennstoff *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="energietraeger_2"
|
name="brennstoff_2"
|
||||||
bind:value={ausweis.brennstoff_2}
|
bind:value={ausweis.brennstoff_2}
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
disabled={!ausweis.zusaetzliche_heizquelle}
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option> Bitte auswählen</option>
|
<option disabled> 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}
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
bind:value={ausweis.einheit_2}
|
bind:value={ausweis.einheit_2}
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
{#each (fuelMap.hasOwnProperty(ausweis.brennstoff_2) ? fuelMap[ausweis.brennstoff_2] : []) as unit}
|
{#each (fuelMap.hasOwnProperty(ausweis.brennstoff_2) ? fuelMap[ausweis.brennstoff_2] : []) as unit}
|
||||||
<option value={unit}>{unit}</option>
|
<option value={unit}>{unit}</option>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>bis</span>
|
<span>bis</span>
|
||||||
<input
|
<input
|
||||||
class=""
|
|
||||||
value={moment(ausweis.startdatum)
|
value={moment(ausweis.startdatum)
|
||||||
.add("1", "year")
|
.add("1", "year")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>bis</span>
|
<span>bis</span>
|
||||||
<input
|
<input
|
||||||
class=""
|
|
||||||
value={moment(ausweis.startdatum)
|
value={moment(ausweis.startdatum)
|
||||||
.add("2", "years")
|
.add("2", "years")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>bis</span>
|
<span>bis</span>
|
||||||
<input
|
<input
|
||||||
class=""
|
|
||||||
value={moment(ausweis.startdatum)
|
value={moment(ausweis.startdatum)
|
||||||
.add("3", "years")
|
.add("3", "years")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch</span>
|
||||||
<input
|
<input
|
||||||
name="energieverbrauch_1_heizquelle_1"
|
name="verbrauch_1"
|
||||||
type="number"
|
type="number"
|
||||||
class:linked={abweichung.indexOf(1) > -1}
|
class:linked={abweichung.indexOf(1) > -1}
|
||||||
bind:value={ausweis.verbrauch_1}
|
bind:value={ausweis.verbrauch_1}
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch</span>
|
||||||
<input
|
<input
|
||||||
name="energieverbrauch_2_heizquelle_1"
|
name="verbrauch_2"
|
||||||
type="number"
|
type="number"
|
||||||
class:linked={abweichung.indexOf(2) > -1}
|
class:linked={abweichung.indexOf(2) > -1}
|
||||||
bind:value={ausweis.verbrauch_2}
|
bind:value={ausweis.verbrauch_2}
|
||||||
@@ -259,7 +259,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch</span>
|
||||||
<input
|
<input
|
||||||
name="energieverbrauch_3_heizquelle_1"
|
name="verbrauch_3"
|
||||||
type="number"
|
type="number"
|
||||||
class:linked={abweichung.indexOf(3) > -1}
|
class:linked={abweichung.indexOf(3) > -1}
|
||||||
bind:value={ausweis.verbrauch_3}
|
bind:value={ausweis.verbrauch_3}
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch</span>
|
||||||
<input
|
<input
|
||||||
name="energieverbrauch_1_heizquelle_2"
|
name="verbrauch_4"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.verbrauch_4}
|
bind:value={ausweis.verbrauch_4}
|
||||||
class:linked={abweichung.indexOf(4) > -1}
|
class:linked={abweichung.indexOf(4) > -1}
|
||||||
@@ -281,7 +281,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch</span>
|
||||||
<input
|
<input
|
||||||
name="energieverbrauch_2_heizquelle_2"
|
name="verbrauch_5"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.verbrauch_5}
|
bind:value={ausweis.verbrauch_5}
|
||||||
class:linked={abweichung.indexOf(5) > -1}
|
class:linked={abweichung.indexOf(5) > -1}
|
||||||
@@ -291,7 +291,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch</span>
|
||||||
<input
|
<input
|
||||||
name="energieverbrauch_3_heizquelle_2"
|
name="verbrauch_6"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.verbrauch_6}
|
bind:value={ausweis.verbrauch_6}
|
||||||
class:linked={abweichung.indexOf(6) > -1}
|
class:linked={abweichung.indexOf(6) > -1}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ const valid = await validateAccessTokenServer(Astro)
|
|||||||
Profil
|
Profil
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<a class="headerButton" href="/login">
|
<a class="headerButton" href="/auth/login">
|
||||||
Login
|
Login
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -76,7 +76,8 @@
|
|||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="number"
|
||||||
|
{name}
|
||||||
bind:value={tag}
|
bind:value={tag}
|
||||||
on:keydown={onKeydown}
|
on:keydown={onKeydown}
|
||||||
on:focusin={onFocusIn}
|
on:focusin={onFocusIn}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ZIPInformation } from "src/lib/ZIPInformation";
|
|
||||||
import Label from "./Label.svelte";
|
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 name: string;
|
||||||
export let readonly: boolean = false;
|
export let readonly: boolean = false;
|
||||||
@@ -9,21 +11,22 @@
|
|||||||
|
|
||||||
|
|
||||||
let hideZipDropdown: boolean = true;
|
let hideZipDropdown: boolean = true;
|
||||||
let zipCodes: ZIPInformation[] = [];
|
let zipCodes: inferProcedureOutput<AppRouter["v1"]["postleitzahlen"]> = [];
|
||||||
|
|
||||||
async function fetchZipCodeInformation() {
|
async function fetchZipCodeInformation() {
|
||||||
const result = await fetch(`/api/zip?zip=${zip}`, {
|
if (!zip || (zip.length < 2)) {
|
||||||
method: "GET",
|
return
|
||||||
headers: {
|
|
||||||
"authorization": "Basic " + btoa("user@ib-cornelsen.de:test")
|
|
||||||
}
|
}
|
||||||
}).then(r => r.json());
|
|
||||||
|
|
||||||
if (result.success === true) {
|
try {
|
||||||
zipCodes = result.data;
|
const result = await client.v1.postleitzahlen.query({ plz: zip });
|
||||||
if (zipCodes.length > 0) {
|
|
||||||
|
if (result.length > 0) {
|
||||||
|
zipCodes = result;
|
||||||
hideZipDropdown = false;
|
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}>
|
<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={() => {
|
<div class="hover:bg-gray-100 cursor-pointer px-2 py-0.5" tabindex="-1" on:click={() => {
|
||||||
zip = z;
|
zip = zipCode.plz;
|
||||||
city = c;
|
city = zipCode.stadt;
|
||||||
hideZipDropdown = true;
|
hideZipDropdown = true;
|
||||||
}}>{z}, {c}</div>
|
}}>{zipCode.plz}, {zipCode.stadt}</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
68
src/cronjobs/update-dwd-test.ts
Normal file
68
src/cronjobs/update-dwd-test.ts
Normal 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));
|
||||||
@@ -28,6 +28,9 @@
|
|||||||
ausweisart: Enums.Ausweisart.VerbrauchsausweisWohnen
|
ausweisart: Enums.Ausweisart.VerbrauchsausweisWohnen
|
||||||
} as VerbrauchsausweisWohnen;
|
} as VerbrauchsausweisWohnen;
|
||||||
|
|
||||||
|
console.log(Enums);
|
||||||
|
|
||||||
|
|
||||||
async function ausweisSpeichern() {
|
async function ausweisSpeichern() {
|
||||||
// Um einen Ausweis zu speichern müssen wir eingeloggt sein, andernfalls wird die API den call ablehnen.
|
// 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.
|
// Wir prüfen also ob wir eingeloggt sind und leiten den Nutzer ggf. auf die Login Seite weiter.
|
||||||
@@ -207,7 +210,7 @@
|
|||||||
<ZipSearch
|
<ZipSearch
|
||||||
bind:zip={gebaeude.plz}
|
bind:zip={gebaeude.plz}
|
||||||
bind:city={gebaeude.ort}
|
bind:city={gebaeude.ort}
|
||||||
name="zip"
|
name="plz"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -251,14 +254,14 @@
|
|||||||
<Label>Keller *</Label>
|
<Label>Keller *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="keller_beheizt"
|
name="keller"
|
||||||
required
|
required
|
||||||
bind:value={ausweis.keller_beheizt}
|
bind:value={gebaeude.keller}
|
||||||
>
|
>
|
||||||
<option>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
<option value={false}>nicht vorhanden</option>
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
|
||||||
<option value={false}>unbeheizt</option>
|
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
|
||||||
<option value={true}>beheizt</option>
|
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -267,11 +270,11 @@
|
|||||||
<div class="form-group col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<Label>Dachgeschoss *</Label>
|
<Label>Dachgeschoss *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select name="dachgeschoss" required>
|
<select name="dachgeschoss" bind:value={gebaeude.dachgeschoss} required>
|
||||||
<option>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
<option value="dnein">nicht vorhanden</option>
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
|
||||||
<option value="dub">unbeheizt</option>
|
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
|
||||||
<option value="dbh">beheizt</option>
|
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
export let redirect: string | null = null;
|
export let redirect: string | null = null;
|
||||||
|
|
||||||
async function login() {
|
async function login(e: SubmitEvent) {
|
||||||
|
e.preventDefault()
|
||||||
const response = await loginClient(email, passwort)
|
const response = await loginClient(email, passwort)
|
||||||
|
|
||||||
if (response === null) {
|
if (response === null) {
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
|
|
||||||
<div style="width:50%;margin: 0 auto">
|
<div style="width:50%;margin: 0 auto">
|
||||||
<h1>Login</h1>
|
<h1>Login</h1>
|
||||||
<div class="flex flex-col gap-4">
|
<form class="flex flex-col gap-4" on:submit={login}>
|
||||||
<div>
|
<div>
|
||||||
<h4>Email</h4>
|
<h4>Email</h4>
|
||||||
<input
|
<input
|
||||||
@@ -49,15 +50,15 @@
|
|||||||
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="********"
|
placeholder="********"
|
||||||
name="password"
|
name="passwort"
|
||||||
bind:value={passwort}
|
bind:value={passwort}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button class="button" on:click={login}>Einloggen</button>
|
<button type="submit" >Einloggen</button>
|
||||||
<div class="flex-row justify-between" style="margin-top: 10px">
|
<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>
|
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
export let redirect: string | null = null;
|
export let redirect: string | null = null;
|
||||||
|
|
||||||
async function login() {
|
async function login(e: SubmitEvent) {
|
||||||
|
e.preventDefault()
|
||||||
try {
|
try {
|
||||||
const response = await client.v1.benutzer.erstellen.mutate({
|
const response = await client.v1.benutzer.erstellen.mutate({
|
||||||
email,
|
email,
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.href = "/login";
|
window.location.href = "/auth/login";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
addNotification({
|
addNotification({
|
||||||
message: "Ups...",
|
message: "Ups...",
|
||||||
@@ -38,13 +39,14 @@
|
|||||||
|
|
||||||
<div style="width:50%;margin: 0 auto">
|
<div style="width:50%;margin: 0 auto">
|
||||||
<h1>Registrieren:</h1>
|
<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="flex flex-row gap-4 w-full">
|
||||||
<div class="w-1/2">
|
<div class="w-1/2">
|
||||||
<h4>Vorname</h4>
|
<h4>Vorname</h4>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Vorname"
|
placeholder="Vorname"
|
||||||
|
name="vorname"
|
||||||
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
bind:value={vorname}
|
bind:value={vorname}
|
||||||
required
|
required
|
||||||
@@ -55,6 +57,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Nachname"
|
placeholder="Nachname"
|
||||||
|
name="name"
|
||||||
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
bind:value={name}
|
bind:value={name}
|
||||||
required
|
required
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
|
name="email"
|
||||||
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
bind:value={email}
|
bind:value={email}
|
||||||
required
|
required
|
||||||
@@ -76,19 +80,20 @@
|
|||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="********"
|
placeholder="********"
|
||||||
|
name="passwort"
|
||||||
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
|
||||||
bind:value={passwort}
|
bind:value={passwort}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button class="button" on:click={login}
|
<button type="submit" class="button"
|
||||||
>Registrieren</button
|
>Registrieren</button
|
||||||
>
|
>
|
||||||
<div class="flex-row justify-between" style="margin-top: 10px">
|
<div class="flex-row justify-between" style="margin-top: 10px">
|
||||||
<a
|
<a
|
||||||
href="/login?redirect={redirect}">Einloggen</a
|
href="/auth/login?redirect={redirect}">Einloggen</a
|
||||||
>
|
>
|
||||||
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
|
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -156,8 +156,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="IGort"
|
name="ort"
|
||||||
|
|
||||||
readonly={true}
|
readonly={true}
|
||||||
bind:value={gebaeude.ort}
|
bind:value={gebaeude.ort}
|
||||||
type="text"
|
type="text"
|
||||||
@@ -174,7 +173,7 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="IGflaeche"
|
name="flaeche"
|
||||||
maxlength="4"
|
maxlength="4"
|
||||||
type="number"
|
type="number"
|
||||||
required
|
required
|
||||||
@@ -191,14 +190,14 @@
|
|||||||
<Label>Keller *</Label>
|
<Label>Keller *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="IGkeller"
|
name="keller"
|
||||||
required
|
required
|
||||||
bind:value={gebaeude.keller}
|
bind:value={gebaeude.keller}
|
||||||
>
|
>
|
||||||
<option>Bitte auswählen</option>
|
<option>Bitte auswählen</option>
|
||||||
<option value={false}>nicht vorhanden</option>
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
|
||||||
<option value={false}>unbeheizt</option>
|
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
|
||||||
<option value={true}>beheizt</option>
|
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -207,11 +206,11 @@
|
|||||||
<div class="form-group col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<Label>Dachgeschoss *</Label>
|
<Label>Dachgeschoss *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select name="IGdach" class="" required>
|
<select name="dachgeschoss" required>
|
||||||
<option>Bitte auswählen</option>
|
<option>Bitte auswählen</option>
|
||||||
<option value="dnein">nicht vorhanden</option>
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
|
||||||
<option value="dub">unbeheizt</option>
|
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
|
||||||
<option value="dbh">beheizt</option>
|
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import LoginModule from "../modules/LoginModule.svelte";
|
import LoginModule from "../../modules/LoginModule.svelte";
|
||||||
import Layout from "../layouts/Layout.astro";
|
import Layout from "../../layouts/Layout.astro";
|
||||||
import { validateAccessTokenServer } from "src/server/lib/validateAccessToken";
|
import { validateAccessTokenServer } from "src/server/lib/validateAccessToken";
|
||||||
|
|
||||||
const valid = await validateAccessTokenServer(Astro)
|
const valid = await validateAccessTokenServer(Astro)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import RegisterModule from "../modules/RegisterModule.svelte";
|
import RegisterModule from "../../modules/RegisterModule.svelte";
|
||||||
import Layout from "../layouts/Layout.astro";
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
|
||||||
const redirect = Astro.url.searchParams.get("redirect");
|
const redirect = Astro.url.searchParams.get("redirect");
|
||||||
---
|
---
|
||||||
Reference in New Issue
Block a user