Kaufabschluss funktioniert.

Kaufabschluss funktioniert einzeln, gesamter Durchgang geht auch. Input Validation ist der nächste große Schritt. Im Formular kommen immer noch viele Werte raus die wir nicht in der Datenbank haban wollen...
This commit is contained in:
Moritz Utcke
2024-01-11 13:41:40 +07:00
parent b20b857a7d
commit d9ac5cf69c
23 changed files with 489 additions and 90 deletions

View File

@@ -9,18 +9,79 @@
import ZipSearch from "#components/ZIPSearch.svelte";
import moment from "moment";
import BilderZusatzsysteme from "#components/Ausweis/BilderZusatzsysteme.svelte";
import { RawNotificationWrapper, RawNotification, notifications } from "@ibcornelsen/ui";
import { RawNotificationWrapper, RawNotification, notifications, addNotification } from "@ibcornelsen/ui";
import { auditHeizungGebaeudeBaujahr } from "#components/Verbrauchsausweis/audits/HeizungGebaeudeBaujahr";
import { AuditType, hidden } from "#components/Verbrauchsausweis/audits/hidden";
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt";
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung";
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
import { client } from "src/trpc";
import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
import Overlay from "#components/Overlay.svelte";
export let uid: string = "";
export let uid: string | null = null;
let gebaeude: GebaeudeStammdaten = {} as GebaeudeStammdaten;
let ausweis: VerbrauchsausweisWohnen = {} as VerbrauchsausweisWohnen;
async function spaeterWeitermachen() {
// 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 (!Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)) {
loginOverlayHidden = false;
const getEvent = (event: MessageEvent) => {
if (event.data == "AUTHORIZED") {
spaeterWeitermachen();
window.removeEventListener("message", getEvent)
loginOverlayHidden = true;
}
}
window.addEventListener("message", getEvent)
return
}
if (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_stammdaten: gebaeude,
uid
})
window.location.href = `/ausweis-gespeichert?uid=${uid}`;
} 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"
})
}
} else {
// Wir speichern den Ausweis ab und leiten auf die "ausweis-gespeichert" Seite weiter.
try {
const { uid } = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
...ausweis,
gebaeude_stammdaten: gebaeude
})
window.location.href = `/ausweis-gespeichert?uid=${uid}`;
} 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"
})
}
}
}
export let gebaeude: GebaeudeStammdaten = {} as GebaeudeStammdaten;
export let ausweis: VerbrauchsausweisWohnen = {} as VerbrauchsausweisWohnen;
if (uid) {
// NOTE: Funktioniert nicht mehr
async () => {
@@ -63,7 +124,7 @@
async function ausweisAbschicken() {
overlay.ariaHidden = "false";
waitOverlayHidden = false;
const response = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
...ausweis,
gebaeude_stammdaten: gebaeude
@@ -72,13 +133,17 @@
window.location.href = `/kundendaten?uid=${response.uid}`;
}
let overlay: HTMLDivElement;
let waitOverlayHidden = true;
let loginOverlayHidden = true;
</script>
<div bind:this={overlay} aria-hidden="true" class="aria-hidden:hidden fixed top-0 left-0 w-[100vw] h-[100vh] flex items-center justify-center bg-[rgba(0,0,0,0.8)] z-50">
<Overlay hidden={loginOverlayHidden}>
<iframe src="/auth/embedded-login" frameborder="0" width="600" height="400"></iframe>
</Overlay>
<Overlay hidden={waitOverlayHidden}>
<p class="text-white font-semibold text-4xl">Bitte warten sie, ihr Ausweis wird nun erstellt.</p>
</div>
</Overlay>
<div class="flex flex-row gap-8 items-center mb-8">
<div class="flex flex-col w-full">
@@ -94,7 +159,7 @@
class="bg-[rgba(252,234,187,0.2)] border-2 p-4 rounded-lg border-[#ffcc03]"
>
<div class="flex flex-row justify-between">
<a class="button" href="/speichern">Später Weitermachen</a>
<button class="button" on:click={spaeterWeitermachen}>Später Weitermachen</button>
<div class="flex gap-4">
<Hilfe />
<button
@@ -231,15 +296,22 @@
<div class="GRB">
<!-- Anteil WW enthalten -->
<div class="flex flex-col">
<div class="flex flex-row gap-6">
<label class="radio-inline"
><input
<div class="flex flex-row gap-4 items-center">
<Label>Warmwasser im Verbrauch enthalten</Label>
<input
type="checkbox"
name="warmwasser_enthalten"
bind:checked={ausweis
.warmwasser_enthalten}
/>Warmwasser im Verbrauch enthalten</label
>
bind:checked={ausweis.warmwasser_enthalten}
/>
</div>
<div class="flex flex-row gap-4 items-center">
<Label>Anteil bekannt</Label>
<input
type="checkbox"
name="warmwasser_anteil_bekannt"
bind:checked={ausweis.warmwasser_anteil_bekannt}
disabled={!ausweis.warmwasser_enthalten}
/>
</div>
</div>
@@ -255,7 +327,7 @@
maxlength="2"
type="number"
bind:value={ausweis.anteil_warmwasser_1}
disabled={!ausweis.warmwasser_enthalten}
disabled={!ausweis.warmwasser_anteil_bekannt}
autocomplete="off"
/>
</div>
@@ -273,7 +345,7 @@
autocomplete="off"
bind:value={ausweis.anteil_warmwasser_2}
disabled={!ausweis.zusaetzliche_heizquelle ||
!ausweis.warmwasser_enthalten}
!ausweis.warmwasser_anteil_bekannt}
/>
</div>

View File

@@ -0,0 +1,56 @@
<script lang="ts">
import { addNotification } from "@ibcornelsen/ui";
import { loginClient } from "#lib/login";
let email: string;
let passwort: string;
async function login() {
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?",
type: "error",
timeout: 6000,
dismissable: true
})
} else {
parent.postMessage("AUTHORIZED", "*");
}
}
</script>
<div style="width:50%;margin: 0 auto">
<h1>Login</h1>
<div class="flex flex-col gap-4">
<div>
<h4>Email</h4>
<input
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
type="text"
placeholder="Email"
name="email"
bind:value={email}
required
/>
</div>
<div>
<h4>Passwort</h4>
<input
class="px-2.5 py-1.5 rounded-lg border bg-gray-50"
type="password"
placeholder="********"
name="password"
bind:value={passwort}
required
/>
</div>
<button class="button" on:click={login}>Einloggen</button>
<div class="flex-row justify-between" style="margin-top: 10px">
<a href="/signup">Registrieren</a>
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
</div>
</div>
</div>

