Automatische Tests und Passwort Vergessen

This commit is contained in:
Moritz Utcke
2025-02-04 10:00:18 +07:00
parent 22cbe52935
commit 9d5867839b
50 changed files with 785 additions and 405 deletions

View File

@@ -18,7 +18,7 @@
"@trpc/client": "^10.45.2", "@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2", "@trpc/server": "^10.45.2",
"astro": "^4.16.17", "astro": "^4.16.17",
"astro-typesafe-api": "^0.2.0", "astro-typesafe-api": "^0.2.1",
"body-scroll-lock": "^4.0.0-beta.0", "body-scroll-lock": "^4.0.0-beta.0",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"bun": "^1.1.45", "bun": "^1.1.45",
@@ -33,6 +33,7 @@
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-timezone": "^0.5.46", "moment-timezone": "^0.5.46",
"nodemailer": "^6.10.0",
"pdf-lib": "^1.17.1", "pdf-lib": "^1.17.1",
"postcss-nested": "^7.0.2", "postcss-nested": "^7.0.2",
"radix-svelte-icons": "^1.0.0", "radix-svelte-icons": "^1.0.0",
@@ -56,6 +57,7 @@
"@types/is-base64": "^1.1.3", "@types/is-base64": "^1.1.3",
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/jsonwebtoken": "^9.0.7", "@types/jsonwebtoken": "^9.0.7",
"@types/nodemailer": "^6.4.17",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0", "@typescript-eslint/parser": "^5.62.0",
@@ -477,6 +479,8 @@
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.1", "", {}, "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg=="], "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.1", "", {}, "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg=="],
"@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="],
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@2.5.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.3", "svelte-hmr": "^0.15.3", "vitefu": "^0.2.4" }, "peerDependencies": { "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w=="], "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@2.5.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.3", "svelte-hmr": "^0.15.3", "vitefu": "^0.2.4" }, "peerDependencies": { "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w=="],
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@1.0.4", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^2.2.0", "svelte": "^3.54.0 || ^4.0.0", "vite": "^4.0.0" } }, "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ=="], "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@1.0.4", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^2.2.0", "svelte": "^3.54.0 || ^4.0.0", "vite": "^4.0.0" } }, "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ=="],
@@ -545,6 +549,8 @@
"@types/node": ["@types/node@22.13.0", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA=="], "@types/node": ["@types/node@22.13.0", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA=="],
"@types/nodemailer": ["@types/nodemailer@6.4.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww=="],
"@types/pug": ["@types/pug@2.0.10", "", {}, "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA=="], "@types/pug": ["@types/pug@2.0.10", "", {}, "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA=="],
"@types/qs": ["@types/qs@6.9.18", "", {}, "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA=="], "@types/qs": ["@types/qs@6.9.18", "", {}, "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA=="],
@@ -651,7 +657,7 @@
"astro": ["astro@4.16.18", "", { "dependencies": { "@astrojs/compiler": "^2.10.3", "@astrojs/internal-helpers": "0.4.1", "@astrojs/markdown-remark": "5.3.0", "@astrojs/telemetry": "3.1.0", "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx": "^7.25.9", "@babel/types": "^7.26.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.3", "@types/babel__core": "^7.20.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.1.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^0.7.2", "cssesc": "^3.0.0", "debug": "^4.3.7", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.5.4", "esbuild": "^0.21.5", "estree-walker": "^3.0.3", "fast-glob": "^3.3.2", "flattie": "^1.1.1", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "html-escaper": "^3.0.3", "http-cache-semantics": "^4.1.1", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.14", "magicast": "^0.3.5", "micromatch": "^4.0.8", "mrmime": "^2.0.0", "neotraverse": "^0.6.18", "ora": "^8.1.1", "p-limit": "^6.1.0", "p-queue": "^8.0.1", "preferred-pm": "^4.0.0", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.6.3", "shiki": "^1.23.1", "tinyexec": "^0.3.1", "tsconfck": "^3.1.4", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", "vite": "^5.4.11", "vitefu": "^1.0.4", "which-pm": "^3.0.0", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "zod": "^3.23.8", "zod-to-json-schema": "^3.23.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-G7zfwJt9BDHEZwlaLNvjbInIw2hPryyD654314KV/XT34pJU6SfN1S+mWa8RAkALcZNJnJXCJmT3JXLQStD3Lw=="], "astro": ["astro@4.16.18", "", { "dependencies": { "@astrojs/compiler": "^2.10.3", "@astrojs/internal-helpers": "0.4.1", "@astrojs/markdown-remark": "5.3.0", "@astrojs/telemetry": "3.1.0", "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx": "^7.25.9", "@babel/types": "^7.26.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.3", "@types/babel__core": "^7.20.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.1.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^0.7.2", "cssesc": "^3.0.0", "debug": "^4.3.7", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.5.4", "esbuild": "^0.21.5", "estree-walker": "^3.0.3", "fast-glob": "^3.3.2", "flattie": "^1.1.1", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "html-escaper": "^3.0.3", "http-cache-semantics": "^4.1.1", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.14", "magicast": "^0.3.5", "micromatch": "^4.0.8", "mrmime": "^2.0.0", "neotraverse": "^0.6.18", "ora": "^8.1.1", "p-limit": "^6.1.0", "p-queue": "^8.0.1", "preferred-pm": "^4.0.0", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.6.3", "shiki": "^1.23.1", "tinyexec": "^0.3.1", "tsconfck": "^3.1.4", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", "vite": "^5.4.11", "vitefu": "^1.0.4", "which-pm": "^3.0.0", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "zod": "^3.23.8", "zod-to-json-schema": "^3.23.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-G7zfwJt9BDHEZwlaLNvjbInIw2hPryyD654314KV/XT34pJU6SfN1S+mWa8RAkALcZNJnJXCJmT3JXLQStD3Lw=="],
"astro-typesafe-api": ["astro-typesafe-api@0.2.0", "", { "peerDependencies": { "astro": "^4.16.17", "typescript": "^5.0.0", "zod": "^3.24.1" }, "bin": { "astro-typesafe-api": "src/cli.ts" } }, "sha512-KCQZyfJ2+Mw7RJS9ThY13MyOTrfUHpfpcKt7qTA0BsvJB2JgxK0x+3YfurBJF+X7tsVVACmo+0QaHS/+xJuIcg=="], "astro-typesafe-api": ["astro-typesafe-api@0.2.1", "", { "dependencies": { "es-codec": "^0.5.0", "globby": "^14.0.2" }, "peerDependencies": { "astro": "^4.16.17", "typescript": "^5.0.0", "zod": "^3.24.1" }, "bin": { "astro-typesafe-api": "src/cli.ts" } }, "sha512-8f0McZj9fWIzT19njJ2z/1zETnbper3ejuba93t72Xvsy6aMTEDXaIGDG3xc9KWUQ9zEcNg+VS52JNWGfYm6CQ=="],
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
@@ -947,6 +953,8 @@
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"es-codec": ["es-codec@0.5.0", "", {}, "sha512-iWbSEF1McYXr++XWCQypRx8hjs887Zlka/x2BVFYp4Li3PJJucTzixoYtY2SNyZRVVPO4aQ10w6wz2rI8noiRg=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
@@ -1129,7 +1137,7 @@
"globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="],
"globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], "globby": ["globby@14.0.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", "ignore": "^5.2.4", "path-type": "^5.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.1.0" } }, "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
@@ -1575,6 +1583,8 @@
"node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="], "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="],
"nodemailer": ["nodemailer@6.10.0", "", {}, "sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA=="],
"nopt": ["nopt@5.0.0", "", { "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ=="], "nopt": ["nopt@5.0.0", "", { "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
@@ -1651,7 +1661,7 @@
"path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="], "path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="],
"path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], "path-type": ["path-type@5.0.0", "", {}, "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg=="],
"path2d": ["path2d@0.1.1", "", {}, "sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA=="], "path2d": ["path2d@0.1.1", "", {}, "sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA=="],
@@ -1967,7 +1977,7 @@
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
"slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="],
"slice-ansi": ["slice-ansi@3.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="], "slice-ansi": ["slice-ansi@3.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="],
@@ -2119,6 +2129,8 @@
"unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="], "unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="],
"unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="],
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="], "unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
@@ -2265,6 +2277,8 @@
"@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@typescript-eslint/typescript-estree/globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="],
"@typescript-eslint/utils/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="], "@typescript-eslint/utils/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
"ahooks/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "ahooks/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
@@ -2299,6 +2313,8 @@
"d3-dsv/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], "d3-dsv/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
"dir-glob/path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
"eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@2.1.0", "", {}, "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="], "eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@2.1.0", "", {}, "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="],
"express/cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="], "express/cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="],
@@ -2435,6 +2451,8 @@
"@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
"@typescript-eslint/typescript-estree/globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@typescript-eslint/utils/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], "@typescript-eslint/utils/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],

View File

@@ -32,7 +32,7 @@
"@trpc/client": "^10.45.2", "@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2", "@trpc/server": "^10.45.2",
"astro": "^4.16.17", "astro": "^4.16.17",
"astro-typesafe-api": "^0.2.0", "astro-typesafe-api": "^0.2.1",
"body-scroll-lock": "^4.0.0-beta.0", "body-scroll-lock": "^4.0.0-beta.0",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"bun": "^1.1.45", "bun": "^1.1.45",
@@ -47,6 +47,7 @@
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-timezone": "^0.5.46", "moment-timezone": "^0.5.46",
"nodemailer": "^6.10.0",
"pdf-lib": "^1.17.1", "pdf-lib": "^1.17.1",
"postcss-nested": "^7.0.2", "postcss-nested": "^7.0.2",
"radix-svelte-icons": "^1.0.0", "radix-svelte-icons": "^1.0.0",
@@ -70,6 +71,7 @@
"@types/is-base64": "^1.1.3", "@types/is-base64": "^1.1.3",
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/jsonwebtoken": "^9.0.7", "@types/jsonwebtoken": "^9.0.7",
"@types/nodemailer": "^6.4.17",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0", "@typescript-eslint/parser": "^5.62.0",

View File

@@ -5,9 +5,10 @@ export const createCaller = createCallerFactory({
"postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"), "postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"),
"aufnahme/[uid]": await import("../src/pages/api/aufnahme/[uid].ts"), "aufnahme/[uid]": await import("../src/pages/api/aufnahme/[uid].ts"),
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"), "aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
"bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"), "bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"),
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
"auth/forgot-password": await import("../src/pages/api/auth/forgot-password.ts"),
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
"bilder/[uid]": await import("../src/pages/api/bilder/[uid].ts"), "bilder/[uid]": await import("../src/pages/api/bilder/[uid].ts"),
"objekt": await import("../src/pages/api/objekt/index.ts"), "objekt": await import("../src/pages/api/objekt/index.ts"),
"ticket": await import("../src/pages/api/ticket/index.ts"), "ticket": await import("../src/pages/api/ticket/index.ts"),

View File

@@ -1,7 +1,8 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import { BenutzerClient } from "./types.js";
export let user: BenutzerClient; export let user: BenutzerClient;

