Verbrauchsausweis Test Vollständig, Besserer Login angefangen

This commit is contained in:
Moritz Utcke
2024-01-15 16:25:01 +07:00
parent ceed5f7bb7
commit f684ce0060
21 changed files with 414 additions and 87 deletions

2
.vscode/tasks.json vendored
View File

@@ -6,7 +6,7 @@
{
"label": "Docker Container Starten",
"type": "shell",
"command": "docker-compose up"
"command": "docker compose up"
}
]
}

View File

@@ -241,6 +241,34 @@ describe("Verbrauchsausweis erstellen Schritt 1", () => {
cy.get("form[name='login'] button[type='submit']").click();
// Der Ausweis sollte jetzt schon erstellt worden sein.
// Der Ausweis sollte jetzt schon erstellt worden sein und wir sollten auf die kundendaten seite weitergeleitet worden sein.
cy.url().should("contain", "/kundendaten");
// Wir füllen jetzt die Kundendaten aus.
cy.get("input[name='vorname']").should("contain.value", vorname);
cy.get("input[name='name']").should("contain.value", nachname);
cy.get("input[name='email']").should("contain.value", email);
cy.get("input[name='telefon']").type(faker.phone.number());
cy.get("input[name='rechnung_empfaenger']").type(`${vorname} ${nachname}`);
cy.get("input[name='rechnung_strasse']").type(faker.location.streetAddress());
// TODO: Random Plz generieren, allerdings muss die auch in der Datenbank vorhanden sein...
cy.get("input[name='rechnung_plz']").type("2103");
// Jetzt sollte der PLZ Container erscheinen, dort klicken wir einfach das erste Element an.
cy.get("div[data-test='plz-container']").children().first().click();
cy.get("input[name='rechnung_telefon']").type(faker.phone.number());
cy.get("input[name='rechnung_email']").type(faker.internet.email());
cy.get("button[data-test='paypal']").click();
// Datenschutz und AGB akzeptieren, dann schicken wir das Formular ab.
cy.get("input[name='agb-akzeptieren']").check()
cy.get("input[name='datenschutz-akzeptieren']").check()
cy.get("button[type='submit']").click();
cy.origin('https://www.mollie.com', () => {
// Jetzt sind wir auf der Mollie Seite, dort wählen wir den "paid" status aus
cy.get("input[type='radio'][name='final_state'][value='paid']").check();
// Da wird unser Test fehlschlagen, da die localhost domain von Mollie aus nicht erreichbar ist.
})
});
});

View File

@@ -50,6 +50,7 @@
"pg": "^8.11.0",
"sass": "^1.62.1",
"svelte": "^3.59.1",
"svelte-dialogs": "^1.2.2",
"svelte-preprocess": "^5.0.3",
"tailwindcss": "^3.3.2",
"trpc-openapi": "^1.2.0",

View File

@@ -0,0 +1,49 @@
import { dialogs } from "../../../svelte-dialogs.config";
import { loginClient } from "#lib/login";
import { addNotification } from "#components/Notifications/shared";
export async function spawnLoginPrompt() {
const result = await dialogs.prompt(
[
{
label: "Email",
type: "email",
required: true,
placeholder: "Email",
name: "email"
},
{
label: "Passwort",
type: "password",
name: "passwort",
required: true,
placeholder: "********",
},
],
{
title: "Login",
submitButtonText: "Einloggen",
cancelButtonText: "Abbrechen",
}
);
if (!result) return false;
const [email, passwort] = result;
const loginResult = await loginClient(email, passwort);
if (loginResult === null) {
addNotification({
type: "error",
message: "Einloggen fehlgeschlagen",
dismissable: true,
subtext: "Bitte überprüfen Sie ihre Eingaben und versuchen es erneut.",
timeout: 5000,
})
return false
}
return true
}

View File