View File

@@ -6,6 +6,7 @@
import PriceContainer from "#components/Kaufabschluss/PriceContainer.svelte";
import { Benutzer, Bezahlmethoden, Enums, Rechnungen, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
import PaymentOption from "#components/PaymentOption.svelte";
import { client } from "src/trpc";
export let user: Benutzer;
export let ausweis: VerbrauchsausweisWohnen
@@ -15,6 +16,17 @@
let agbAkzeptiert: boolean;
let datenschutzAkzeptiert: boolean;
async function createPayment() {
const response = await client.v1.payments.create.mutate({
ausweisart: "VerbrauchsausweisWohnen",
uid: ausweis.uid,
payment_method: selectedPaymentType,
services: []
})
window.location.href = response.checkout_url
}
</script>
<div class="w-full px-8">
@@ -303,6 +315,7 @@
</div>
</div>
<button class="pay-button" disabled={!agbAkzeptiert || !datenschutzAkzeptiert}
on:click={createPayment}
>Kostenpflichtig Bestellen</button
>
</div>

View File

@@ -1,26 +1,16 @@
<script lang="ts">
import Cookies from "js-cookie"
import { addNotification } from "@ibcornelsen/ui";
import { client } from "src/trpc";
import { loginClient } from "#lib/login";
let email: string;
let passwort: string;
export let redirect: string | null = null;
async function login() {
try {
const response = await client.v1.benutzer.getRefreshToken.query({
email,
passwort
})
const options = {
domain: `.${window.location.hostname}`,
path: "/",
expires: response.exp
}
Cookies.set("accessToken", response.accessToken, options);
Cookies.set("refreshToken", response.refreshToken, options);
window.location.href = "/user";
} catch (e) {
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?",
@@ -28,6 +18,13 @@
timeout: 6000,
dismissable: true
})
} else {
if (redirect) {
window.location.href = redirect
return
}
window.location.href = "/user";
}
}
</script>
@@ -59,8 +56,8 @@
</div>
<button class="button" on:click={login}>Einloggen</button>
<div class="flex-row justify-between" style="margin-top: 10px">
<a href="/signup">Registrieren</a>
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
<a href="/signup?redirect={redirect}">Registrieren</a>
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
</div>
</div>
</div>

View File

@@ -7,14 +7,22 @@
let vorname: string;
let name: string;
export let redirect: string | null = null;
async function login() {
try {
const response = await client.v1.benutzer.erstellen.query({
const response = await client.v1.benutzer.erstellen.mutate({
email,
passwort,
vorname,
name
})
if (redirect) {
window.location.href = redirect
return
}
window.location.href = "/login";
} catch (e) {
addNotification({
@@ -78,9 +86,9 @@
>
<div class="flex-row justify-between" style="margin-top: 10px">
<a
href="/login">Einloggen</a
href="/login?redirect={redirect}">Einloggen</a
>
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
<a href="/user/passwort_vergessen?redirect={redirect}">Passwort Vergessen?</a>
</div>
</div>
</div>