View File

@@ -9,13 +9,13 @@
} from "@ibcornelsen/database/client"; } from "@ibcornelsen/database/client";
import { import {
GebaeudeClient, ObjektClient,
UploadedGebaeudeBild, UploadedGebaeudeBild,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
export let ausweis: VerbrauchsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient;
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let images: UploadedGebaeudeBild[] = []; export let images: UploadedGebaeudeBild[] = [];
</script> </script>

View File

@@ -10,18 +10,18 @@
import { Enums } from "@ibcornelsen/database/client"; import { Enums } from "@ibcornelsen/database/client";
import { import {
BedarfsausweisWohnenClient, BedarfsausweisWohnenClient,
GebaeudeAufnahmeClient, AufnahmeClient,
GebaeudeClient, ObjektClient,
VerbrauchsausweisGewerbeClient, VerbrauchsausweisGewerbeClient,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
export let objekt: GebaeudeClient; export let objekt: ObjektClient;
export let ausweis: export let ausweis:
| VerbrauchsausweisWohnenClient | VerbrauchsausweisWohnenClient
| VerbrauchsausweisGewerbeClient | VerbrauchsausweisGewerbeClient
| BedarfsausweisWohnenClient; | BedarfsausweisWohnenClient;
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
export let ausweisart: Enums.Ausweisart; export let ausweisart: Enums.Ausweisart;
</script> </script>

View File

@@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import ZipSearch from "#components/PlzSuche.svelte"; import ZipSearch from "#components/PlzSuche.svelte";
import { Enums } from "@ibcornelsen/database/client"; import { Bezahlmethoden, Enums } from "@ibcornelsen/database/client";
import PaymentOption from "#components/PaymentOption.svelte"; import PaymentOption from "#components/PaymentOption.svelte";
export let selectedPaymentType: Bezahlmethoden = export let selectedPaymentType: Bezahlmethoden =

View File

@@ -10,16 +10,16 @@
//import Label from "../Label.svelte"; //import Label from "../Label.svelte";
import { import {
GebaeudeAufnahmeClient, AufnahmeClient,
GebaeudeClient, ObjektClient,
UploadedGebaeudeBild, UploadedGebaeudeBild,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
import { boolean } from "astro:schema"; import { boolean } from "astro:schema";
import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte"; import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte";
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
export let ausweis: VerbrauchsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient;
export let images: UploadedGebaeudeBild[]; export let images: UploadedGebaeudeBild[];
</script> </script>
@@ -35,21 +35,92 @@ md:grid-cols-2 md:gap-x-6 md:gap-y-8
xl:grid-cols-2 xl:gap-x-8 xl:gap-y-8 xl:grid-cols-2 xl:gap-x-8 xl:gap-y-8
2xl:grid-cols-3 2xl:gap-x-8 2xl:gap-y-2 2xl:grid-cols-3 2xl:gap-x-8 2xl:gap-y-2
"> "
>
<SanierungsOption label="Zentral/Etage" name="zentralheizung" help="Bitte anklicken wenn die Heizwärme <b>zentral erzeugt</b> und von dort in die Räume verteilt wird. Gasthermen und Etagenheizungen in der Wohnung gehören auch dazu." value="ZH" bind:checked={aufnahme.zentralheizung}></SanierungsOption> <SanierungsOption
<SanierungsOption label="Einzelofen" name="einzelofen" help="Bei <b>dezentraler Erzeugung</b> in den Räumen wie z.B. Nachtspeicher, Kami- oder Kachelofen. Dezentrale Klimageräte zur Wärmeerzeugung gehören auch dazu." value="EO" bind:checked={aufnahme.einzelofen}></SanierungsOption> label="Zentral/Etage"
<SanierungsOption label="Durchlauferhitzer (elektrisch)" name="durchlauf_erhitzer" help="Wenn <b>dezentrale</b> elektrische <b>Warmwassererzeugung</b> vorhanden ist" value="DH" bind:checked={aufnahme.durchlauf_erhitzer}></SanierungsOption> name="zentralheizung"
<SanierungsOption label="Standardkessel" name="standard_kessel" help="Gemeint sind Konstanttemperaturkessel und ältere Gebläse- oder Feststoffkessel" value="SK" bind:checked={aufnahme.standard_kessel}></SanierungsOption> help="Bitte anklicken wenn die Heizwärme <b>zentral erzeugt</b> und von dort in die Räume verteilt wird. Gasthermen und Etagenheizungen in der Wohnung gehören auch dazu."
<SanierungsOption label="Solarsystem für Warmwasser" name="solarsystem_warmwasser" help="Solarpanele auf dem Dach zur <b>alternativen Warmwassererzeugung</b> aus Sonnenenergie. Nicht zu verwechseln mit Photovoltaik." value="SSWW" bind:checked={aufnahme.solarsystem_warmwasser}></SanierungsOption> value="ZH"
<SanierungsOption label="Wärmepumpe" name="waermepumpe" help="Elektrisch betriebener Wärmerzeuger der thermische Energie aus natürlichen Wärmequellen wie der <b>Umgebungsluft, dem Erdreich oder Grundwasser</b> nutzbar macht." value="WP" bind:checked={aufnahme.waermepumpe}></SanierungsOption> bind:checked={aufnahme.zentralheizung}
<SanierungsOption label="Niedertemperaturkessel" name="niedertemperatur_kessel" help="Heizkessel der mit <b>niedrigen Vorlauftemperaturen</b> (35-75 °C) arbeitet. Im Vergleich zum Brennwertkessel ist er weniger effizient, wird aber noch in älteren Heizsystemen eingesetzt." value="NK" bind:checked={aufnahme.niedertemperatur_kessel}></SanierungsOption> ></SanierungsOption>
<SanierungsOption label="Brennwertkessel" name="brennwert_kessel" help="Hat einen besonders <b>hohen Wirkungsgrad</b> weil er die im Abgas enthaltene Kondensationswärme zurückgewinnt. Auch zu erkennen am doppelwandigem Abgasrohr welches sich nicht erhitzt." value="BWK" bind:checked={aufnahme.brennwert_kessel}></SanierungsOption> <SanierungsOption
<SanierungsOption label="Warmwasserrohre gedämmt" name="warmwasser_rohre_gedaemmt" help="Gemeint sind die sichtbaren Rohre des Verteilsystems Warmwasser. Gedämmte Rohre sind an den <b>dunklen Ummantelungen</b> (Manschetten) zu erkennen." value="BWK" bind:checked={aufnahme.warmwasser_rohre_gedaemmt}></SanierungsOption> label="Einzelofen"
<SanierungsOption label="Heizungsrohre gedämmt" name="heizungsrohre_gedaemmt" help="Gemeint sind die sichtbaren Rohre des Verteilsystems Heizung. Gedämmte Rohre sind an den <b>dunklen Ummantelungen</b> (Manschetten) zu erkennen.ext" value="HRGD" bind:checked={aufnahme.heizungsrohre_gedaemmt}></SanierungsOption> name="einzelofen"
<SanierungsOption label="Zirkulation" name="zirkulation" help="Kreislauf von Heizungs- oder Warmwasser <b>innerhalb eines Leitungssystems</b>, um eine gleichmäßige Wärmeverteilung sicherzustellen." value="ZK" bind:checked={aufnahme.zirkulation}></SanierungsOption> help="Bei <b>dezentraler Erzeugung</b> in den Räumen wie z.B. Nachtspeicher, Kami- oder Kachelofen. Dezentrale Klimageräte zur Wärmeerzeugung gehören auch dazu."
<SanierungsOption label="Photovoltaik auf dem Dach" name="photovoltaik" help="Direkte Umwandlung von Sonnenlicht in <b>elektrische Energie</b> mittels Solarzellen, die den photoelektrischen Effekt nutzen." value="PV" bind:checked={aufnahme.photovotaik}></SanierungsOption> value="EO"
bind:checked={aufnahme.einzelofen}
></SanierungsOption>
<SanierungsOption
label="Durchlauferhitzer (elektrisch)"
name="durchlauf_erhitzer"
help="Wenn <b>dezentrale</b> elektrische <b>Warmwassererzeugung</b> vorhanden ist"
value="DH"
bind:checked={aufnahme.durchlauf_erhitzer}
></SanierungsOption>
<SanierungsOption
label="Standardkessel"
name="standard_kessel"
help="Gemeint sind Konstanttemperaturkessel und ältere Gebläse- oder Feststoffkessel"
value="SK"
bind:checked={aufnahme.standard_kessel}
></SanierungsOption>
<SanierungsOption
label="Solarsystem für Warmwasser"
name="solarsystem_warmwasser"
help="Solarpanele auf dem Dach zur <b>alternativen Warmwassererzeugung</b> aus Sonnenenergie. Nicht zu verwechseln mit Photovoltaik."
value="SSWW"
bind:checked={aufnahme.solarsystem_warmwasser}
></SanierungsOption>
<SanierungsOption
label="Wärmepumpe"
name="waermepumpe"
help="Elektrisch betriebener Wärmerzeuger der thermische Energie aus natürlichen Wärmequellen wie der <b>Umgebungsluft, dem Erdreich oder Grundwasser</b> nutzbar macht."
value="WP"
bind:checked={aufnahme.waermepumpe}
></SanierungsOption>
<SanierungsOption
label="Niedertemperaturkessel"
name="niedertemperatur_kessel"
help="Heizkessel der mit <b>niedrigen Vorlauftemperaturen</b> (35-75 °C) arbeitet. Im Vergleich zum Brennwertkessel ist er weniger effizient, wird aber noch in älteren Heizsystemen eingesetzt."
value="NK"
bind:checked={aufnahme.niedertemperatur_kessel}
></SanierungsOption>
<SanierungsOption
label="Brennwertkessel"
name="brennwert_kessel"
help="Hat einen besonders <b>hohen Wirkungsgrad</b> weil er die im Abgas enthaltene Kondensationswärme zurückgewinnt. Auch zu erkennen am doppelwandigem Abgasrohr welches sich nicht erhitzt."
value="BWK"
bind:checked={aufnahme.brennwert_kessel}
></SanierungsOption>
<SanierungsOption
label="Warmwasserrohre gedämmt"
name="warmwasser_rohre_gedaemmt"
help="Gemeint sind die sichtbaren Rohre des Verteilsystems Warmwasser. Gedämmte Rohre sind an den <b>dunklen Ummantelungen</b> (Manschetten) zu erkennen."
value="BWK"
bind:checked={aufnahme.warmwasser_rohre_gedaemmt}
></SanierungsOption>
<SanierungsOption
label="Heizungsrohre gedämmt"
name="heizungsrohre_gedaemmt"
help="Gemeint sind die sichtbaren Rohre des Verteilsystems Heizung. Gedämmte Rohre sind an den <b>dunklen Ummantelungen</b> (Manschetten) zu erkennen.ext"
value="HRGD"
bind:checked={aufnahme.heizungsrohre_gedaemmt}
></SanierungsOption>
<SanierungsOption
label="Zirkulation"
name="zirkulation"
help="Kreislauf von Heizungs- oder Warmwasser <b>innerhalb eines Leitungssystems</b>, um eine gleichmäßige Wärmeverteilung sicherzustellen."
value="ZK"
bind:checked={aufnahme.zirkulation}
></SanierungsOption>
<SanierungsOption
label="Photovoltaik auf dem Dach"
name="photovoltaik"
help="Direkte Umwandlung von Sonnenlicht in <b>elektrische Energie</b> mittels Solarzellen, die den photoelektrischen Effekt nutzen."
value="PV"
bind:checked={aufnahme.photovoltaik}
></SanierungsOption>
</div> </div>
<HeizungImage bind:images bind:ausweis bind:gebaeude /> <HeizungImage bind:images bind:ausweis bind:gebaeude />

View File

@@ -1,11 +1,11 @@
<script lang="ts"> <script lang="ts">
import ImageGrid from "../ImageGrid.svelte";; import ImageGrid from "../ImageGrid.svelte";;
import { Enums, type BedarfsausweisWohnen, type VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client"; import { Enums, type BedarfsausweisWohnen, type VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./types.js"; import { ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./types.js";
export let images: UploadedGebaeudeBild[] = []; export let images: UploadedGebaeudeBild[] = [];
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
</script> </script>
<div class="grid grid-cols-2 gap-x-6 mt-6"> <div class="grid grid-cols-2 gap-x-6 mt-6">

View File

@@ -1,11 +1,11 @@
<script lang="ts"> <script lang="ts">
import ImageGrid from "../ImageGrid.svelte";; import ImageGrid from "../ImageGrid.svelte";;
import { Enums, type BedarfsausweisWohnen, type VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client"; import { Enums, type BedarfsausweisWohnen, type VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./types.js"; import { ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./types.js";
export let images: UploadedGebaeudeBild[] = []; export let images: UploadedGebaeudeBild[] = [];
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
</script> </script>
<div class="grid grid-cols-2 gap-x-6 mt-6"> <div class="grid grid-cols-2 gap-x-6 mt-6">

View File

@@ -1,11 +1,11 @@
<script lang="ts"> <script lang="ts">
import ImageGrid from "../ImageGrid.svelte";; import ImageGrid from "../ImageGrid.svelte";;
import { Enums, type BedarfsausweisWohnen, type VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client"; import { Enums, type BedarfsausweisWohnen, type VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./types.js"; import { ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./types.js";
export let images: UploadedGebaeudeBild[] = []; export let images: UploadedGebaeudeBild[] = [];
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
</script> </script>
<div class="grid grid-cols-2 gap-x-6 mt-6"> <div class="grid grid-cols-2 gap-x-6 mt-6">

View File

@@ -2,8 +2,9 @@
import HelpLabel from "#components/labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import { AufnahmeClient } from "./types.js";
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
</script> </script>

View File

@@ -3,16 +3,16 @@
import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte"; import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte";
import { import {
BedarfsausweisWohnenClient, BedarfsausweisWohnenClient,
GebaeudeAufnahmeClient, AufnahmeClient,
GebaeudeClient, ObjektClient,
VerbrauchsausweisGewerbeClient, VerbrauchsausweisGewerbeClient,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte"; import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte";
export let ausweis: VerbrauchsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient;
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
export let objekt: GebaeudeClient; export let objekt: ObjektClient;
let maxPerformance = 250; let maxPerformance = 250;

View File

@@ -1,14 +1,13 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import ZipSearch from "#components/PlzSuche.svelte"; import ZipSearch from "#components/PlzSuche.svelte";
import { BenutzerClient, RechnungClient } from "./types.js";
export let user: BenutzerClient; export let user: BenutzerClient;
let rechnung: inferProcedureInput< let rechnung: RechnungClient = {
AppRouter["v1"]["rechnungen"]["erstellen"]
> = {
email: user.email, email: user.email,
empfaenger: user.vorname + " " + user.name, empfaenger: user.vorname + " " + user.name,
strasse: user.adresse, strasse: user.adresse,

View File

@@ -7,16 +7,16 @@
//import Label from "../Label.svelte"; //import Label from "../Label.svelte";
import { import {
GebaeudeAufnahmeClient, AufnahmeClient,
GebaeudeClient, ObjektClient,
UploadedGebaeudeBild, UploadedGebaeudeBild,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
import { boolean } from "astro:schema"; import { boolean } from "astro:schema";
import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte" import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte"
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
export let ausweis: VerbrauchsausweisWohnenClient export let ausweis: VerbrauchsausweisWohnenClient
export let images: UploadedGebaeudeBild[]; export let images: UploadedGebaeudeBild[];

View File

@@ -1,29 +1,29 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte"; import Inputlabel from "#components/labels/InputLabel.svelte";
import HeizungImage from "./HeizungImage.svelte";
import HeizungImage from "./HeizungImage.svelte";
//import Label from "../Label.svelte";
//import Label from "../Label.svelte";
import {
GebaeudeAufnahmeClient, import {
GebaeudeClient, AufnahmeClient,
UploadedGebaeudeBild, ObjektClient,
VerbrauchsausweisWohnenClient, UploadedGebaeudeBild,
} from "./types.js"; VerbrauchsausweisWohnenClient,
import { boolean } from "astro:schema"; } from "./types.js";
import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte" import { boolean } from "astro:schema";
import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte";
export let gebaeude: GebaeudeClient;
export let aufnahme: GebaeudeAufnahmeClient; export let gebaeude: ObjektClient;
export let ausweis: VerbrauchsausweisWohnenClient export let aufnahme: AufnahmeClient;
export let images: UploadedGebaeudeBild[]; export let ausweis: VerbrauchsausweisWohnenClient;
export let images: UploadedGebaeudeBild[];
</script>
</script>
<div
id="sanierungszustand"
class="bereich-box grid
grid-cols-1 gap-x-4 gap-y-2 grid-cols-1 gap-x-4 gap-y-2
sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8 sm:grid-cols-2 sm:gap-x-6 sm:gap-y-8
@@ -31,29 +31,97 @@
xl:grid-cols-2 xl:gap-x-8 xl:gap-y-8 xl:grid-cols-2 xl:gap-x-8 xl:gap-y-8
2xl:grid-cols-3 2xl:gap-x-8 2xl:gap-y-2 2xl:grid-cols-3 2xl:gap-x-8 2xl:gap-y-2
2xl:grid-cols-3 2xl:gap-x-8 2xl:gap-y-2 "
"> >
<SanierungsOption
<SanierungsOption label="Zentral/Etage" name="zentralheizung" help="Bitte anklicken wenn die Heizwärme <strong>zentral erzeugt</strong> und von dort in die Räume verteilt wird. Gasthermen und Etagenheizungen in der Wohnung gehören auch dazu." value="ZH" bind:checked={aufnahme.zentralheizung}></SanierungsOption> label="Zentral/Etage"
<SanierungsOption label="Einzelofen" name="einzelofen" help="Bei <strong>dezentraler Erzeugung</strong> in den Räumen wie z.B. Nachtspeicher, Kami- oder Kachelofen. Dezentrale Klimageräte zur Wärmeerzeugung gehören auch dazu." value="EO" bind:checked={aufnahme.einzelofen}></SanierungsOption> name="zentralheizung"
<SanierungsOption label="Durchlauferhitzer (elektrisch)" name="durchlauf_erhitzer" help="Wenn <strong>dezentrale</strong> elektrische <strong>Warmwassererzeugung</strong> vorhanden ist" value="DH" bind:checked={aufnahme.durchlauf_erhitzer}></SanierungsOption> help="Bitte anklicken wenn die Heizwärme <strong>zentral erzeugt</strong> und von dort in die Räume verteilt wird. Gasthermen und Etagenheizungen in der Wohnung gehören auch dazu."
<SanierungsOption label="Standardkessel" name="standard_kessel" help="Gemeint sind Konstanttemperaturkessel und ältere Gebläse- oder Feststoffkessel" value="SK" bind:checked={aufnahme.standard_kessel}></SanierungsOption> value="ZH"
<SanierungsOption label="Solarsystem für Warmwasser" name="solarsystem_warmwasser" help="Solarpanele auf dem Dach zur <strong>alternativen Warmwassererzeugung</strong> aus Sonnenenergie. Nicht zu verwechseln mit Photovoltaik." value="SSWW" bind:checked={aufnahme.solarsystem_warmwasser}></SanierungsOption> bind:checked={aufnahme.zentralheizung}
<SanierungsOption label="Wärmepumpe" name="waermepumpe" help="Elektrisch betriebener Wärmerzeuger der thermische Energie aus natürlichen Wärmequellen wie der <strong>Umgebungsluft, dem Erdreich oder Grundwasser</strong> nutzbar macht." value="WP" bind:checked={aufnahme.waermepumpe}></SanierungsOption> ></SanierungsOption>
<SanierungsOption label="Niedertemperaturkessel" name="niedertemperatur_kessel" help="Heizkessel der mit <strong>niedrigen Vorlauftemperaturen</strong> (35-75 °C) arbeitet. Im Vergleich zum Brennwertkessel ist er weniger effizient, wird aber noch in älteren Heizsystemen eingesetzt." value="NK" bind:checked={aufnahme.niedertemperatur_kessel}></SanierungsOption> <SanierungsOption
<SanierungsOption label="Brennwertkessel" name="brennwert_kessel" help="Hat einen besonders <strong>hohen Wirkungsgrad</strong> weil er die im Abgas enthaltene Kondensationswärme zurückgewinnt. Auch zu erkennen am doppelwandigem Abgasrohr welches sich nicht erhitzt." value="BWK" bind:checked={aufnahme.brennwert_kessel}></SanierungsOption> label="Einzelofen"
<SanierungsOption label="Warmwasserrohre gedämmt" name="warmwasser_rohre_gedaemmt" help="Gemeint sind die sichtbaren Rohre des Verteilsystems Warmwasser. Gedämmte Rohre sind an den <strong>dunklen Ummantelungen</strong> (Manschetten) zu erkennen." value="BWK" bind:checked={aufnahme.warmwasser_rohre_gedaemmt}></SanierungsOption> name="einzelofen"
<SanierungsOption label="Heizungsrohre gedämmt" name="heizungsrohre_gedaemmt" help="Gemeint sind die sichtbaren Rohre des Verteilsystems Heizung. Gedämmte Rohre sind an den <strong>dunklen Ummantelungen</strong> (Manschetten) zu erkennen.ext" value="HRGD" bind:checked={aufnahme.heizungsrohre_gedaemmt}></SanierungsOption> help="Bei <strong>dezentraler Erzeugung</strong> in den Räumen wie z.B. Nachtspeicher, Kami- oder Kachelofen. Dezentrale Klimageräte zur Wärmeerzeugung gehören auch dazu."
<SanierungsOption label="Zirkulation" name="zirkulation" help="Kreislauf von Heizungs- oder Warmwasser <strong>innerhalb eines Leitungssystems</strong>, um eine gleichmäßige Wärmeverteilung sicherzustellen." value="ZK" bind:checked={aufnahme.zirkulation}></SanierungsOption> value="EO"
<SanierungsOption label="Photovoltaik auf dem Dach" name="photovoltaik" help="Direkte Umwandlung von Sonnenlicht in <strong>elektrische Energie</strong> mittels Solarzellen, die den photoelektrischen Effekt nutzen." value="PV" bind:checked={aufnahme.photovotaik}></SanierungsOption> bind:checked={aufnahme.einzelofen}
</div> ></SanierungsOption>
<SanierungsOption
<HeizungImage bind:images bind:ausweis bind:gebaeude /> label="Durchlauferhitzer (elektrisch)"
name="durchlauf_erhitzer"
<style lang="postcss"> help="Wenn <strong>dezentrale</strong> elektrische <strong>Warmwassererzeugung</strong> vorhanden ist"
value="DH"
</style> bind:checked={aufnahme.durchlauf_erhitzer}
></SanierungsOption>
<SanierungsOption
label="Standardkessel"
name="standard_kessel"
help="Gemeint sind Konstanttemperaturkessel und ältere Gebläse- oder Feststoffkessel"
value="SK"
bind:checked={aufnahme.standard_kessel}
></SanierungsOption>
<SanierungsOption
label="Solarsystem für Warmwasser"
name="solarsystem_warmwasser"
help="Solarpanele auf dem Dach zur <strong>alternativen Warmwassererzeugung</strong> aus Sonnenenergie. Nicht zu verwechseln mit Photovoltaik."
value="SSWW"
bind:checked={aufnahme.solarsystem_warmwasser}
></SanierungsOption>
<SanierungsOption
label="Wärmepumpe"
name="waermepumpe"
help="Elektrisch betriebener Wärmerzeuger der thermische Energie aus natürlichen Wärmequellen wie der <strong>Umgebungsluft, dem Erdreich oder Grundwasser</strong> nutzbar macht."
value="WP"
bind:checked={aufnahme.waermepumpe}
></SanierungsOption>
<SanierungsOption
label="Niedertemperaturkessel"
name="niedertemperatur_kessel"
help="Heizkessel der mit <strong>niedrigen Vorlauftemperaturen</strong> (35-75 °C) arbeitet. Im Vergleich zum Brennwertkessel ist er weniger effizient, wird aber noch in älteren Heizsystemen eingesetzt."
value="NK"
bind:checked={aufnahme.niedertemperatur_kessel}
></SanierungsOption>
<SanierungsOption
label="Brennwertkessel"
name="brennwert_kessel"
help="Hat einen besonders <strong>hohen Wirkungsgrad</strong> weil er die im Abgas enthaltene Kondensationswärme zurückgewinnt. Auch zu erkennen am doppelwandigem Abgasrohr welches sich nicht erhitzt."
value="BWK"
bind:checked={aufnahme.brennwert_kessel}
></SanierungsOption>
<SanierungsOption
label="Warmwasserrohre gedämmt"
name="warmwasser_rohre_gedaemmt"
help="Gemeint sind die sichtbaren Rohre des Verteilsystems Warmwasser. Gedämmte Rohre sind an den <strong>dunklen Ummantelungen</strong> (Manschetten) zu erkennen."
value="BWK"
bind:checked={aufnahme.warmwasser_rohre_gedaemmt}
></SanierungsOption>
<SanierungsOption
label="Heizungsrohre gedämmt"
name="heizungsrohre_gedaemmt"
help="Gemeint sind die sichtbaren Rohre des Verteilsystems Heizung. Gedämmte Rohre sind an den <strong>dunklen Ummantelungen</strong> (Manschetten) zu erkennen.ext"
value="HRGD"
bind:checked={aufnahme.heizungsrohre_gedaemmt}
></SanierungsOption>
<SanierungsOption
label="Zirkulation"
name="zirkulation"
help="Kreislauf von Heizungs- oder Warmwasser <strong>innerhalb eines Leitungssystems</strong>, um eine gleichmäßige Wärmeverteilung sicherzustellen."
value="ZK"
bind:checked={aufnahme.zirkulation}
></SanierungsOption>
<SanierungsOption
label="Photovoltaik auf dem Dach"
name="photovoltaik"
help="Direkte Umwandlung von Sonnenlicht in <strong>elektrische Energie</strong> mittels Solarzellen, die den photoelektrischen Effekt nutzen."
value="PV"
bind:checked={aufnahme.photovoltaik}
></SanierungsOption>
</div>
<HeizungImage bind:images bind:ausweis bind:gebaeude />
<!--
<div class="GRB3"> <div class="GRB3">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
@@ -151,5 +219,6 @@
<AusweisPreviewContainer bind:images bind:ausweis bind:gebaeude /> <AusweisPreviewContainer bind:images bind:ausweis bind:gebaeude />
--> -->
-->
<style lang="postcss">
</style>

View File

@@ -8,16 +8,16 @@
//import Label from "../Label.svelte"; //import Label from "../Label.svelte";
import { import {
GebaeudeAufnahmeClient, AufnahmeClient,
GebaeudeClient, ObjektClient,
UploadedGebaeudeBild, UploadedGebaeudeBild,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
import { boolean } from "astro:schema"; import { boolean } from "astro:schema";
import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte" import SanierungsOption from "#components/Ausweis/SanierungsOption.svelte"
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
export let ausweis: VerbrauchsausweisWohnenClient export let ausweis: VerbrauchsausweisWohnenClient
export let images: UploadedGebaeudeBild[]; export let images: UploadedGebaeudeBild[];

View File

@@ -14,14 +14,14 @@
import fuelList from "./brennstoffListe.js"; import fuelList from "./brennstoffListe.js";
import { auditVerbrauchAbweichung } from "../Verbrauchsausweis/audits/VerbrauchAbweichung.js"; import { auditVerbrauchAbweichung } from "../Verbrauchsausweis/audits/VerbrauchAbweichung.js";
import { import {
GebaeudeAufnahmeClient, AufnahmeClient,
GebaeudeClient, ObjektClient,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
import { addNotification } from "#components/Notifications/shared.js"; import { addNotification } from "#components/Notifications/shared.js";
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let aufnahme: GebaeudeAufnahmeClient; export let aufnahme: AufnahmeClient;
export let ausweis: VerbrauchsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient;
// Wir dürfen bis zu 4.5 Jahre alte Klimafaktoren benutzen, also nehmen wir alle Monate seitdem und generieren daraus die Auswahl. // Wir dürfen bis zu 4.5 Jahre alte Klimafaktoren benutzen, also nehmen wir alle Monate seitdem und generieren daraus die Auswahl.

View File

@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import UploadImages from "./UploadImages.svelte"; import UploadImages from "./UploadImages.svelte";
import type { BedarfsausweisWohnen, Enums, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client"; import type { BedarfsausweisWohnen, Enums, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js"; import { ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js";
import { RotateCounterClockwise, Trash, Upload } from "radix-svelte-icons"; import { RotateCounterClockwise, Trash, Upload } from "radix-svelte-icons";
export let images: UploadedGebaeudeBild[] = []; export let images: UploadedGebaeudeBild[] = [];
@@ -9,7 +9,7 @@
export let min: number = 1; export let min: number = 1;
export let name: string = ""; export let name: string = "";
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let kategorie: Enums.BilderKategorie export let kategorie: Enums.BilderKategorie
async function rotateImage(image: UploadedGebaeudeBild): Promise<UploadedGebaeudeBild> { async function rotateImage(image: UploadedGebaeudeBild): Promise<UploadedGebaeudeBild> {

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { notifications } from "./shared" import { notifications } from "./shared.js"
export let component: ConstructorOfATypedSvelteComponent; export let component: ConstructorOfATypedSvelteComponent;
</script> </script>

View File

@@ -1,9 +1,9 @@
<script lang="ts"> <script lang="ts">
import { A6BerechnungWaermeTransferMaxStroemeLueftungGesamt } from "#lib/Berechnungen/BedarfsausweisWohnen/A6BerechnungWaermeTransferMaxStroemeLueftungGesamt.js"; import { A6BerechnungWaermeTransferMaxStroemeLueftungGesamt } from "#lib/Berechnungen/BedarfsausweisWohnen/A6BerechnungWaermeTransferMaxStroemeLueftungGesamt.js";
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { BedarfsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types.js";
export let ausweis: BedarfsausweisWohnenClient; export let ausweis: BedarfsausweisWohnenClient;
export let gebaeude_aufnahme: GebaeudeAufnahmeClient; export let gebaeude_aufnahme: AufnahmeClient;
// Berechnete Werte aus A5 // Berechnete Werte aus A5
$: result = A6BerechnungWaermeTransferMaxStroemeLueftungGesamt(); $: result = A6BerechnungWaermeTransferMaxStroemeLueftungGesamt();

View File

@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { BedarfsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types.js";
export let ausweis: BedarfsausweisWohnenClient; export let ausweis: BedarfsausweisWohnenClient;
export let gebaeude_aufnahme: GebaeudeAufnahmeClient; export let gebaeude_aufnahme: AufnahmeClient;
import { A9BerechnungNutzenergiebedarfTrinkwarmwasser } from "#lib/Berechnungen/BedarfsausweisWohnen/A9BerechnungNutzenergiebedarfTrinkwarmwasser.js"; import { A9BerechnungNutzenergiebedarfTrinkwarmwasser } from "#lib/Berechnungen/BedarfsausweisWohnen/A9BerechnungNutzenergiebedarfTrinkwarmwasser.js";

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import HelpLabel from "#labels/HelpLabel.svelte"; import HelpLabel from "#components/labels/HelpLabel.svelte";
import type { BedarfsausweisWohnen, Enums, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client"; import type { BedarfsausweisWohnen, Enums, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
export let max: number = 2; export let max: number = 2;
@@ -7,11 +7,11 @@
export let name: string = "" export let name: string = ""
// Array of base64 encoded images read into the input. // Array of base64 encoded images read into the input.
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js"; import { ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js";
export let images: UploadedGebaeudeBild[] = []; export let images: UploadedGebaeudeBild[] = [];
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
export let gebaeude: GebaeudeClient; export let gebaeude: ObjektClient;
export let kategorie: Enums.BilderKategorie; export let kategorie: Enums.BilderKategorie;
function getAllImages(this: HTMLInputElement) { function getAllImages(this: HTMLInputElement) {

View File

@@ -1,6 +1,6 @@
import { GebaeudeAufnahmeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { AufnahmeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
export function auditBedarfsausweisBenoetigt(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeAufnahmeClient): boolean { export function auditBedarfsausweisBenoetigt(ausweis: VerbrauchsausweisWohnenClient, gebaeude: AufnahmeClient): boolean {
if (ausweis.ausstellgrund == "Neubau" || ausweis.ausstellgrund == "Modernisierung") { if (ausweis.ausstellgrund == "Neubau" || ausweis.ausstellgrund == "Modernisierung") {
return true; return true;
} }

View File

@@ -1,9 +1,9 @@
import { GebaeudeClient, VerbrauchsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { ObjektClient, VerbrauchsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "./hidden.js"; import { AuditType, hidden } from "./hidden.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js"; import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import { getKlimafaktoren } from "#lib/Klimafaktoren.js"; import { getKlimafaktoren } from "#lib/Klimafaktoren.js";
export async function auditEndEnergie(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeClient, aufnahme: GebaeudeAufnahmeClient): Promise<boolean> { export async function auditEndEnergie(ausweis: VerbrauchsausweisWohnenClient, gebaeude: ObjektClient, aufnahme: AufnahmeClient): Promise<boolean> {
if (hidden.has(AuditType.END_ENERGIE)) { if (hidden.has(AuditType.END_ENERGIE)) {
return false; return false;
} }

View File

@@ -1,7 +1,7 @@
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { AufnahmeClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "../audits/hidden.js"; import { AuditType, hidden } from "../audits/hidden.js";
export function auditHeizungGebaeudeBaujahr(gebaeude: GebaeudeAufnahmeClient): boolean { export function auditHeizungGebaeudeBaujahr(gebaeude: AufnahmeClient): boolean {
if ((gebaeude.baujahr_heizung && gebaeude.baujahr_heizung.length > 0) && (gebaeude.baujahr_gebaeude && gebaeude.baujahr_gebaeude.length > 0)) { if ((gebaeude.baujahr_heizung && gebaeude.baujahr_heizung.length > 0) && (gebaeude.baujahr_gebaeude && gebaeude.baujahr_gebaeude.length > 0)) {
return gebaeude.baujahr_heizung[0] > 1500 && return gebaeude.baujahr_heizung[0] > 1500 &&
gebaeude.baujahr_gebaeude[0] > 1500 && gebaeude.baujahr_gebaeude[0] > 1500 &&

View File

@@ -1,7 +1,7 @@
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { AufnahmeClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "../audits/hidden.js"; import { AuditType, hidden } from "../audits/hidden.js";
export function auditHeizungJuengerDreiJahre(gebaeude: GebaeudeAufnahmeClient): boolean { export function auditHeizungJuengerDreiJahre(gebaeude: AufnahmeClient): boolean {
if (gebaeude.baujahr_heizung && gebaeude.baujahr_heizung.length > 0) { if (gebaeude.baujahr_heizung && gebaeude.baujahr_heizung.length > 0) {
if (!hidden.has(AuditType.HEIZUNG_JUENGER_DREI_JAHRE)) { if (!hidden.has(AuditType.HEIZUNG_JUENGER_DREI_JAHRE)) {

View File

@@ -1,8 +1,8 @@
import { GebaeudeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "./hidden.js"; import { AuditType, hidden } from "./hidden.js";
import { getKlimafaktoren } from "#lib/Klimafaktoren.js"; import { getKlimafaktoren } from "#lib/Klimafaktoren.js";
export async function auditKlimaFaktoren(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeClient): Promise<boolean> { export async function auditKlimaFaktoren(ausweis: VerbrauchsausweisWohnenClient, gebaeude: ObjektClient): Promise<boolean> {
if (hidden.has(AuditType.KLIMA_FAKTOREN)) { if (hidden.has(AuditType.KLIMA_FAKTOREN)) {
return false; return false;
} }

View File

@@ -1,7 +1,7 @@
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { AufnahmeClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "./hidden.js"; import { AuditType, hidden } from "./hidden.js";
export function auditLeerStand(gebaeude: GebaeudeAufnahmeClient): boolean { export function auditLeerStand(gebaeude: AufnahmeClient): boolean {
if (gebaeude.leerstand && !hidden.has(AuditType.LEER_STAND)) { if (gebaeude.leerstand && !hidden.has(AuditType.LEER_STAND)) {
return ( return (
(gebaeude.leerstand > 30) (gebaeude.leerstand > 30)

View File

@@ -1,10 +1,10 @@
import { GebaeudeClient } from "#components/Ausweis/types.js"; import { ObjektClient } from "#components/Ausweis/types.js";
import { memoize } from "src/lib/Memoization.js"; import { memoize } from "src/lib/Memoization.js";
import { AuditType, hidden } from "../audits/hidden.js"; import { AuditType, hidden } from "../audits/hidden.js";
import { api } from "astro-typesafe-api/client"; import { api } from "astro-typesafe-api/client";
export const auditPlzNichtErkannt = memoize( export const auditPlzNichtErkannt = memoize(
async (gebaeude: GebaeudeClient) => { async (gebaeude: ObjektClient) => {
if (gebaeude.plz) { if (gebaeude.plz) {
if (gebaeude.plz.length == 5) { if (gebaeude.plz.length == 5) {
try { try {

View File

@@ -1,7 +1,7 @@
import { GebaeudeAufnahmeClient, GebaeudeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { AufnahmeClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "./hidden.js"; import { AuditType, hidden } from "./hidden.js";
export function auditVerbrauchAbweichung(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeAufnahmeClient): number[] { export function auditVerbrauchAbweichung(ausweis: VerbrauchsausweisWohnenClient, gebaeude: AufnahmeClient): number[] {
if (gebaeude.leerstand && (gebaeude.leerstand > 0)) { if (gebaeude.leerstand && (gebaeude.leerstand > 0)) {
return []; return [];
} }

View File

@@ -1,7 +1,7 @@
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { AufnahmeClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "./hidden.js"; import { AuditType, hidden } from "./hidden.js";
export function auditWohnFlaeche(gebaeude: GebaeudeAufnahmeClient ): boolean { export function auditWohnFlaeche(gebaeude: AufnahmeClient ): boolean {
if (gebaeude.einheiten && gebaeude.flaeche ) { if (gebaeude.einheiten && gebaeude.flaeche ) {
if (!hidden.has(AuditType.WOHN_FLAECHE)){ if (!hidden.has(AuditType.WOHN_FLAECHE)){
return ( return (

View File

@@ -1,7 +1,7 @@
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { AufnahmeClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "../audits/hidden.js"; import { AuditType, hidden } from "../audits/hidden.js";
export function auditWohnflaecheGroesserGesamtflaeche(gebaeude: GebaeudeAufnahmeClient ): boolean { export function auditWohnflaecheGroesserGesamtflaeche(gebaeude: AufnahmeClient ): boolean {
if (gebaeude.flaeche && gebaeude.nutzflaeche){ if (gebaeude.flaeche && gebaeude.nutzflaeche){
return (gebaeude.flaeche > gebaeude.nutzflaeche && !hidden.has(AuditType.WOHNFLAECHE_GROESSER_GESAMTFLAECHE)); return (gebaeude.flaeche > gebaeude.nutzflaeche && !hidden.has(AuditType.WOHNFLAECHE_GROESSER_GESAMTFLAECHE));
} }

View File

@@ -1,7 +1,7 @@
import { GebaeudeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { AuditType, hidden } from "./hidden.js"; import { AuditType, hidden } from "./hidden.js";
export function auditZeitraumAktuell(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeClient): boolean { export function auditZeitraumAktuell(ausweis: VerbrauchsausweisWohnenClient, gebaeude: ObjektClient): boolean {
if (hidden.has(AuditType.ZEITRAUM_AKTUELL)) { if (hidden.has(AuditType.ZEITRAUM_AKTUELL)) {
return false; return false;
} }

View File

@@ -2,14 +2,14 @@ import fuelList from "#components/Ausweis/brennstoffListe.js";
import { faker } from "@faker-js/faker"; import { faker } from "@faker-js/faker";
import { Enums } from "@ibcornelsen/database/client"; import { Enums } from "@ibcornelsen/database/client";
console.log(Enums);
import "cypress-file-upload" import "cypress-file-upload"
describe("Verbrauchsausweis erstellen Schritt 1", () => { describe("Verbrauchsausweis erstellen Schritt 1", () => {
it("erstellt einen neuen Verbrauchsausweis Wohngebäude.", () => { it("erstellt einen neuen Verbrauchsausweis Wohngebäude.", () => {
cy.visit("/energieausweis-erstellen/verbrauchsausweis-wohngebaeude"); cy.visit("/energieausweis-erstellen/verbrauchsausweis-wohngebaeude");
console.log(Enums);
// cy.wait(1000); // cy.wait(1000);

View File

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

View File

@@ -0,0 +1,31 @@
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import {faker} from "@faker-js/faker";
describe('Benutzer Logout', () => {
// Wir generieren uns einen zufälligen Nutzer
const email = "user@ib-cornelsen.de"
const password = "passwort"
it("meldet einen Nutzer an und leitet auf die Startseite weiter", () => {
cy.visit("/auth/login")
cy.wait(1000)
cy.get('input[name="email"]').type(email)
cy.get('input[name="passwort"]').type(password)
cy.get('button[type="submit"]').click()
cy.url().should("include", "/dashboard")
// 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")
})
it("meldet einen Nutzer ab und leitet auf die Login Seite weiter", () => {
cy.visit("/auth/logout")
cy.url().should("include", "/auth/login")
})
})

View File

@@ -0,0 +1,24 @@
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import {faker} from "@faker-js/faker";
describe('Benutzer Passwort Vergessen', () => {
// Wir generieren uns einen zufälligen Nutzer
const email = "user@ib-cornelsen.de"
const password = "passwort"
it("fordert ein neues Passwort an", () => {
cy.visit("/auth/passwort-vergessen")
cy.wait(1000)
cy.get('input[name="email"]').type(email)
cy.get('button[type="submit"]').click()
cy.url().should("include", "/dashboard")
// Wir sollten nun einen Access Token und Refresh Token in unseren Cookies sehen.
cy.getCookie(API_ACCESS_TOKEN_COOKIE_NAME).should("exist")
cy.getCookie(API_REFRESH_TOKEN_COOKIE_NAME).should("exist")
})
})

View File

@@ -1,7 +1,7 @@
import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME } from "#lib/constants.js"; import { API_ACCESS_TOKEN_COOKIE_NAME, API_REFRESH_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import {faker} from "@faker-js/faker"; import {faker} from "@faker-js/faker";
describe('Benutzer Authentifizierung', () => { describe('Benutzer Registrierung', () => {
// Wir generieren uns einen zufälligen Nutzer // Wir generieren uns einen zufälligen Nutzer
const email = faker.internet.email() const email = faker.internet.email()
const password = faker.internet.password() const password = faker.internet.password()

View File

@@ -1,5 +1,5 @@
import { A9BerechnungNutzenergiebedarfTrinkwarmwasser } from "#lib/Berechnungen/BedarfsausweisWohnen/A9BerechnungNutzenergiebedarfTrinkwarmwasser.js"; import { A9BerechnungNutzenergiebedarfTrinkwarmwasser } from "#lib/Berechnungen/BedarfsausweisWohnen/A9BerechnungNutzenergiebedarfTrinkwarmwasser.js";
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { BedarfsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types.js";
/** /**
* Implementierung Tabelle A10 * Implementierung Tabelle A10
@@ -7,9 +7,9 @@ import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/
* @see 18599-Tabellenverfahren-Wohngebaeude.pdf * @see 18599-Tabellenverfahren-Wohngebaeude.pdf
* @export * @export
* @param {BedarfsausweisWohnenClient} ausweis * @param {BedarfsausweisWohnenClient} ausweis
* @param {GebaeudeAufnahmeClient} gebaeude_aufnahme * @param {AufnahmeClient} gebaeude_aufnahme
*/ */
export function A10BerechnungWaermequellenAnlagentechnikTrinkwarmwasser(ausweis: BedarfsausweisWohnenClient, gebaeude_aufnahme: GebaeudeAufnahmeClient) { export function A10BerechnungWaermequellenAnlagentechnikTrinkwarmwasser(ausweis: BedarfsausweisWohnenClient, gebaeude_aufnahme: AufnahmeClient) {
const result = A9BerechnungNutzenergiebedarfTrinkwarmwasser(ausweis, gebaeude_aufnahme); const result = A9BerechnungNutzenergiebedarfTrinkwarmwasser(ausweis, gebaeude_aufnahme);
const trinkwasserWaermebedarf = result.trinkwasserWaermebedarf; const trinkwasserWaermebedarf = result.trinkwasserWaermebedarf;

View File

@@ -26,7 +26,7 @@ export function A11BerechnungWaermequellenZusammenstellung() {
const result = A8BerechnungWaermequellenAusAnlagentechnikHeizung(); const result = A8BerechnungWaermequellenAusAnlagentechnikHeizung();
const ausweis = {}; // Replace with actual BedarfsausweisWohnenClient object const ausweis = {}; // Replace with actual BedarfsausweisWohnenClient object
const gebaeude_aufnahme = {}; // Replace with actual GebaeudeAufnahmeClient object const gebaeude_aufnahme = {}; // Replace with actual AufnahmeClient object
const resultTrinkwarmwasser = A10BerechnungWaermequellenAnlagentechnikTrinkwarmwasser(ausweis, gebaeude_aufnahme); const resultTrinkwarmwasser = A10BerechnungWaermequellenAnlagentechnikTrinkwarmwasser(ausweis, gebaeude_aufnahme);
const WaermeQuellenAnlagentechnikTrinkwarmwasser = resultTrinkwarmwasser.WaermeQuellenAnlagentechnikTrinkwarmwasser; const WaermeQuellenAnlagentechnikTrinkwarmwasser = resultTrinkwarmwasser.WaermeQuellenAnlagentechnikTrinkwarmwasser;

View File

@@ -1,4 +1,4 @@
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types.js"; import { BedarfsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types.js";
import { linearInterpolation } from "js-interpolate" import { linearInterpolation } from "js-interpolate"
@@ -8,9 +8,9 @@ import { linearInterpolation } from "js-interpolate"
* @see 18599-Tabellenverfahren-Wohngebaeude.pdf * @see 18599-Tabellenverfahren-Wohngebaeude.pdf
* @export * @export
* @param {BedarfsausweisWohnenClient} ausweis * @param {BedarfsausweisWohnenClient} ausweis
* @param {GebaeudeAufnahmeClient} gebaeude_aufnahme * @param {AufnahmeClient} gebaeude_aufnahme
*/ */
export function A9BerechnungNutzenergiebedarfTrinkwarmwasser(ausweis: BedarfsausweisWohnenClient, gebaeude_aufnahme: GebaeudeAufnahmeClient) { export function A9BerechnungNutzenergiebedarfTrinkwarmwasser(ausweis: BedarfsausweisWohnenClient, gebaeude_aufnahme: AufnahmeClient) {
// A_NGF aus Eingabe // A_NGF aus Eingabe
const bezugsflaeche = 154.2; const bezugsflaeche = 154.2;

View File

@@ -1,8 +1,7 @@
<script lang="ts"> <script lang="ts">
import { addNotification } from "@ibcornelsen/ui"; import { addNotification } from "@ibcornelsen/ui";
import { CrossCircled } from "radix-svelte-icons"; import { api } from "astro-typesafe-api/client";
import CheckCircled from "radix-svelte-icons/src/lib/icons/CheckCircled.svelte"; import { CrossCircled, CheckCircled } from "radix-svelte-icons";
import {client} from "src/trpc";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
let email: string; let email: string;
@@ -12,7 +11,7 @@
async function sendPasswordMail(e: SubmitEvent) { async function sendPasswordMail(e: SubmitEvent) {
e.preventDefault() e.preventDefault()
try { try {
const response = await client.v1.benutzer.passwortAnfrageSenden.query({ const response = await api.auth["forgot-password"].GET.fetch({
email email
}) })
@@ -20,7 +19,7 @@
} catch (e) { } catch (e) {
addNotification({ addNotification({
message: "Ups...", message: "Ups...",
subtext: "Da ist wohl etwas schiefgelaufen... Diese Email Adresse ist bereits in Benutzung, haben sie vielleicht bereits ein Konto bei uns?", subtext: "Da ist wohl etwas schiefgelaufen... Bitte versuchen sie es erneut, falls das Problem weiterhin bestehen sollte melden sie sich bei unserem Support damit wir ihnen helfen können.",
type: "error", type: "error",
timeout: 0, timeout: 0,
dismissable: true dismissable: true
@@ -44,7 +43,7 @@
required required
/> />
{#if showEmailSuccess} {#if showEmailSuccess}
<div role="alert" class="alert alert-success" in:fade> <div role="alert" class="flex bg-green-400 bg-opacity-25 border-green-600 border items-center gap-4 px-4 py-2 rounded-lg" in:fade>
<CheckCircled size={24} /> <CheckCircled size={24} />
<span class="font-semibold">Falls sie ein Konto bei uns haben wurde eine Email an sie verschickt.</span> <span class="font-semibold">Falls sie ein Konto bei uns haben wurde eine Email an sie verschickt.</span>
</div> </div>

View File

@@ -1,28 +1,37 @@
<script lang="ts"> <script lang="ts">
import { addNotification } from "@ibcornelsen/ui"; import { addNotification } from "#components/Notifications/index.js";
import {client} from "src/trpc"; import NotificationWrapper from "#components/Notifications/NotificationWrapper.svelte";
import { api } from "astro-typesafe-api/client";
let passwort: string; let passwort: string;
let passwortWiederholen: string; let passwortWiederholen: string;
export let token: string; export let token: string;
let disabled = false;
async function confirmResetPassword(e: SubmitEvent) { async function confirmResetPassword(e: SubmitEvent) {
e.preventDefault() e.preventDefault()
try { try {
await client.v1.benutzer.passwortZuruecksetzen.mutate({ disabled = true
await api.auth["forgot-password"].POST.fetch({
passwort, passwort,
token token
}) })
addNotification({ addNotification({
message: "Passwort zurückgesetzt.", message: "Passwort zurückgesetzt.",
subtext: "Ihr Passwort wurde erfolgreich zurückgesetzt, sie können diese Seite nun schließen.", subtext: "Ihr Passwort wurde erfolgreich zurückgesetzt, sie werden in kürze zum Login weitergeleitet.",
type: "success", type: "success",
timeout: 0, timeout: 0,
dismissable: true dismissable: true
}) })
setTimeout(() => {
window.location.href = "/auth/login"
}, 5000)
} catch (e) { } catch (e) {
disabled = false
addNotification({ addNotification({
message: "Ups...", message: "Ups...",
subtext: "Beim zurücksetzen ihres Passworts ist etwas schiefgelaufen, bitte versuchen sie es erneut.", subtext: "Beim zurücksetzen ihres Passworts ist etwas schiefgelaufen, bitte versuchen sie es erneut.",
@@ -46,6 +55,7 @@
data-test="passwort" data-test="passwort"
class="input input-bordered text-base text-base-content font-medium" class="input input-bordered text-base text-base-content font-medium"
bind:value={passwort} bind:value={passwort}
{disabled}
required required
/> />
<h4>Passwort wiederholen</h4> <h4>Passwort wiederholen</h4>
@@ -56,6 +66,7 @@
data-test="passwort_wiederholen" data-test="passwort_wiederholen"
class="input input-bordered text-base text-base-content font-medium" class="input input-bordered text-base text-base-content font-medium"
bind:value={passwortWiederholen} bind:value={passwortWiederholen}
{disabled}
required required
/> />
</div> </div>
@@ -68,4 +79,6 @@
> >
</div> </div>
</form> </form>
</div> </div>
<NotificationWrapper></NotificationWrapper>

View File

@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import { BenutzerClient, GebaeudeClient } from "#components/Ausweis/types"; import { BenutzerClient, ObjektClient } from "#components/Ausweis/types";
export let user: BenutzerClient; export let user: BenutzerClient;
export let gebaeudeArray: GebaeudeClient[]; export let gebaeudeArray: ObjektClient[];
</script> </script>
<h1 class="text-4xl font-medium my-8">Willkommen zurück, {user.vorname}!</h1> <h1 class="text-4xl font-medium my-8">Willkommen zurück, {user.vorname}!</h1>

View File

@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import PerformanceScore from "#components/Ausweis/PerformanceScore.svelte"; import PerformanceScore from "#components/Ausweis/PerformanceScore.svelte";
import ProgressBar from "#components/Ausweis/Progressbar.svelte"; import ProgressBar from "#components/Ausweis/Progressbar.svelte";
import Bereich from "#labels/Bereich.svelte"; import Bereich from "#components/labels/Bereich.svelte";
import Ansprechpartner from "#components/Ausweis/Ansprechpartner.svelte"; import Ansprechpartner from "#components/Ausweis/Ansprechpartner.svelte";
import Rechnungsadresse from "#components/Ausweis/Rechnungsadresse.svelte"; import Rechnungsadresse from "#components/Ausweis/Rechnungsadresse.svelte";
import Bezahlung from "#components/Ausweis/Bezahlung.svelte"; import Bezahlung from "#components/Ausweis/Bezahlung.svelte";
@@ -14,12 +14,13 @@
import LoginDialog from "#components/LoginDialog.svelte"; import LoginDialog from "#components/LoginDialog.svelte";
import { PRICES } from "#lib/constants.js"; import { PRICES } from "#lib/constants.js";
import { import {
AufnahmeClient, AufnahmeClient,
BenutzerClient, BenutzerClient,
ObjektClient, ObjektClient,
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "#components/Ausweis/types.js"; } from "#components/Ausweis/types.js";
import { validateAccessTokenClient } from "src/client/lib/validateAccessToken.js"; import { validateAccessTokenClient } from "src/client/lib/validateAccessToken.js";
import ButtonZurueckSpeichernKaufabschluss from "#components/Ausweis/ButtonZurueckSpeichernKaufabschluss.svelte";
export let user: BenutzerClient; export let user: BenutzerClient;
export let ausweis: VerbrauchsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient;
@@ -94,300 +95,277 @@
} }
</script> </script>
<div id="skala" class="bg-white grid grid-cols-1 gap-x-8 gap-y-4 p-4 <div
id="skala"
class="bg-white grid grid-cols-1 gap-x-8 gap-y-4 p-4
2xl:grid-cols-2 2xl:gap-x-8 2xl:grid-cols-2 2xl:gap-x-8
"> "
<div id="performance-box" class="w-full box relative px-4 order-2 2xl:order-1 self-stretch grid grid-cols-1"> >
<PerformanceScore <div
bind:ausweis id="performance-box"
bind:aufnahme class="w-full box relative px-4 order-2 2xl:order-1 self-stretch grid grid-cols-1"
bind:objekt >
/> <PerformanceScore bind:ausweis bind:aufnahme bind:objekt />
</div> </div>
<div id="progress-box" class="w-full box relative px-4 py-3 text-center order-1 2xl:order-2 self-stretch">
<h1 class="text-secondary text-3xl m-0">Energiesausweis erstellen</h1>
<h2 class="text-primary text-xl">Verbrauchsausweis Wohnen {PRICES.VerbrauchsausweisWohnen[0]}</h2>
<ProgressBar progress={50}
/>
</div>
<div
id="progress-box"
class="w-full box relative px-4 py-3 text-center order-1 2xl:order-2 self-stretch"
>
<h1 class="text-secondary text-3xl m-0">Energiesausweis erstellen</h1>
<h2 class="text-primary text-xl">
Verbrauchsausweis Wohnen {PRICES.VerbrauchsausweisWohnen[0]}
</h2>
<ProgressBar progress={50} />
</div>
</div> </div>
<form id="formInput-2" on:submit={speichern}> <form id="formInput-2" on:submit={speichern}>
<div id="formular-box" class="formular-boxen ring-0"> <div id="formular-box" class="formular-boxen ring-0">
<Bereich <Bereich
bind:user
bereich="1" bereich="1"
title="Eingabe des Ansprechpartners -> {user.email}" title="Eingabe des Ansprechpartners -> {user.email}"
> >
<Ansprechpartner <Ansprechpartner bind:user /></Bereich
bind:user
/></Bereich
> >
<Bereich <Bereich bereich="2" title="Rechnungsadresse">
bind:user <Rechnungsadresse bind:user /></Bereich
bereich="2"
title="Rechnungsadresse"
>
<Rechnungsadresse
bind:user
/></Bereich
> >
<Bereich <Bereich bereich="3" title="Bezahlmethode">
bind:selectedPaymentType <Bezahlung bind:selectedPaymentType /></Bereich
bereich="3"
title="Bezahlmethode"
>
<Bezahlung
bind:selectedPaymentType
/></Bereich
> >
<div class="grid grid-cols-2 gap-x-6 my-6">
<div class="zusaetze bereich-box bg-white">
<h3>Zusatzleistungen:</h3>
{#each services as service}
<div class="grid grid-cols-2 gap-x-6 my-6">
<div class="zusaetze bereich-box bg-white ">
<h3>Zusatzleistungen:</h3>
{#each services as service}
<div class="zusatz"> <div class="zusatz">
<input
<input type="checkbox"
type="checkbox" bind:checked={service.selected}
bind:checked={service.selected} />
/> <div class="text-right pr-6">
<div class="text-right pr-6"><b>{@html service.price}</b> inkl. Mwst</div> <b>{@html service.price}</b> inkl. Mwst
<div>{@html service.name}</div> </div>
<div>{@html service.name}</div>
</div> </div>
{/each} {/each}
</div>
<div class=" bereich-box bg-white ring-primary/50 ring-2" >
<h3>Kosten:</h3>
<div class="ProduktKostenTabelle">
<div class="zeile betrag">
<div>Netto-Preis Energieausweis</div><div>:</div><div class="text-right"><b>{(price * 0.81).toFixed(2) + " €"}</b></div>
</div> </div>
<div class="zeile betrag"> <div class=" bereich-box bg-white ring-primary/50 ring-2">
<div>Zusatzleistung (Prüfung Mehraufwand) <h3>Kosten:</h3>
</div><div>:</div><div class="text-right"><b>0.00 €</b></div>
</div> <div class="ProduktKostenTabelle">
<div class="zeile betrag">
<div class="zeile betrag"> <div>Netto-Preis Energieausweis</div>
<div>19% gesetzl. MwSt. <div>:</div>
</div><div>:</div><div class="text-right"><b>{(price * 0.19).toFixed(2) + " €"}</b></div> <div class="text-right">
</div> <b>{(price * 0.81).toFixed(2) + " €"}</b>
<div class="zeile betrag mt-4"> </div>
<div><b>Preis inkl. MwSt.</b> </div>
</div><div>:</div><div class="text-right"><b>{price.toFixed(2) + " €"}</b></div>
</div> <div class="zeile betrag">
<div class="zeile betrag mt-4 items-center"> <div>Zusatzleistung (Prüfung Mehraufwand)</div>
<div><b>Bezahlmethode</b> <div>:</div>
</div><div>:</div><div class="justify-self-end"> <div class="text-right"><b>0.00 €</b></div>
<img src="images/{selectedPaymentType}.png" alt="{selectedPaymentType}" /> </div>
<div class="zeile betrag">
<div>19% gesetzl. MwSt.</div>
<div>:</div>
<div class="text-right">
<b>{(price * 0.19).toFixed(2) + " €"}</b>
</div>
</div>
<div class="zeile betrag mt-4">
<div><b>Preis inkl. MwSt.</b></div>
<div>:</div>
<div class="text-right">
<b>{price.toFixed(2) + " €"}</b>
</div>
</div>
<div class="zeile betrag mt-4 items-center">
<div><b>Bezahlmethode</b></div>
<div>:</div>
<div class="justify-self-end">
<img
src="images/{selectedPaymentType}.png"
alt={selectedPaymentType}
/>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div> <ButtonZurueckSpeichernKaufabschluss />
<ButtonZurueckSpeichernKaufabschluss /> <div class="bereich-box pr-12 mt-6">
<Pruefung
<div class="bereich-box pr-12 mt-6"> bereich="A"
title="Prüfung der Ausweisart"
<Pruefung bullets={[
bereich="A" ["Vermietung, Verkauf oder sonstiges.", false],
title="Prüfung der Ausweisart" [
bullets={[ "Baujahr Heizung nicht kleiner als Baujahr Gebäude.",
["Vermietung, Verkauf oder sonstiges.", false], false,
["Baujahr Heizung nicht kleiner als Baujahr Gebäude.", false], ],
["Baujahr nach 1977 oder saniert oder mehr als 4 Wohneinheiten", false], [
["Heizung min. 3 Jahre alt.", false], "Baujahr nach 1977 oder saniert oder mehr als 4 Wohneinheiten",
["Verbrauchsausweis zulässig.", false] false,
]}> ],
</Pruefung> ["Heizung min. 3 Jahre alt.", false],
["Verbrauchsausweis zulässig.", false],
]}
></Pruefung>
<Pruefung <Pruefung
bereich="B" bereich="B"
title="Prüfung der Adresse, Wohnfläche, Keller und Dach" title="Prüfung der Adresse, Wohnfläche, Keller und Dach"
bullets={[ bullets={[
["PLZ gültig.", false], ["PLZ gültig.", false],
["Klimafaktorern.", false], ["Klimafaktorern.", false],
["Wohnfläche passt zu Wohneinheiten", false] ["Wohnfläche passt zu Wohneinheiten", false],
]}> ]}
</Pruefung> ></Pruefung>
<Pruefung <Pruefung
bereich="C" bereich="C"
title="Prüfung der Verbrauchsangaben" title="Prüfung der Verbrauchsangaben"
bullets={[ bullets={[
["Verbrauchsmenge schlüssig.", false], ["Verbrauchsmenge schlüssig.", false],
["Verbrauchsabweichung im Rahmen.", false], ["Verbrauchsabweichung im Rahmen.", false],
["Endenergieverbrauch schlüssig", false] ["Endenergieverbrauch schlüssig", false],
]}> ]}
</Pruefung> ></Pruefung>
<Pruefung <Pruefung
bereich="D" bereich="D"
title="Prüfung Warmwasser und alternative Energieversorgung" title="Prüfung Warmwasser und alternative Energieversorgung"
bullets={[ bullets={[
["Warmwasseranteil schlüssig.", false], ["Warmwasseranteil schlüssig.", false],
["Verbrauchsabweichung im Rahmen.", false], ["Verbrauchsabweichung im Rahmen.", false],
["Endenergieverbrauch schlüssig", false] ["Endenergieverbrauch schlüssig", false],
]}> ]}
</Pruefung> ></Pruefung>
<Pruefung <Pruefung
bereich="E" bereich="E"
title="Prüfung von Gebäudetyp, Lüftung, Kühlung und Leerstand" title="Prüfung von Gebäudetyp, Lüftung, Kühlung und Leerstand"
bullets={[ bullets={[["Leerstand nicht größer als 30%.", false]]}
["Leerstand nicht größer als 30%.", false] ></Pruefung>
]}>
</Pruefung>
<Pruefung <Pruefung
bereich="F" bereich="F"
title="Prüfung des Sanierungsstandes und der Gebäudebilder" title="Prüfung des Sanierungsstandes und der Gebäudebilder"
bullets={[ bullets={[
["Mindestens ein Bild pro Abschnitt vorhanden.", false], ["Mindestens ein Bild pro Abschnitt vorhanden.", false],
["Angaben zum Sanierungsstand vorhanden.", false], ["Angaben zum Sanierungsstand vorhanden.", false],
["Bei Baujahr vor 1978 Dach oder Geschossdecke min. 12 cm gedämmt.", false] [
]}> "Bei Baujahr vor 1978 Dach oder Geschossdecke min. 12 cm gedämmt.",
</Pruefung> false,
],
]}
></Pruefung>
</div>
</div>
<div class="varianten bereich-box bg-white">
<h3>Hiermit bestelle ich folgende Version des Energieausweises:</h3>
<div class="variante">
<input
type="radio"
bind:group={basePrice}
value={prices[0]}
name="Preis"
checked
/>
<div class="text-right pr-4"><b>{prices[0]}</b> inkl. MwSt.</div>
<div>Verbrauchsausweis online als PDF per E-Mail</div>
</div>
<div class="variante">
<input
type="radio"
bind:group={basePrice}
value={prices[1]}
name="Preis"
/>
<div class="text-right pr-4"><b>{prices[1]}</b> inkl. MwSt.</div>
<div>
Verbrauchsausweis online inkl. Beratung als PDF per E-Mail
</div> </div>
</div>
<div class="varianten bereich-box bg-white">
<h3>Hiermit bestelle ich folgende Version des Energieausweises:</h3>
<div class="variante">
<input
type="radio"
bind:group={basePrice}
value={prices[0]}
name="Preis"
checked
/>
<div class="text-right pr-4"><b>{prices[0]}</b> inkl. MwSt.</div>
<div>Verbrauchsausweis online als PDF per E-Mail</div>
</div>
<div class="variante">
<input
type="radio"
bind:group={basePrice}
value={prices[1]}
name="Preis"
/>
<div class="text-right pr-4"><b>{prices[1]}</b> inkl. MwSt.</div>
<div>Verbrauchsausweis online inkl. Beratung als PDF per E-Mail</div>
</div>
<div class="variante">
<input
type="radio"
bind:group={basePrice}
value={prices[2]}
name="Preis"
/>
<div class="text-right pr-4"><b>{prices[2]}</b> inkl. MwSt.</div>
<div>Verbrauchsausweis offline als PDF per E-Mail (Sie schicken uns 3 Verbrauchsabrechnungen)</div>
</div>
</div> </div>
<div class="variante">
<input
<div class="zusaetze bereich-box bg-white"> type="radio"
bind:group={basePrice}
<h3>Zusatzleistungen</h3> value={prices[2]}
name="Preis"
{#each services as service} />
<div class="text-right pr-4"><b>{prices[2]}</b> inkl. MwSt.</div>
<div class="zusatz"> <div>
Verbrauchsausweis offline als PDF per E-Mail (Sie schicken uns 3
<input Verbrauchsabrechnungen)
type="checkbox" </div>
bind:checked={service.selected}
/>
<div class="text-right pr-6"><b>{@html service.price}</b> inkl. Mwst</div>
<div>{@html service.name}</div>
</div>
{/each}
</div> </div>
</div> </div>
</div>
</div> <div class="zusaetze bereich-box bg-white">
<h3>Zusatzleistungen</h3>
<!-- <ButtonZurueckSpeichernKaufabschluss bind:ausweis bind:aufnahme bind:objekt bind:bilder bind:user /> -->
{#each services as service}
<div class="zusatz">
<input type="checkbox" bind:checked={service.selected} />
<div class="text-right pr-6">
<b>{@html service.price}</b> inkl. Mwst
</div>
<div>{@html service.name}</div>
</div>
{/each}
</div>
<!-- <ButtonZurueckSpeichernKaufabschluss bind:ausweis bind:aufnahme bind:objekt bind:bilder bind:user /> -->
</form> </form>
<style lang="postcss"> <style lang="postcss">
h3{@apply text-[1.25rem] ml-0 font-bold mb-6} h3 {
@apply text-[1.25rem] ml-0 font-bold mb-6;
.ProduktKostenTabelle{@apply block;
.zeile{@apply grid grid-cols-[19rem_1rem_5rem_1fr];}
.betrag{@apply font-bold text-[1.15rem]}
} }
.varianten{@apply block; .ProduktKostenTabelle {
.variante{@apply grid grid-cols-[40px_8rem_1fr] items-start pb-4; @apply block;
input{@apply mt-[5px] .zeile {
@apply grid grid-cols-[19rem_1rem_5rem_1fr];
}
.betrag {
@apply font-bold text-[1.15rem];
} }
} }
}
.zusaetze{@apply block; .varianten {
.zusatz{@apply grid grid-cols-[40px_8rem_1fr] items-start pb-3; @apply block;
input{@apply mt-[4px] .variante {
@apply grid grid-cols-[40px_8rem_1fr] items-start pb-4;
input {
@apply mt-[5px];
}
}
}
.zusaetze {
@apply block;
.zusatz {
@apply grid grid-cols-[40px_8rem_1fr] items-start pb-3;
input {
@apply mt-[4px];
}
} }
} }
}
</style> </style>

View File

@@ -27,7 +27,7 @@
import BilderZusatzsysteme from "../../components/Ausweis/BilderZusatzsysteme.svelte"; import BilderZusatzsysteme from "../../components/Ausweis/BilderZusatzsysteme.svelte";
import moment from "moment"; import moment from "moment";
import { Enums } from "@ibcornelsen/database/client"; import { Enums } from "@ibcornelsen/database/client";
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types.js"; import { ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types.js";
import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
export let ausweis: VerbrauchsausweisGewerbeClient; export let ausweis: VerbrauchsausweisGewerbeClient;

View File

@@ -3,7 +3,7 @@
import Layout from "#layouts/Layout.astro"; import Layout from "#layouts/Layout.astro";
import { berechnungNutzenergiebedarfHeizen } from "#lib/Berechnungen/BedarfsausweisWohnen/BerechnungNutzenergiebedarfHeizen.js" import { berechnungNutzenergiebedarfHeizen } from "#lib/Berechnungen/BedarfsausweisWohnen/BerechnungNutzenergiebedarfHeizen.js"
import A12NutzenergiebedarfHeizung from "#components/Tabellen/A12NutzenergiebedarfHeizung.svelte"; import A12NutzenergiebedarfHeizung from "#components/Tabellen/A12NutzenergiebedarfHeizung.svelte";
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types"; import { BedarfsausweisWohnenClient, AufnahmeClient } from "#components/Ausweis/types";
import A1AnlagenBeschreibung from "#components/Tabellen/A1AnlagenBeschreibung.svelte"; import A1AnlagenBeschreibung from "#components/Tabellen/A1AnlagenBeschreibung.svelte";
import A1AllgemeineAnlagenbeschreibung from "#components/Tabellen/A1AllgemeineAnlagenbeschreibung.svelte"; import A1AllgemeineAnlagenbeschreibung from "#components/Tabellen/A1AllgemeineAnlagenbeschreibung.svelte";
import A2WaermequellenSolareEinstrahlungWintergarten from "#components/Tabellen/A2WaermequellenSolareEinstrahlungWintergarten.svelte"; import A2WaermequellenSolareEinstrahlungWintergarten from "#components/Tabellen/A2WaermequellenSolareEinstrahlungWintergarten.svelte";
@@ -20,7 +20,7 @@ import A14AufwandszahlenMittlereBelastung from "#components/Tabellen/A14Aufwands
import A15AufwandszahlenGesamtErzeugernutzWaerme from "#components/Tabellen/A15AufwandszahlenGesamtErzeugernutzWaerme.svelte"; import A15AufwandszahlenGesamtErzeugernutzWaerme from "#components/Tabellen/A15AufwandszahlenGesamtErzeugernutzWaerme.svelte";
const ausweis: BedarfsausweisWohnenClient = {}; const ausweis: BedarfsausweisWohnenClient = {};
const gebaeude_aufnahme: GebaeudeAufnahmeClient = { flaeche: 152 } const gebaeude_aufnahme: AufnahmeClient = { flaeche: 152 }
--- ---

View File

@@ -0,0 +1,137 @@
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
import * as nodemailer from "nodemailer"
import { prisma } from "@ibcornelsen/database/server";
import { decodeToken, encodeToken } from "#lib/auth/token.js";
import { TokenType } from "#lib/auth/types.js";
import { hashPassword } from "#lib/password.js";
export const GET = defineApiRoute({
input: z.object({
email: z.string().email()
}),
output: z.void(),
async fetch(input, context, transfer) {
const user = await prisma.benutzer.findUnique({
where: {
email: input.email
}
})
if (!user) {
// Wir senden einen INTERNAL_SERVER_ERROR zurück, damit man nicht aus dem Fehler schließen kann, ob es den Nutzer gibt.
throw new APIError({
code: "INTERNAL_SERVER_ERROR",
message: "Etwas ist schiefgelaufen, bitte versuchen sie es erneut."
})
}
// Wir generieren einen Token der für 30 Minuten gültig ist, damit der Nutzer das Passwort zurücksetzen kann.
const resetToken = encodeToken({
exp: Date.now() + 15 * 60 * 1000,
typ: TokenType.Reset,
uid: user.uid
})
const transport = nodemailer.createTransport({
host: "smtp.ionos.de",
port: 465,
secure: true,
auth: {
user: "info@online-energieausweis.org",
pass: "Katendeich5a2024!"
}
})
const info = await transport.sendMail({
from: `"IBCornelsen" <info@online-energieausweis.org>`,
to: input.email,
subject: "Zurücksetzen ihres Passworts",
text: `Hallo ${user.vorname},
sie haben eine Anfrage zum Zurücksetzen ihres Passworts gestellt. Klicken sie auf den folgenden Link, um ein neues Passwort festzulegen:
https://ibcornelsen.de/auth/passwort-zuruecksetzen?t=${resetToken}
Dieser Link ist für die nächsten 15 Minuten gültig. Falls du diese Anfrage nicht gestellt hast, kannst du diese E-Mail ignorieren - dein Passwort bleibt unverändert.
Falls du Hilfe benötigst, kontaktiere uns unter info@online-energieausweis.org.
Viele Grüße,
IBCornelsen`
})
if (info.rejected) {
throw new APIError({
code: "INTERNAL_SERVER_ERROR",
message: "Etwas ist schiefgelaufen, bitte versuchen sie es erneut."
})
}
},
})
export const POST = defineApiRoute({
input: z.object({
token: z.string(),
passwort: z.string()
}),
output: z.void(),
async fetch(input, context, transfer) {
const decoded = decodeToken(input.token);
if (!decoded.exp || decoded.exp < Date.now() || decoded.typ !== TokenType.Reset || !decoded.uid) {
throw new APIError({
code: "BAD_REQUEST",
message: "Der von ihnen benutzte Token ist nicht mehr gültig."
})
}
const user = await prisma.benutzer.findUnique({
where: {
uid: decoded.uid
}
})
if (!user) {
throw new APIError({
code: "NOT_FOUND",
message: "Kein Benutzer passt zu dem genutzten Token."
})
}
const hashed = hashPassword(input.passwort)
await prisma.benutzer.update({
where: {
uid: decoded.uid
},
data: {
passwort: hashed
}
})
const transport = nodemailer.createTransport({
host: "smtp.ionos.de",
port: 465,
secure: true,
auth: {
user: "info@online-energieausweis.org",
pass: "Katendeich5a2024!"
}
})
const info = await transport.sendMail({
from: `"IBCornelsen" <info@online-energieausweis.org>`,
to: user.email,
subject: "Ihr Passwort wurde erfolgreich zurückgesetzt",
text: `Hallo ${user.vorname},
Ihr Passwort wurde erfolgreich zurückgesetzt. Sie können sich jetzt mit Ihrem neuen Passwort anmelden.
Falls Sie diese Änderung nicht selbst vorgenommen haben, setzen Sie Ihr Passwort bitte sofort erneut zurück und kontaktieren Sie unseren Support unter info@online-energieausweis.org.
Viele Grüße,
IBCornelsen`
})
},
})

View File

@@ -2,6 +2,8 @@
import PasswortZuruecksetzenModule from "../../modules/Auth/PasswortZuruecksetzenModule.svelte"; import PasswortZuruecksetzenModule from "../../modules/Auth/PasswortZuruecksetzenModule.svelte";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken"; import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import MinimalLayout from "#layouts/MinimalLayout.astro"; import MinimalLayout from "#layouts/MinimalLayout.astro";
import { decodeToken } from "#lib/auth/token";
import { TokenType } from "#lib/auth/types";
const valid = await validateAccessTokenServer(Astro) const valid = await validateAccessTokenServer(Astro)
@@ -9,10 +11,19 @@ if (valid) {
return Astro.redirect("/dashboard") return Astro.redirect("/dashboard")
} }
const token = Astro.url.searchParams.get("token") const token = Astro.url.searchParams.get("t")
if (!token) { if (!token) {
return Astro.redirect("/login") return Astro.redirect("/")
}
const decoded = decodeToken(token)
console.log(decoded.exp, Date.now());
if (!decoded.exp || decoded.exp < Date.now() || decoded.typ !== TokenType.Reset) {
return Astro.redirect("/")
} }
--- ---