@@ -0,0 +1,67 @@
import { dialogs } from "../../../svelte-dialogs.config";
import { addNotification } from "#components/Notifications/shared";
import { client } from "src/trpc";
export async function spawnSignupPrompt() {
const result = await dialogs.prompt(
[
{
label: "Vorname",
type: "text",
required: true,
placeholder: "Vorname",
name: "vorname"
},
{
label: "Name",
type: "text",
required: true,
placeholder: "Name",
name: "name"
},
{
label: "Email",
type: "email",
required: true,
placeholder: "Email",
name: "email"
},
{
label: "Passwort",
type: "password",
name: "passwort",
required: true,
placeholder: "********",
},
],
{
title: "Registrieren",
submitButtonText: "Registrieren",
cancelButtonText: "Abbrechen",
}
);
if (!result) return false;
const [vorname, name, email, passwort] = result;
try {
const response = await client.v1.benutzer.erstellen.mutate({
email,
passwort,
vorname,
name,
});
return true;
} catch(e) {
addNotification({
type: "error",
message: "Registrieren fehlgeschlagen",
dismissable: true,
subtext: "Ein Fehler ist aufgetreten, vielleicht wird die angegebene Email bereits verwendet.",
timeout: 5000,
})
return false;
}
}

View File

@@ -0,0 +1,7 @@
import { AppRouter } from "@ibcornelsen/api";
import { inferProcedureInput } from "@trpc/server";
import { client } from "src/trpc";
export async function createTicket(info: inferProcedureInput<AppRouter["v1"]["tickets"]["erstellen"]>) {
return await client.v1.tickets.erstellen.mutate(info)
}

View File

View File

@@ -1,6 +1,6 @@
import { AppRouter } from "@ibcornelsen/api";
import { GebaeudeBilder } from "@ibcornelsen/database/client";
import { inferProcedureInput } from "@trpc/server";
import { Benutzer, GebaeudeBilder } from "@ibcornelsen/database/client";
import { inferProcedureInput, inferProcedureOutput } from "@trpc/server";
export type UploadedGebaeudeBild = Omit<
GebaeudeBilder,
@@ -66,3 +66,5 @@ export type BedarfsausweisWohnenClient = inferProcedureInput<
export type GebaeudeClient = inferProcedureInput<
AppRouter["v1"]["verbrauchsausweisWohnen"]["2016"]["speichern"]
>["gebaeude"];
export type BenutzerClient = inferProcedureOutput<AppRouter["v1"]["benutzer"]["fromPublicId"]>

View File

@@ -7,7 +7,7 @@
export let selectedPaymentType: Bezahlmethoden;
</script>
<button type="button" class="flex flex-col items-center cursor-pointer" class:bg-gray-100={paymentType == selectedPaymentType} on:click={() => selectedPaymentType = paymentType}>
<button type="button" data-test={paymentType} class="flex flex-col items-center cursor-pointer" class:bg-gray-100={paymentType == selectedPaymentType} on:click={() => selectedPaymentType = paymentType}>
<img src={icon} alt={name} />
<span aria-label={name}>
{name}

View File

