Merge branch 'main' into UMBE

This commit is contained in:
UMBENOMENA
2024-11-19 19:45:55 +01:00
committed by GitHub
34 changed files with 329 additions and 220 deletions

View File

@@ -23,4 +23,4 @@ jobs:
git clean -f -d
git pull origin main
git status
bash build.sh
make prod

View File

@@ -1,4 +1,4 @@
.PHONY: dev database api online-energieausweis all
.PHONY: dev database api online-energieausweis all prod bun-install-database bun-install-api
online-energieausweis:
bun run dev
@@ -6,13 +6,47 @@ online-energieausweis:
dev: online-energieausweis api database
database:
$(MAKE) -C ../database dev
bun-install-database:
cd ../database
docker compose up
bun link
bun install
bun-install-api: bun-install-database
cd ../api
bun install
bun link @ibcornelsen/database
api:
cd ../api
bun run dev
$(MAKE) -C ../api dev
all:
mkdir -p ~/logs
bun run dev 2>&1 | tee ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log
prod: bun-install-api bun-install-database
mkdir -p ~/logs
mkdir -p ~/persistent/online-energieausweis
# Wir müssen sichergehen, dass der Database Container läuft, sonst können wir ihn nicht linken.
@if [ ! $$(docker ps | grep database | wc -l) -gt 0 ]; then \
cd ../database; \
$(MAKE) prod; \
cd ../online-energieausweis; \
fi
# Auch die API sollte bereits laufen
@if [ $$(pm2 pid api) -eq "0" ]; then \
cd ../api; \
$(MAKE) prod; \
cd ../online-energieausweis; \
fi
- rm -f ~/online-energieausweis/.env;
- touch ~/online-energieausweis/.env;
- echo "PRIVATE_KEY=$(cat /etc/letsencrypt/live/ibcornelsen.de/privkey.pem | base64 | tr -d '\n')" >> ~/online-energieausweis/.env;
- echo "CERTIFICATE=$(cat /etc/letsencrypt/live/ibcornelsen.de/fullchain.pem | base64 | tr -d '\n')" >> ~/online-energieausweis/.env;
- pm2 delete online-energieausweis
pm2 start --name "online-energieausweis" --log ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log --time bun -- astro dev

View File

@@ -1,41 +1,39 @@
import { defineConfig } from "astro/config";
import svelte from "@astrojs/svelte";
// import astroI18next from "astro-i18next";
import tailwind from "@astrojs/tailwind";
// https://astro.build/config
import node from "@astrojs/node";
// https://astro.build/config
import mdx from "@astrojs/mdx";
import { fileURLToPath } from "url";
// https://astro.build/config
// https://astro.build/config
export default defineConfig({
integrations: [svelte(), tailwind(), mdx()],
outDir: "./dist",
output: "server",
vite: {
optimizeDeps: {
exclude: ["@ibcornelsen/api", "@ibcornelsen/database"]
vite: {
optimizeDeps: {
exclude: ["@ibcornelsen/api", "@ibcornelsen/database"]
},
resolve: {
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url))
}
},
ssr: {
noExternal: ["@pdfme/generator", "@pdfme/common", "@pdfme/schemas"]
},
resolve: {
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url))
}
},
build: {
commonjsOptions: {
transformMixedEsModules: true
}
}
},
build: {
commonjsOptions: {
transformMixedEsModules: false
}
}
},
adapter: node({
mode: "middleware"
}),
server: {
port: 3000
}
server: {
port: 3000
}
});

View File

@@ -14,38 +14,24 @@ DB_PORT=5432
# ausgeführt zu werden. Außerdem würde es nicht wirklich Sinn ergeben, wenn das
# Build Skript sich die Änderungen am build Skript holen würde...
# Wir müssen alle lokalen Pakete verlinken
# --------------------------------- Database --------------------------------- #
cd ../database
bun link
cd ../api
bun link
cd ../ui
bun link
cd ../database
bun install
# ------------------------------------ API ----------------------------------- #
cd ../api
bun install
cd ../ui
bun install
bun link @ibcornelsen/database
# ------------------------------------ APP ----------------------------------- #
cd ../$APP_NAME
# Als erstes linken wir das package mit yalc, damit wir z.B. in online-energieausweis darauf zugreifen können.
cd ../database
bunx yalc push --scripts
cd ../api
bunx yalc push --scripts
cd ../$APP_NAME
bunx yalc add @ibcornelsen/database
bunx yalc add @ibcornelsen/api
# Dann installieren wir noch einmal alle dependencies, das ist besonders wichtig
# falls wir lokal verlinkte Projekte haben, sonst werden die nicht in unser
# docker image übernommen
bun install
# Dann stoppen wir unser altes docker image und bauen es neu.
docker stop $APP_NAME
docker rm $APP_NAME
docker build -t $APP_NAME .
bun link @ibcornelsen/database
# Jeder unserer Applikationen hat ein Verzeichnis in dem alle Dateien dauerhaft,
# Versionsunabhängig gespeichert werden. Dieses legen wir hier an, falls es noch
@@ -54,10 +40,10 @@ PERSISTENT_DIR="${HOME}/persistent/${APP_NAME}";
mkdir -p $PERSISTENT_DIR;
# TODO: Wir legen hier die .env Datei an, die die SSL Zertifikate enthält.
# rm -f ~/$APP_NAME/.env;
# touch ~/$APP_NAME/.env;
# echo "PRIVATE_KEY=$(cat /etc/letsencrypt/live/ibcornelsen.de/privkey.pem | base64 | tr -d '\n')" >> ~/$APP_NAME/.env;
# echo "CERTIFICATE=$(cat /etc/letsencrypt/live/ibcornelsen.de/fullchain.pem | base64 | tr -d '\n')" >> ~/$APP_NAME/.env;
rm -f ~/$APP_NAME/.env;
touch ~/$APP_NAME/.env;
echo "PRIVATE_KEY=$(cat /etc/letsencrypt/live/ibcornelsen.de/privkey.pem | base64 | tr -d '\n')" >> ~/$APP_NAME/.env;
echo "CERTIFICATE=$(cat /etc/letsencrypt/live/ibcornelsen.de/fullchain.pem | base64 | tr -d '\n')" >> ~/$APP_NAME/.env;
# Wir müssen sichergehen, dass der Database Container läuft, sonst können wir ihn nicht linken.
if [ ! $((docker ps | grep $DB_CONTAINER_NAME) | wc -l) -gt 0 ]; then
@@ -66,12 +52,20 @@ if [ ! $((docker ps | grep $DB_CONTAINER_NAME) | wc -l) -gt 0 ]; then
cd ../$APP_NAME;
fi
# Auch die API sollte bereits laufen
if [ $(pm2 pid api) -eq "0" ]; then
cd ../api;
make prod;
cd ../$APP_NAME;
fi
# Jetzt wo wir alle Vorbereitungen getroffen haben, starten wir das Docker Image und linken es mit der Datenbank.
docker run -d --name $APP_NAME --link $DB_CONTAINER_NAME \
-v "${PERSISTENT_DIR}:/persistent" \
-v "./node_modules/@ibcornelsen/database:/${APP_NAME}/node_modules/@ibcornelsen/database" \
-v "./node_modules/@ibcornelsen/api:/${APP_NAME}/node_modules/@ibcornelsen/api" \
-v "./node_modules/@ibcornelsen/ui:/${APP_NAME}/node_modules/@ibcornelsen/ui" \
-p "${APP_PORT}:3000" \
$APP_NAME;
# docker run -d --name $APP_NAME --link $DB_CONTAINER_NAME \
# -v "${PERSISTENT_DIR}:/persistent" \
# -v "./node_modules/@ibcornelsen/database:/${APP_NAME}/node_modules/@ibcornelsen/database" \
# -v "./node_modules/@ibcornelsen/api:/${APP_NAME}/node_modules/@ibcornelsen/api" \
# -v "./node_modules/@ibcornelsen/ui:/${APP_NAME}/node_modules/@ibcornelsen/ui" \
# -p "${APP_PORT}:3000" \
# $APP_NAME;
make prod

View File