@@ -67,7 +67,7 @@
maxlength="5"
/>
<div class="absolute top-[calc(100%+4px)] left-0 w-full bg-white py-2 shadow-md rounded-lg" hidden={hideZipDropdown}>
<div data-test="plz-container" class="absolute top-[calc(100%+4px)] left-0 w-full bg-white py-2 shadow-md rounded-lg" hidden={hideZipDropdown}>
{#each zipCodes as zipCode}
<div class="hover:bg-gray-100 cursor-pointer px-2 py-0.5" tabindex="-1" on:click={() => {
zip = zipCode.plz;

View File

@@ -1,5 +1,6 @@
---
import "../style/global.scss"
import "../../svelte-dialogs.config"
import Footer from '../components/Footer.astro';
import Header from '../components/Header.astro';
import SidebarLeft from '../components/SidebarLeft.astro';

View File

@@ -2,6 +2,7 @@
import i18next from "i18next";
import "../style/global.scss";
import "../../svelte-dialogs.config"
import Footer from "../components/Footer.astro";
import Header from "../components/Header.astro";
import SidebarLeft from "../components/SidebarLeft.astro";

View File

@@ -0,0 +1,137 @@
<script lang="ts">
import { BenutzerClient, GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
import { addNotification, updateNotification } from "@ibcornelsen/ui";
import { validateAccessTokenClient } from "#client/lib/validateAccessToken";
import { client } from "src/trpc";
import EmbeddedAuthFlowModule from "#modules/EmbeddedAuthFlowModule.svelte";
import Overlay from "#components/Overlay.svelte";
export let gebaeude: GebaeudeClient;
export let images: UploadedGebaeudeBild[];
export let ausweis: VerbrauchsausweisWohnenClient;
export let user: BenutzerClient;
async function bilderHochladen() {
// Alle Bilder hochladen
const notification = addNotification({
dismissable: false,
message: "Bilder hochladen.",
subtext: `${images.length} Bilder werden hochgeladen, bitte haben sie Geduld.`,
timeout: 0,
type: "info"
})
for (let i = 0; i < images.length; i++) {
const image = images[i];
if (image.uid) {
// Bild wurde bereits hochgeladen, wir müssen es also nicht nochmal hochladen.
continue
}
try {
const response = await client.v1.bilder.upload.mutate({
base64: image.base64,
kategorie: image.kategorie,
gebaeude_uid: gebaeude.uid
})
image.uid = response.uid
updateNotification(notification, {
dismissable: true,
message: "Bild hochgeladen.",
subtext: `${i + 1}/${images.length} Bildern wurden erfolgreich hochgeladen, bitte haben sie Geduld.`,
timeout: 4000
})
} catch (e) {
updateNotification(notification, {
dismissable: true,
message: "Bild konnte nicht hochgeladen werden.",
subtext: `Bild ${i + 1}/${images.length} konnte nicht hochgeladen werden, wir haben bereits ein Ticket erstellt und melden uns so schnell wie möglich bei ihnen.`,
timeout: 150000,
type: "error"
})
}
}
}
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.
if (!await validateAccessTokenClient()) {
loginOverlayHidden = false;
return
}
loginOverlayHidden = true;
if (ausweis.uid) {
// Anscheinend wurde der Ausweis bereits erstellt und hat eine UID.
// Jetzt müssen wir ihn nun nur noch abspeichern.
try {
await client.v1.verbrauchsausweisWohnen[2016].speichern.mutate({
ausweis,
gebaeude
})
await bilderHochladen();
return true;
} catch (e) {
// TODO: Ticket mit Fehldermeldung abschicken.
}
} else {
// Wir speichern den Ausweis ab und leiten auf die "ausweis-gespeichert" Seite weiter.
try {
const response = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
ausweis,
gebaeude
})
ausweis.uid = response.uid;
gebaeude.uid = response.gebaeude_uid;
await bilderHochladen();
return true;
} catch (e: any) {
await client.v1.tickets.erstellen.mutate({
titel: "Ausweis konnte nicht gespeichert werden",
beschreibung: e.stack,
email: user.email ?? "",
metadata: JSON.stringify({
ausweis,
gebaeude
})
})
// TODO: Ticket mit Fehldermeldung abschicken.
}
}
addNotification({
dismissable: false,
message: "Ausweis konnte nicht gespeichert werden, bitte versuchen sie es erneut.",
subtext: "Sollte das Problem weiterhin bestehen, kontaktieren sie bitte den Support.",
timeout: 6000,
type: "error"
})
return false
}
async function ausweisAbschicken(e: SubmitEvent) {
e.preventDefault()
const result = await ausweisSpeichern();
if (result === true) {
window.location.href = `/kundendaten?uid=${ausweis.uid}`;
}
}
let loginOverlayHidden = true;
</script>
<Overlay bind:hidden={loginOverlayHidden}>
<div class="bg-white w-full max-w-screen-sm py-8">
<EmbeddedAuthFlowModule onLogin={ausweisAbschicken}></EmbeddedAuthFlowModule>
</div>
</Overlay>
<button type="submit" class="button">Weiter</button>

View File

@@ -20,14 +20,22 @@
import EmbeddedAuthFlowModule from "#modules/EmbeddedAuthFlowModule.svelte";
import AusweisGespeichertModule from "./AusweisGespeichertModule.svelte";
import { validateAccessTokenClient } from "src/client/lib/validateAccessToken";
import { UploadedGebaeudeBild, VerbrauchsausweisWohnenClient, GebaeudeClient } from "#components/Ausweis/types";
import { UploadedGebaeudeBild, VerbrauchsausweisWohnenClient, GebaeudeClient, BenutzerClient } from "#components/Ausweis/types";
export let gebaeude: GebaeudeClient = {} as GebaeudeClient;
export let images: UploadedGebaeudeBild[] = [];
export let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient;
export let user: BenutzerClient = {} as BenutzerClient;
async function uploadImages() {
async function bilderHochladen() {
// Alle Bilder hochladen
const notification = addNotification({
dismissable: false,
message: "Bilder hochladen.",
subtext: `${images.length} Bilder werden hochgeladen, bitte haben sie Geduld.`,
timeout: 0,
type: "info"
})
for (let i = 0; i < images.length; i++) {
const image = images[i];
if (image.uid) {
@@ -35,14 +43,6 @@
continue
}
const notification = addNotification({
dismissable: false,
message: "Bilder hochladen.",
subtext: `Bild ${i + 1}/${images.length} wird hochgeladen, bitte haben sie Geduld.`,
timeout: 0,
type: "info"
})
try {
const response = await client.v1.bilder.upload.mutate({
base64: image.base64,
@@ -55,7 +55,7 @@
updateNotification(notification, {
dismissable: true,
message: "Bild hochgeladen.",
subtext: `Bild ${i + 1}/${images.length} wurde erfolgreich hochgeladen.`,
subtext: `${i + 1}/${images.length} Bildern wurden erfolgreich hochgeladen, bitte haben sie Geduld.`,
timeout: 4000
})
} catch (e) {
@@ -74,6 +74,8 @@
// 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.
if (!await validateAccessTokenClient()) {
// TOOD: Auf Dialog umstellen.
//await spawnLoginPrompt();
loginOverlayHidden = false;
return
}
@@ -89,23 +91,14 @@
gebaeude
})
await uploadImages();
await bilderHochladen();
return true;
} catch (e) {
addNotification({
dismissable: false,
message: "Ausweis konnte nicht gespeichert werden, bitte versuchen sie es erneut.",
subtext: "Sollte das Problem weiterhin bestehen, kontaktieren sie bitte den Support.",
timeout: 6000,
type: "error"
})
return false
// TODO: Ticket mit Fehldermeldung abschicken.
}
} else {
// Wir speichern den Ausweis ab und leiten auf die "ausweis-gespeichert" Seite weiter.
console.log(ausweis, gebaeude);
try {
const response = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
ausweis,
@@ -114,10 +107,23 @@
ausweis.uid = response.uid;
gebaeude.uid = response.gebaeude_uid;
await uploadImages();
await bilderHochladen();
return true;
} catch (e) {
} catch (e: any) {
await client.v1.tickets.erstellen.mutate({
titel: "Ausweis konnte nicht gespeichert werden",
beschreibung: e.stack,
email: user.email ?? "",
metadata: JSON.stringify({
ausweis,
gebaeude
})
})
// TODO: Ticket mit Fehldermeldung abschicken.
}
}
addNotification({
dismissable: false,
message: "Ausweis konnte nicht gespeichert werden, bitte versuchen sie es erneut.",
@@ -125,9 +131,7 @@
timeout: 6000,
type: "error"
})
return false;
}
}
return false
}
async function spaeterWeitermachen() {
@@ -165,7 +169,7 @@
async function ausweisAbschicken(e: SubmitEvent) {
e.preventDefault()
if (e && e.preventDefault) e.preventDefault();
const result = await ausweisSpeichern();
if (result === true) {
@@ -180,7 +184,7 @@
<Overlay bind:hidden={loginOverlayHidden}>
<div class="bg-white w-full max-w-screen-sm py-8">
<EmbeddedAuthFlowModule onLogin={spaeterWeitermachen}></EmbeddedAuthFlowModule>
<EmbeddedAuthFlowModule onLogin={ausweisAbschicken}></EmbeddedAuthFlowModule>
</div>
</Overlay>

View File

@@ -1,8 +1,9 @@
<script lang="ts">
import { loginClient } from "#lib/login";
import EmbeddedLoginModule from "./EmbeddedLoginModule.svelte"
import EmbeddedRegisterModule from "./EmbeddedRegisterModule.svelte"
export let onLogin: () => void
export let onLogin: (response: Awaited<ReturnType<typeof loginClient>>) => any;
let route: "login" | "signup" = "login"

View File

@@ -5,7 +5,7 @@
export let navigate: (target: string) => void;
export let data: { email: string; passwort: string };
export let onLogin: (response: Awaited<ReturnType<typeof loginClient>>) => void;
export let onLogin: (response: Awaited<ReturnType<typeof loginClient>>) => any;
async function login(e: SubmitEvent) {
e.preventDefault()

View File

@@ -44,10 +44,6 @@
async function createPayment(e: SubmitEvent) {
e.preventDefault()
if (form.checkValidity() === false) {
form.reportValidity();
return;
}
const response = await client.v1.rechnungen.erstellen.mutate({
...rechnung,
@@ -57,10 +53,8 @@
services: services.filter(service => service.selected).map(service => service.id)
})
//window.location.href = response.checkout_url
window.location.href = response.checkout_url
}
let form: HTMLFormElement;
</script>
<div class="w-full px-8">
@@ -74,7 +68,7 @@
<div
class="w-full"
>
<form class="flex flex-row gap-8" bind:this={form}>
<form class="flex flex-row gap-8" on:submit={createPayment}>
<div class="w-3/5">
<div class="GRB3">
<HelpLabel title="Ansprechpartner" />
@@ -101,7 +95,7 @@
<!-- Nachname -->
<div>
<Label>Nachname *</Label>
<input name="nachname" type="text" bind:value={user.name} required />
<input name="name" type="text" bind:value={user.name} required />
</div>
</div>
<div class="grid grid-cols-2 gap-4">
@@ -130,7 +124,7 @@
<div>
<Label>Empfänger *</Label>
<input
name="Rempfaenger"
name="rechnung_empfaenger"
type="text"
bind:value={rechnung.empfaenger}
required
@@ -143,7 +137,8 @@
<div>
<Label>Zusatzzeile</Label>
<input
name="Rzusatzzeile"
name="rechnung_zusatzzeile"
bind:value={rechnung.zusatzzeile}
type="text"
data-rule-maxlength="80"
data-msg-maxlength="max. 80 Zeichen"
@@ -155,7 +150,7 @@
<div>
<Label>Straße, Hausnummer *</Label>
<input
name="Rstrasse"
name="rechnung_strasse"
bind:value={rechnung.strasse}
type="text"
required
@@ -166,7 +161,7 @@
<!-- PLZ -->
<ZipSearch
name="versand_plz"
name="rechnung_plz"
bind:zip={rechnung.plz}
bind:city={rechnung.ort}
/>
@@ -187,13 +182,13 @@
<!-- Telefon -->
<div>
<Label>Telefon</Label>
<input name="Rtelefon" bind:value={rechnung.telefon} type="text" />
<input name="rechnung_telefon" bind:value={rechnung.telefon} type="text" />
</div>
<!-- Email -->
<div>
<Label>E-Mail</Label>
<input name="Remail" bind:value={rechnung.email} type="email" />
<input name="rechnung_email" bind:value={rechnung.email} type="email" />
</div>
</div>
</div>
@@ -207,7 +202,7 @@
<input
class="w-[15px] h-[15px]"
type="checkbox"
id="deliveryAddress"
name="abweichende_versand_adresse"
bind:checked={rechnung.abweichende_versand_adresse}
/>
<Label>Abweichende Versandadresse</Label>
@@ -217,7 +212,7 @@
<div>
<Label>Empfänger *</Label>
<input
name="Vempfaenger"
name="versand_empfaenger"
type="text"
readonly={!rechnung.abweichende_versand_adresse}
bind:value={rechnung.versand_empfaenger}
@@ -231,7 +226,7 @@
<div>
<Label>Zusatzzeile</Label>
<input
name="Vzusatzzeile"
name="versand_zusatzzeile"
type="text"
readonly={!rechnung.abweichende_versand_adresse}
bind:value={rechnung.versand_zusatzzeile}
@@ -245,10 +240,10 @@
<div>
<Label>Straße, Hausnummer *</Label>
<input
name="Vstrasse"
name="versand_strasse"
type="text"
readonly={!rechnung.abweichende_versand_adresse}
bind:value={rechnung.strasse}
bind:value={rechnung.versand_strasse}
required
data-rule-maxlength="40"
data-msg-maxlength="max. 40 Zeichen"
@@ -257,7 +252,7 @@
<!-- PLZ -->
<ZipSearch
name="rplz"
name="versand_plz"
readonly={!rechnung.abweichende_versand_adresse}
bind:zip={rechnung.versand_plz}
bind:city={rechnung.versand_ort}
@@ -267,7 +262,7 @@
<div>
<Label>Ort *</Label>
<input
name="Vort"
name="versand_ort"
type="text"
readonly
required
@@ -283,24 +278,24 @@
<HelpLabel title="Bezahlmethode" />
<hr />
<div class="flex flex-row justify-between gap-4">
<PaymentOption paymentType={Enums.Bezahlmethoden.PAYPAL} bind:selectedPaymentType name={"PayPal"} icon={"/images/paypal.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.SOFORT} bind:selectedPaymentType name={"Sofort"} icon={"/images/sofort.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.GIROPAY} bind:selectedPaymentType name={"Giropay"} icon={"/images/giropay.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.KREDITKARTE} bind:selectedPaymentType name={"Kreditkarte"} icon={"/images/mastercard.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.RECHNUNG} bind:selectedPaymentType name={"Rechnung"} icon={"/images/rechnung.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.paypal} bind:selectedPaymentType name={"PayPal"} icon={"/images/paypal.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.sofort} bind:selectedPaymentType name={"Sofort"} icon={"/images/sofort.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.giropay} bind:selectedPaymentType name={"Giropay"} icon={"/images/giropay.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.creditcard} bind:selectedPaymentType name={"Kreditkarte"} icon={"/images/mastercard.png"}></PaymentOption>
<PaymentOption paymentType={Enums.Bezahlmethoden.rechnung} bind:selectedPaymentType name={"Rechnung"} icon={"/images/rechnung.png"}></PaymentOption>
</div>
<div class="w-1/2">
<div class="flex-row justify-between">
<h5>{selectedPaymentType}</h5>
<img
src="../../images/{selectedPaymentType ==
Enums.Bezahlmethoden.KREDITKARTE
Enums.Bezahlmethoden.creditcard
? 'mastercard'
: selectedPaymentType}.png"
class="payment-option-logo"
/>
</div>
{#if selectedPaymentType == Enums.Bezahlmethoden.RECHNUNG}
{#if selectedPaymentType == Enums.Bezahlmethoden.rechnung}
<p>
Sobald sie AGB und Datenschutzerklärung
gelesen und akzeptiert haben können sie den
@@ -322,8 +317,8 @@
{/if}
<div class="column">
<div class="flex-row center">
<input type="checkbox" bind:checked={agbAkzeptiert} />
<label for="accept-agb"
<input type="checkbox" name="agb-akzeptieren" bind:checked={agbAkzeptiert} />
<label for="agb-akzeptieren"
>Ich erkläre mich mit den <a
href="https://online-energieausweis.org/agb"
>AGB</a
@@ -333,9 +328,10 @@
<div class="flex-row center">
<input
type="checkbox"
name="datenschutz-akzeptieren"
bind:checked={datenschutzAkzeptiert}
/>
<label for="accept-datenschutz"
<label for="datenschutz-akzeptieren"
>Ich erkläre mich mit der <a
href="https://online-energieausweis.org/impressum"
>Datenschutzerklärung</a
@@ -349,7 +345,6 @@
</div>
</div>
<button type="submit" class="pay-button" disabled={!agbAkzeptiert || !datenschutzAkzeptiert}
on:click={createPayment}
>Kostenpflichtig Bestellen</button
>
</div>

View File

@@ -8,21 +8,22 @@
export let redirect: string | null = null;
async function login(e: SubmitEvent) {
e.preventDefault()
const response = await loginClient(email, passwort)
e.preventDefault();
const response = await loginClient(email, passwort);
if (response === null) {
addNotification({
message: "Ups...",
subtext: "Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?",
subtext:
"Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?",
type: "error",
timeout: 6000,
dismissable: true
})
dismissable: true,
});
} else {
if (redirect) {
window.location.href = redirect
return
window.location.href = redirect;
return;
}
window.location.href = "/user";
@@ -58,7 +59,9 @@
<button type="submit">Einloggen</button>
<div class="flex-row justify-between" style="margin-top: 10px">
<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>
</form>
</div>

View File

@@ -4,8 +4,9 @@ import AusweisLayout from "#layouts/AusweisLayout.astro";
import VerbrauchsausweisWohnenModule from "#modules/Ausweise/VerbrauchsausweisWohnenModule.svelte";
import { prisma } from "@ibcornelsen/database/server";
import { exclude } from "#lib/exclude";
import { UploadedGebaeudeBild, VerbrauchsausweisWohnenClient, GebaeudeClient } from "#components/Ausweis/types";
import { UploadedGebaeudeBild, VerbrauchsausweisWohnenClient, GebaeudeClient, BenutzerClient } from "#components/Ausweis/types";
import { createCaller } from "#lib/caller";
import { API_UID_COOKIE_NAME } from "#lib/constants";
const uid = Astro.url.searchParams.get("uid");
let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient;
@@ -44,6 +45,14 @@ if (uid) {
}
}
const benutzerUid = Astro.cookies.get(API_UID_COOKIE_NAME).value
let user: BenutzerClient = {} as BenutzerClient;
if (benutzerUid) {
user = await createCaller(Astro).v1.benutzer.fromPublicId({
uid: benutzerUid
})
}
---
<AusweisLayout title="Verbrauchsausweis erstellen">

20
svelte-dialogs.config.ts Normal file
View File

@@ -0,0 +1,20 @@
import { dialogs } from "svelte-dialogs";
dialogs.config({
global: {
inputClass: "px-2.5 py-1.5 rounded-lg border bg-white",
inputLabelClass: "text-gray-500 bg-white ml-2 w-fit",
bodyClass: "bg-white flex flex-col gap-4",
dialogClass: "bg-white rounded-md px-8 py-8",
cancelButtonClass: "button",
footerClass: "flex justify-end bg-white mt-4 gap-4",
resetButton: false,
submitButtonClass: "button",
titleClass: "text-2xl font-bold mb-4",
dividerClass: "border-b border-gray-200",
closeOnBg: true,
closeOnEsc: true
}
});
export { dialogs }

View File

@@ -25,6 +25,8 @@
"#components/*": ["./src/components/*"],
"#layouts/*": ["./src/layouts/*"],
"#modules/*": ["./src/modules/*"],
"#client/*": ["./src/modules/*"],
"#server/*": ["./src/modules/*"],
},
"types": ["cypress", "cypress-file-upload", "bun-types"]
}