@@ -17,62 +17,62 @@
},
"private": true,
"dependencies": {
"@astrojs/mdx": "^2.1.1",
"@astrojs/node": "^5.1.4",
"@astrojs/mdx": "^3.1.9",
"@astrojs/node": "^8.3.4",
"@astrojs/svelte": "^2.2.0",
"@astrojs/tailwind": "^3.1.3",
"@ibcornelsen/api": "link:@ibcornelsen/api",
"@ibcornelsen/database": "link:@ibcornelsen/database",
"@ibcornelsen/ui": "^0.0.2",
"@mollie/api-client": "^3.7.0",
"@pdfme/common": "^5.1.6",
"@pdfme/generator": "^5.1.6",
"@pdfme/ui": "^5.1.6",
"@trpc/client": "^10.45.0",
"@trpc/server": "^10.45.0",
"astro": "^2.5.1",
"@pdfme/common": "^5.1.7",
"@pdfme/generator": "^5.1.7",
"@pdfme/ui": "^5.1.7",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"astro": "^4.16.10",
"astro-i18next": "1.0.0-beta.21",
"body-scroll-lock": "^4.0.0-beta.0",
"buffer": "^6.0.3",
"bun": "^1.0.2",
"bun": "^1.1.34",
"csvtojson": "^2.0.10",
"express": "^4.18.2",
"flag-icons": "^6.9.2",
"fontkit": "^2.0.2",
"i18next": "^23.4.1",
"i18next-fs-backend": "^2.1.5",
"i18next-http-backend": "^2.2.1",
"express": "^4.21.1",
"flag-icons": "^6.15.0",
"fontkit": "^2.0.4",
"i18next": "^23.16.5",
"i18next-fs-backend": "^2.3.2",
"i18next-http-backend": "^2.6.2",
"js-cookie": "^3.0.5",
"js-interpolate": "^1.0.1",
"katex": "^0.16.7",
"moment": "^2.29.4",
"moment-timezone": "^0.5.45",
"postcss-nested": "^7.0.2",
"katex": "^0.16.11",
"moment": "^2.30.1",
"moment-timezone": "^0.5.46",
"radix-svelte-icons": "^1.0.0",
"sass": "^1.62.1",
"svelte": "^3.59.1",
"sass": "^1.80.6",
"svelte": "^3.59.2",
"svelte-dialogs": "^1.2.2",
"svelte-preprocess": "^5.0.3",
"svelte-ripple-action": "^1.0.5",
"tailwindcss": "^3.4.15",
"svelte-preprocess": "^5.1.4",
"svelte-ripple-action": "^1.0.6",
"tailwindcss": "^3.4.14",
"trpc-openapi": "^1.2.0",
"uuid": "^9.0.0",
"zod": "^3.22.4"
"uuid": "^9.0.1",
"zod": "^3.23.8"
},
"devDependencies": {
"@faker-js/faker": "^8.3.1",
"@tailwindcss/typography": "^0.5.10",
"@faker-js/faker": "^8.4.1",
"@tailwindcss/typography": "^0.5.15",
"@types/body-scroll-lock": "^3.1.2",
"@types/fontkit": "^2.0.6",
"@types/fontkit": "^2.0.7",
"@types/js-cookie": "^3.0.6",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
"autoprefixer": "^10.4.20",
"bun-types": "^1.0.22",
"cypress": "^13.6.2",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"bun-types": "^1.1.34",
"cypress": "^13.15.2",
"cypress-file-upload": "^5.0.8",
"daisyui": "^4.6.0",
"daisyui": "^4.12.14",
"eslint": "~8.15.0",
"eslint-config-prettier": "8.1.0",
"postcss": "^8.4.49",

View File

@@ -1,6 +1,6 @@
import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME, API_UID_COOKIE_NAME } from "../../lib/constants";
import { client } from "src/trpc";
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME, API_UID_COOKIE_NAME } from "#lib/constants.js";
import { client } from "../../trpc.js";
import moment from "moment";

View File

@@ -5,7 +5,7 @@
VerbrauchsausweisWohnenClient,
} from "./Ausweis/types.js";
import AusweisPruefenTooltip from "./AusweisPruefenTooltip.svelte";
import { addNotification } from "./NotificationProvider/shared";
import { addNotification } from "./NotificationProvider/shared.js";
import { CheckCircled, CrossCircled, Image } from "radix-svelte-icons";
import ChevronDown from "radix-svelte-icons/src/lib/icons/ChevronDown.svelte";
@@ -158,13 +158,13 @@
if (gebaeude_aufnahme_allgemein.solarsystem_warmwasser) {
// Wenn Warmwasser Anteil unbekannt und Solarsystem
verbrauchWWGesamt_1 =
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
" m² x 12 kWh/m² x 3 Jahre";
solarsystemWarmwasser = "Solarsystem Warmwasser";
} else {
// Wenn Warmwasser Anteil unbekannt und **kein** Solarsystem
verbrauchWWGesamt_1 =
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
" m² x 20 kWh/m² x 3 Jahre";
solarsystemWarmwasser = "kein Solarsystem Warmwasser";
}
@@ -181,7 +181,7 @@
ausweis.keller_beheizt +
" ) in m²";
table3Z1 = gebaeude_aufnahme_allgemein.flaeche;
table3Z2 = calculations?.energetische_nutzfläche;
table3Z2 = calculations?.energetischeNutzflaeche;
tooltip4Z1 =
@@ -261,7 +261,7 @@
tooltip8Z1 =
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
" m² x 6 kWh/m² x 3 Jahre >> Kühlungszuschlag in kWh";
tooltip8Z2 = "";
table8Z1 = calculations?.kuehlungsZuschlag;
@@ -277,7 +277,7 @@
" + " +
calculations?.energieVerbrauchHeizungBereinigt_2 +
") / (3 * " +
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
") >> Durchschnittsverbrauch Heizung in kWh";
table9Z1 =
calculations?.faktorDurchschnittsEnergieVerbrauchHeizungBereinigt;
@@ -288,7 +288,7 @@
"faktorDurchschnittsEnergieVerbrauchHeizungBereinigt"
] +
" x " +
calculations.leerstand +
calculations?.leerstand +
" x (" +
calculations.energieVerbrauchHeizungBereinigt_1 +
" + " +
@@ -304,21 +304,13 @@
table10Z1 = calculations?.leerstandsZuschlagHeizung;
table10Z2 = calculations?.leerstandsZuschlagWarmwasser;
tooltip11Z1 =
"(" +
calculations?.energieVerbrauchHeizungBereinigt_1 +
" + " +
calculations?.energieVerbrauchWarmwasser_1 +
") / (3 Jahre x " +
calculations?.energetische_nutzfläche +
") Endenergieverbrauch 1 in kWh/m²a";
tooltip11Z2 =
"(" +
calculations?.energieVerbrauchHeizungBereinigt_2 +
" + " +
calculations?.energieVerbrauchWarmwasser_2 +
") / (3 Jahre x " +
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
") Endenergieverbrauch 2 in kWh/m²a";
table11Z1 = calculations?.endEnergieVerbrauch_1;
table11Z2 = calculations?.endEnergieVerbrauch_2;
@@ -333,7 +325,7 @@
" x " +
calculations?.primaerfaktorww +
")) / (3 Jahre x " +
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
") Primärenergieverbrauch 1 in kWh/m²a";
tooltip12Z2 =
"((" +
@@ -345,7 +337,7 @@
" x " +
calculations?.primaerfaktorww_1 +
")) / (3 Jahre x " +
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
") Primärenergieverbrauch 2 in kWh/m²a";
table12Z1 = calculations?.primaerEnergieVerbrauch_1;
table12Z2 = calculations?.primaerEnergieVerbrauch_2;
@@ -356,13 +348,13 @@
" + " +
calculations?.leerstandsZuschlagWarmwasser +
") / (3 Jahre x " +
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
") Endenergieverbrauch Leerstand in kWh/m²a";
tooltip13Z2 =
"(" +
calculations?.kuehlungsZuschlag +
") / (3 Jahre x " +
calculations?.energetische_nutzfläche +
calculations?.energetischeNutzflaeche +
") Endenergieverbrauch Kühlung in kWh/m²a";
table13Z1 = calculations?.endEnergieVerbrauchLeerstandsZuschlag;
table13Z2 = calculations?.endEnergieVerbrauchKuehlungsZuschlag;
@@ -509,7 +501,7 @@
<span>{ausweis.faktorKeller} x {gebaeude_aufnahme_allgemein.flaeche}m² Energetische Nutzfläche (Keller {gebaeude_aufnahme_allgemein.keller}) in m²</span>
</div>
<span>{gebaeude_aufnahme_allgemein.flaeche}</span>
<span><strong>{calculations?.energetische_nutzfläche}</strong></span>
<span><strong>{calculations?.energetischeNutzflaeche}</strong></span>
</AusweisPruefenTooltip>
</td
>
@@ -604,7 +596,7 @@
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip11Z1}</span>
<span>({calculations?.energieVerbrauchHeizungBereinigt_1} + {calculations?.energieVerbrauchWarmwasser_1}) / (3 Jahre x {calculations?.energetischeNutzflaeche}) Endenergieverbrauch 1 in kWh/m²a</span>
<br>
<span>{tooltip11Z2}</span>
</div>
@@ -748,7 +740,7 @@
<td title="Ausweis ausstellen" class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => ausweisAusstellen('{gebaeude_aufnahme_allgemein.uid}')}>A</button
on:click={() => ausweisAusstellen(gebaeude_aufnahme_allgemein.uid)}>A</button
></td
>
<td
@@ -756,7 +748,7 @@
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => ausweisAusstellenPost('{gebaeude_aufnahme_allgemein.uid}')}>P</button
on:click={() => ausweisAusstellenPost(gebaeude_aufnahme_allgemein.uid)}>P</button
></td
>
<td
@@ -764,7 +756,7 @@
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => ausweisnichtAusstellen('{gebaeude_aufnahme_allgemein.uid}')}>N</button
on:click={() => ausweisnichtAusstellen(gebaeude_aufnahme_allgemein.uid)}>N</button
></td
>
<td
@@ -772,7 +764,7 @@
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => bestellBestaetigung('{gebaeude_aufnahme_allgemein.uid}')}>B</button
on:click={() => bestellBestaetigung(gebaeude_aufnahme_allgemein.uid)}>B</button
></td
>
<td
@@ -780,7 +772,7 @@
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => erinnern('{gebaeude_aufnahme_allgemein.uid}')}
on:click={() => erinnern(gebaeude_aufnahme_allgemein.uid)}
>E</button
></td
>
@@ -793,12 +785,16 @@
href="/energieausweis-erstellen/gespeichert?id={gebaeude_aufnahme_allgemein.uid}">F</a
></td
>
{@html gebaeude_aufnahme_allgemein.kontrolldatei
? `<td title="XML-Datei an das DiBT verschicken." class="w-4 p-1"><button class="btn btn-xs btn-ghost" on:click="xmlAbschicken('{gebaeude_aufnahme_allgemein.uid}')">X</button></td>`
: ""}
{@html !gebaeude_aufnahme_allgemein.registriernummer
? `<td title="Registriernummer vom DiBT anfordern." class="w-4 p-1"><button class="btn btn-xs btn-ghost" on:click="registriernummerAnfordern('{gebaeude_aufnahme_allgemein.uid}')">R</button></td>`
: ""}
{#if gebaeude_aufnahme_allgemein.kontrolldatei}
<td title="XML-Datei an das DiBT verschicken." class="w-4 p-1"><button class="btn btn-xs btn-ghost" on:click={() => {
xmlAbschicken(gebaeude_aufnahme_allgemein.uid)
}}>X</button></td>
{/if}
{#if !gebaeude_aufnahme_allgemein.registriernummer}
<td title="Registriernummer vom DiBT anfordern." class="w-4 p-1"><button class="btn btn-xs btn-ghost" on:click={() => {
registriernummerAnfordern(gebaeude_aufnahme_allgemein.uid)
}}>R</button></td>
{/if}
</tr>
</tbody>
</table>

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import {
VerbrauchsausweisWohnenClient,
} from "#components/Ausweis/types";
} from "#components/Ausweis/types.js";
import moment from "moment";
import { dialogs } from "svelte-dialogs";
import {
@@ -11,8 +11,8 @@
Pencil2,
QuestionMarkCircled,
} from "radix-svelte-icons";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
import { client } from "src/trpc";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import { client } from "src/trpc.js";
export let ausweis: VerbrauchsausweisWohnenClient;
export let progress: number;
@@ -167,7 +167,7 @@
{/await}
<div class="card-actions justify-end mt-8">
<a class="btn btn-primary" href="/energieausweis-erstellen/verbrauchsausweis-wohnen?uid={ausweis.uid}">Bearbeiten</a>
<a class="btn btn-ghost" title="PDF Herunterladen" target="_blank" href="/pdf/ansichtsausweis?ausweis_uid={ausweis.uid}">
<a class="btn btn-ghost" title="PDF Herunterladen" target="_blank" href="/pdf/ansichtsausweis?uid={ausweis.uid}">
<Download size={22} />
</a>
</div>

View File

@@ -4,7 +4,7 @@ import ThemeController from "./ThemeController.svelte";
const valid = await validateAccessTokenServer(Astro)
const lightTheme = Astro.cookies.get("theme").value === "light";
const lightTheme = Astro.cookies.get("theme")?.value === "light";
---
<header>

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import RawNotification from "./RawNotification.svelte";
import { Notification } from "./shared";
import { Notification } from "./shared.js";
export let notification: Notification & { uid: string };
</script>

View File

@@ -2,7 +2,7 @@
import Notification from "./Notification.svelte";
import RawNotificationWrapper from "./RawNotificationWrapper.svelte";
import { notifications } from "./shared";
import { notifications } from "./shared.js";
</script>
<RawNotificationWrapper>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { Notification, deleteNotification } from "./shared";
import { Notification, deleteNotification } from "./shared.js";
import { fly } from "svelte/transition";
export let notification: Partial<Notification> & { uid: string };

View File

@@ -0,0 +1,9 @@
import Notification from "./Notification.svelte";
export { Notification };
import NotificationWrapper from "./NotificationWrapper.svelte";
export { NotificationWrapper };
import RawNotificationWrapper from "./RawNotificationWrapper.svelte";
export { RawNotificationWrapper };
import RawNotification from "./RawNotification.svelte";
export { RawNotification };
export * from "./shared.js";

View File

@@ -1,4 +1,15 @@
---
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import SidebarWidgetLogin from "./SidebarWidgetLogin.svelte";
import SidebarWidgetProfile from "./SidebarWidgetProfile.svelte"
const loggedin = await validateAccessTokenServer(Astro)
---
<div class="flex flex-col gap-4">
{ !loggedin ?
<SidebarWidgetLogin client:load></SidebarWidgetLogin> : <SidebarWidgetProfile></SidebarWidgetProfile>}
<div class="infoCard">
<h2 style="font-weight: bold; font-size: 1.2em; color: #3A4AB5;">
Rufen Sie uns an<br /> Wir sind gerne für Sie da

View File

@@ -0,0 +1,96 @@
<script lang="ts">
import { loginClient } from "#lib/login";
import CrossCircled from "radix-svelte-icons/src/lib/icons/CrossCircled.svelte";
import { fade } from "svelte/transition";
let email: string;
let passwort: string;
async function login(e: SubmitEvent) {
console.log(e);
e.preventDefault();
const response = await loginClient(email, passwort);
if (response === null) {
errorHidden = false;
} else {
window.location.href = "/dashboard";
}
}
let errorHidden = true;
</script>
<div
id="card-login"
class="box card hidden bg-white px-6 py-4 mb-5
lg:block"
>
<div class="grid">
<div class="grid grid-cols-[2rem,1fr,1fr]">
<img
class="w-6 align-middle"
src="/images/right-sidebar/UMBE_user-icon.svg"
alt="user-icon"
/>
<h2 class="text-secondary">Kunden Login</h2>
<div class="justify-self-end text-secondary">
<a
class="text-lg font-bold text-box-heading leading-6 no-underline hover:text-primary"
href="">Kontakt</a
>
/
<a
class="text-lg font-bold text-box-heading leading-6 no-underline hover:text-primary"
href="">AGB</a
>
</div>
</div>
<hr class="mb-4" />
<form on:submit={login}>
<input
class="my-1 rounded-md px-2 py-1 ring-1 w-full"
type="text"
placeholder="nutzer@email.com"
name="email"
bind:value={email}
on:focus={() => (errorHidden = true)}
required
/>
<input
class="my-1 rounded-md px-2 py-1 ring-1 w-full"
type="password"
minlength="8"
placeholder="********"
name="passwort"
bind:value={passwort}
on:focus={() => (errorHidden = true)}
required
/>
{#if !errorHidden}
<div role="alert" class="alert alert-error" in:fade out:fade={{delay: 400}}>
<CrossCircled size={24} />
<span class="font-semibold">Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?</span>
</div>
{/if}
<button class="my-1 rounded-md px-2 py-1 ring-1 w-full bg-secondary text-white font-bold hover:bg-primary" type="submit">Einloggen</button>
</form>
<div class="grid grid-cols-[1fr,1fr]">
<a
class="justify-self-start text-sm font-bold no-underline hover:text-primary"
href="/auth/signup">Registrieren</a
>
<a
class="justify-self-end text-sm font-bold no-underline hover:text-primary"
href="/auth/passwort-vergessen">Passwort vergessen</a
>
</div>
<div></div>
</div>
</div>
<style lang="scss">
</style>

View File

@@ -0,0 +1,10 @@
<script lang="ts">
</script>
<div
id="card-login"
class="box card hidden bg-white px-6 py-4
lg:block"
>
<a href="/dashboard">Profil</a>
</div>

View File

@@ -1,5 +1,5 @@
---
import Login from "#components/UMBE_card-login.svelte";
import Login from "#components/SidebarWidgetLogin.svelte";
import Contact from "#components/UMBE_card-contact.svelte";
import Review from "#components/UMBE_card-review.svelte";
import VApromo from "#components/UMBE_card-VA-promo.svelte";

View File

@@ -1,44 +0,0 @@
<script>
</script>
<div id ="card-login"
class=" box card hidden bg-white px-6 py-4 mb-5
lg:block">
<div class="grid">
<div class="grid grid-cols-[2rem,1fr,1fr]">
<img class="w-6 align-middle" src="/images/right-sidebar/UMBE_user-icon.svg" alt="user-icon"/>
<h2 class="text-secondary">Kunden Login</h2>
<div class="justify-self-end text-secondary">
<a class="text-lg font-bold text-box-heading leading-6 no-underline hover:text-primary" href="">Kontakt</a> /
<a class="text-lg font-bold text-box-heading leading-6 no-underline hover:text-primary" href="">AGB</a>
</div>
</div>
<hr class="mb-4">
<form action="" method="">
<input class="my-1 rounded-md px-2 py-1 ring-1 w-full" id="user" name="user" type="email" placeholder="e-mail" />
<input class="my-1 rounded-md px-2 py-1 ring-1 w-full" id="password" name="password" type="password" placeholder="password" />
<button class="my-1 rounded-md px-2 py-1 ring-1 w-full bg-secondary text-white font-bold hover:bg-primary">einloggen</button>
</form>
<div class="grid grid-cols-[1fr,1fr]">
<a class="justify-self-start text-sm font-bold no-underline hover:text-primary" href="">Registrieren</a>
<a class="justify-self-end text-sm font-bold no-underline hover:text-primary" href="">Passwort vergessen</a>
</div>
<div>
</div>
</div>
</div>
<style lang="scss">
</style>

1
src/env.d.ts vendored
View File

@@ -1,3 +1,4 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />
/// <reference path="../.astro-i18n/generated.d.ts" />

View File

@@ -1,6 +1,7 @@
---
import i18next from "i18next";
import "../style/UMBE_global.css";
import "../style/global.scss";
import "../../svelte-dialogs.config"
import Footer from "../components/Footer.astro";

View File

@@ -1,4 +1,4 @@
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { Enums } from "@ibcornelsen/database/client";
import moment from "moment";

View File

@@ -1,11 +1,11 @@
import { appRouter, t } from "@ibcornelsen/api";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "./constants";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "./constants.js";
export const createCaller = function (opts: any) {
// 1. create a caller-function for your router
const createCaller = t.createCallerFactory(appRouter);
const token = Buffer.from(opts.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME).value ?? "", "utf-8").toString("base64");
const token = Buffer.from(opts.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value ?? "", "utf-8").toString("base64");
// 2. create a caller using your `Context`
return createCaller({
authorization: `Bearer ${token}`,

View File

@@ -1,14 +1,17 @@
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { generate } from "@pdfme/generator";
import VerbrauchsausweisWohnen2016Template from "../../lib/pdf/templates/GEG24_Verbrauchsausweis.json";
import { convertAusweisData } from "#lib/AusweisData";
import { variable } from "#lib/pdf/plugins/variables";
import { convertAusweisData } from "#lib/AusweisData.js";
/* -------------------------------- Pdf Tools ------------------------------- */
import { variable } from "#lib/pdf/plugins/variables/index.js";
import { text, image } from "@pdfme/schemas";
import { Schema, Template } from "@pdfme/common";
import { Moment } from "moment";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import moment from "moment";
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen";
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";
export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohnenClient) {
const template = VerbrauchsausweisWohnen2016Template as Template;

View File

@@ -9,25 +9,25 @@
import ZipSearch from "#components/PlzSuche.svelte";
import moment from "moment";
import BilderZusatzsysteme from "#components/Ausweis/BilderZusatzsysteme.svelte";
import { RawNotificationWrapper, RawNotification, notifications } from "@ibcornelsen/ui";
import { auditHeizungGebaeudeBaujahr } from "#components/Verbrauchsausweis/audits/HeizungGebaeudeBaujahr";
import { auditHeizungJuengerDreiJahre } from "#components/Verbrauchsausweis/audits/HeizungJuengerDreiJahre";
import { auditZeitraumAktuell } from "#components/Verbrauchsausweis/audits/ZeitraumAktuell";
import { auditKlimaFaktoren } from "#components/Verbrauchsausweis/audits/KlimaFaktoren";
import { auditWohnFlaeche } from "#components/Verbrauchsausweis/audits/WohnFlaeche";
import { auditWarmWasser } from "#components/Verbrauchsausweis/audits/WarmWasser";
import { auditLeerStand } from "#components/Verbrauchsausweis/audits/LeerStand";
import { auditPlzNichtErkannt } from "#components/Verbrauchsausweis/audits/PlzNichtErkannt";
import { AuditType, hidden } from "#components/Verbrauchsausweis/audits/hidden";
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt";
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung";
import { auditEndEnergie } from "#components/Verbrauchsausweis/audits/EndEnergie";
import { auditWohnflaecheGroesserGesamtflaeche } from "#components/Verbrauchsausweis/audits/WohnflaecheGroesserGesamtflaeche";
import { RawNotificationWrapper, RawNotification, notifications } from "#components/Notifications/index.js";
import { auditHeizungGebaeudeBaujahr } from "#components/Verbrauchsausweis/audits/HeizungGebaeudeBaujahr.js";
import { auditHeizungJuengerDreiJahre } from "#components/Verbrauchsausweis/audits/HeizungJuengerDreiJahre.js";
import { auditZeitraumAktuell } from "#components/Verbrauchsausweis/audits/ZeitraumAktuell.js";
import { auditKlimaFaktoren } from "#components/Verbrauchsausweis/audits/KlimaFaktoren.js";
import { auditWohnFlaeche } from "#components/Verbrauchsausweis/audits/WohnFlaeche.js";
import { auditWarmWasser } from "#components/Verbrauchsausweis/audits/WarmWasser.js";
import { auditLeerStand } from "#components/Verbrauchsausweis/audits/LeerStand.js";
import { auditPlzNichtErkannt } from "#components/Verbrauchsausweis/audits/PlzNichtErkannt.js";
import { AuditType, hidden } from "#components/Verbrauchsausweis/audits/hidden.js";
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt.js";
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung.js";
import { auditEndEnergie } from "#components/Verbrauchsausweis/audits/EndEnergie.js";
import { auditWohnflaecheGroesserGesamtflaeche } from "#components/Verbrauchsausweis/audits/WohnflaecheGroesserGesamtflaeche.js";
import { Enums } from "@ibcornelsen/database/client"
import Overlay from "#components/Overlay.svelte";
import AusweisGespeichertModule from "./AusweisGespeichertModule.svelte";
import { VerbrauchsausweisWohnenClient, BenutzerClient, UploadedGebaeudeBild } from "#components/Ausweis/types";
import { verbrauchsausweisWohnenSpeichern } from "src/client/lib/verbrauchsausweisWohnenSpeichern";
import { VerbrauchsausweisWohnenClient, BenutzerClient, UploadedGebaeudeBild } from "#components/Ausweis/types.js";
import { verbrauchsausweisWohnenSpeichern } from "src/client/lib/verbrauchsausweisWohnenSpeichern.js";
// TODO: Vom Server sollte ein volles Objekt kommen, dass alle Subobjekte enthält, weil es sonst zu Problemen führen kann
// wenn gebaeude_aufnahme_allgemein oder gebaeude_stammdaten nicht existiert...

View File

@@ -12,7 +12,7 @@ if (!accessTokenValid) {
const caller = createCaller(Astro);
const user = await caller.v1.benutzer.self();
const user = await caller.v1.benutzer.self(undefined);
const gebaeudeArray = await caller.v1.gebaeude.getMany({ limit: 5 });
---

View File

@@ -10,7 +10,7 @@ if (base64) {
const json = buffer.toString("utf-8");
ausweis = JSON.parse(json) as VerbrauchsausweisWohnenClient;
} else {
const uidAusweis = Astro.url.searchParams.get("ausweis_uid");
const uidAusweis = Astro.url.searchParams.get("uid");
if (!uidAusweis) {
return Astro.redirect("/404");

View File

@@ -14,7 +14,7 @@ if (base64) {
const json = buffer.toString("utf-8");
ausweis = JSON.parse(json) as VerbrauchsausweisWohnenClient;
} else {
const uidAusweis = Astro.url.searchParams.get("ausweis_uid");
const uidAusweis = Astro.url.searchParams.get("uid");
if (!uidAusweis) {
return Astro.redirect("/404");

View File

@@ -1,12 +1,12 @@
import { createCaller } from "#lib/caller";
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME, API_UID_COOKIE_NAME } from "#lib/constants";
import { createCaller } from "#lib/caller.js";
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME, API_UID_COOKIE_NAME } from "#lib/constants.js";
import type { AstroGlobal } from "astro";
import moment from "moment";
export async function validateAccessTokenServer(astro: AstroGlobal) {
const accessToken = astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME).value;
const refreshToken = astro.cookies.get(API_REFRESH_TOKEN_COOKIE_NAME).value;
const accessToken = astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value;
const refreshToken = astro.cookies.get(API_REFRESH_TOKEN_COOKIE_NAME)?.value;
if (!refreshToken) {
// Wir haben keinen Refresh Token, also müssen wir uns neu anmelden.

View File

@@ -2,9 +2,9 @@
"compilerOptions": {
// Enable top-level await, and other modern ESM features
"target": "ESNext",
"module": "ESNext",
"module": "NodeNext",
// Enable node-style module resolution, for things like npm package imports
"moduleResolution": "node",
"moduleResolution": "NodeNext",
// Enable JSON imports
"resolveJsonModule": true,
// Enable stricter transpilation for better output
@@ -28,6 +28,6 @@
"#client/*": ["./src/client/*"],
"#server/*": ["./src/server/*"],
},
"types": ["cypress", "cypress-file-upload", "bun-types"]
"types": ["cypress", "cypress-file-upload", "bun-types", "svelte"]
}
}