Bugfixes, Kundendaten, Datenbank Anpassung
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { defineConfig } from "astro/config";
|
||||
import svelte from "@astrojs/svelte";
|
||||
import astroI18next from "astro-i18next";
|
||||
// import astroI18next from "astro-i18next";
|
||||
|
||||
import tailwind from "@astrojs/tailwind";
|
||||
|
||||
@@ -12,7 +12,7 @@ import mdx from "@astrojs/mdx";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [astroI18next(),svelte(), tailwind(), mdx()],
|
||||
integrations: [/*astroI18next(),*/svelte(), tailwind(), mdx()],
|
||||
outDir: "./dist",
|
||||
output: "server",
|
||||
adapter: node({
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
POSTGRES_DB=main
|
||||
POSTGRES_HOST=database
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_USER=main
|
||||
POSTGRES_PASSWORD=hHMP8cd^N3SnzGRR
|
||||
|
||||
DB_CONTAINER_NAME=database
|
||||
|
||||
POSTGRES_DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
|
||||
@@ -1,11 +1,9 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
online-energieausweis:
|
||||
ibcornelsen-online-energieausweis:
|
||||
build: ./
|
||||
container_name: online-energieausweis
|
||||
command: bun run dev --host
|
||||
depends_on:
|
||||
- database
|
||||
environment:
|
||||
PORT: 3000
|
||||
NODE_ENV: "development"
|
||||
@@ -14,9 +12,5 @@ services:
|
||||
- ./:/online-energieausweis
|
||||
- ./node_modules/@ibcornelsen/ui:/online-energieausweis/node_modules/@ibcornelsen/ui
|
||||
- ./node_modules/@ibcornelsen/database:/online-energieausweis/node_modules/@ibcornelsen/database
|
||||
- ./node_modules/@ibcornelsen/api:/online-energieausweis/node_modules/@ibcornelsen/api
|
||||
- ./persistent:/persistent
|
||||
database:
|
||||
network_mode: host
|
||||
build: ../database
|
||||
env_file:
|
||||
- ../database/.env
|
||||
@@ -28,6 +28,7 @@
|
||||
"@trpc/server": "^10.45.0",
|
||||
"astro": "^2.5.1",
|
||||
"astro-i18next": "1.0.0-beta.21",
|
||||
"buffer": "^6.0.3",
|
||||
"bun": "^1.0.2",
|
||||
"cookiejs": "^2.1.2",
|
||||
"csvtojson": "^2.0.10",
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
import { Buffer } from "buffer";
|
||||
|
||||
export let ausweis: VerbrauchsausweisWohnen;
|
||||
export let gebaeude: GebaeudeStammdaten;
|
||||
|
||||
const base64 = btoa(JSON.stringify(ausweis));
|
||||
let base64: string = "";
|
||||
$: {
|
||||
if (ausweis && gebaeude) {
|
||||
base64 = Buffer.from(JSON.stringify({...ausweis, gebaeude_stammdaten: gebaeude}), "utf-8").toString("base64");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/datenblatt?base64={base64}">
|
||||
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/ansichtsausweis?base64={base64}">
|
||||
<img src="/images/ausweis.webp" alt="Ausweis" />
|
||||
<span class="text-black font-medium text-lg">Ansichtsausweis</span>
|
||||
</a>
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
import HelpLabel from "#components/HelpLabel.svelte";
|
||||
|
||||
export let ausweis: VerbrauchsausweisWohnen;
|
||||
export let gebaeude: GebaeudeStammdaten;
|
||||
|
||||
import ImageGrid from "../ImageGrid.svelte";
|
||||
import { VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
|
||||
let images: (File & { data: string })[] = [];
|
||||
</script>
|
||||
@@ -33,8 +34,8 @@
|
||||
<hr class="trenner_form_100" />
|
||||
|
||||
<div class="flex flex-row gap-4">
|
||||
<AnsichtsausweisButton {ausweis} />
|
||||
<DatenblattButton {ausweis} />
|
||||
<AnsichtsausweisButton {ausweis} {gebaeude} />
|
||||
<DatenblattButton {ausweis} {gebaeude} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -348,4 +348,4 @@
|
||||
als PDF anschauen</Label
|
||||
>
|
||||
|
||||
<AusweisPreviewContainer {ausweis} />
|
||||
<AusweisPreviewContainer {ausweis} {gebaeude} />
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
import { Buffer } from "buffer";
|
||||
|
||||
export let ausweis: VerbrauchsausweisWohnen;
|
||||
export let gebaeude: GebaeudeStammdaten;
|
||||
|
||||
const base64 = btoa(JSON.stringify(ausweis));
|
||||
let base64: string = "";
|
||||
$: {
|
||||
if (ausweis && gebaeude) {
|
||||
base64 = Buffer.from(JSON.stringify({...ausweis, gebaeude_stammdaten: gebaeude}), "utf-8").toString("base64");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/datenblatt?base64={base64}">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
import i18next from "i18next";
|
||||
import {localizeUrl} from "astro-i18next"
|
||||
import { t } from "i18next";
|
||||
// import i18next from "i18next";
|
||||
// import {localizeUrl} from "astro-i18next"
|
||||
// import { t } from "i18next";
|
||||
import { isLoggedIn } from "../lib/UI/isLoggedIn";
|
||||
import LanguageDropdown from "./LanguageDropdown.svelte";
|
||||
// import LanguageDropdown from "./LanguageDropdown.svelte";
|
||||
|
||||
const loggedIn = isLoggedIn(Astro);
|
||||
---
|
||||
@@ -38,7 +38,7 @@ const loggedIn = isLoggedIn(Astro);
|
||||
</div>
|
||||
|
||||
<div class="nav-head">
|
||||
<LanguageDropdown
|
||||
<!--<LanguageDropdown
|
||||
countries={[
|
||||
{ iso: "de", flag: "de", name: "Deutsch" },
|
||||
{ iso: "en", flag: "us", name: "English" },
|
||||
@@ -49,7 +49,7 @@ const loggedIn = isLoggedIn(Astro);
|
||||
})}
|
||||
current={i18next.language}
|
||||
client:load
|
||||
/>
|
||||
/> -->
|
||||
<a
|
||||
class="headerButton"
|
||||
href="/energieausweis-erstellen/verbrauchsausweis-erstellen.php"
|
||||
|
||||
15
src/components/PaymentOption.svelte
Normal file
15
src/components/PaymentOption.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { Bezahlmethoden } from "@ibcornelsen/database";
|
||||
|
||||
export let name: string;
|
||||
export let icon: string;
|
||||
export let paymentType: Bezahlmethoden;
|
||||
export let selectedPaymentType: Bezahlmethoden;
|
||||
</script>
|
||||
|
||||
<button class="flex flex-col items-center cursor-pointer" class:bg-gray-100={paymentType == selectedPaymentType} on:click={() => selectedPaymentType = paymentType}>
|
||||
<img src={icon} alt={name} />
|
||||
<span aria-label={name}>
|
||||
{name}
|
||||
</span>
|
||||
</button>
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
import { localizePath } from "astro-i18next"
|
||||
---
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<nav>
|
||||
<div class="nav-card">
|
||||
@@ -10,9 +6,9 @@ import { localizePath } from "astro-i18next"
|
||||
>Energieausweis erstellen</a
|
||||
>
|
||||
<div class="dropdown-content">
|
||||
<a href={localizePath("/verbrauchsausweis")}>Verbrauchsausweis erstellen</a>
|
||||
<a href={localizePath("/bedarfsausweis")}>Bedarfsausweis erstellen</a>
|
||||
<a href={localizePath("/verbrauchsausweis-gewerbe")}
|
||||
<a href="/verbrauchsausweis">Verbrauchsausweis erstellen</a>
|
||||
<a href="/bedarfsausweis">Bedarfsausweis erstellen</a>
|
||||
<a href="/verbrauchsausweis-gewerbe"
|
||||
>Verbrauchsausweis Gewerbe erstellen</a
|
||||
>
|
||||
<a href="/bedarfsausweis-gewerbe"
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
import ZipSearch from "../ZIPSearch.svelte";
|
||||
import { buildingTypes } from "./BuildingTypes";
|
||||
import BilderZusatzsysteme from "../Ausweis/BilderZusatzsysteme.svelte";
|
||||
import { VerbrauchsausweisGewerbe } from "src/lib/Ausweis/VerbrauchsausweisGewerbe";
|
||||
import moment from "moment";
|
||||
import { VerbrauchsausweisGewerbe } from "@ibcornelsen/database";
|
||||
|
||||
let ausweis = new VerbrauchsausweisGewerbe();
|
||||
let ausweis: VerbrauchsausweisGewerbe = {};
|
||||
|
||||
let additionalHeating: boolean = false;
|
||||
let heatedWaterIncluded: boolean = false;
|
||||
|
||||
@@ -43,8 +43,6 @@ const schema = JSON.stringify({
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<script type="application/ld+json" set:html={schema}></script>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.jpg" />
|
||||
<link rel="stylesheet" href="style/main.css" />
|
||||
<link rel="stylesheet" href="style/bootstrap.min.css" />
|
||||
|
||||
<meta
|
||||
name="description"
|
||||
|
||||
@@ -47,8 +47,6 @@ const schema = JSON.stringify({
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<script type="application/ld+json" set:html={schema}></script>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.jpg" />
|
||||
<link rel="stylesheet" href="style/main.css" />
|
||||
<link rel="stylesheet" href="style/bootstrap.min.css" />
|
||||
|
||||
<meta
|
||||
name="description"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getKlimafaktoren } from "#lib/getKlimafaktoren";
|
||||
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
||||
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import jwt from "jwt-simple";
|
||||
|
||||
type TokenData = { uid: string, exp: number }
|
||||
|
||||
export function encodeToken(data: TokenData) {
|
||||
const token = jwt.encode(data, "yIvbgS$k7Bfc+mpV%TWDZAhje9#uJad4", "HS256");
|
||||
return token;
|
||||
}
|
||||
|
||||
export function decodeToken(token: string): Partial<TokenData> {
|
||||
return jwt.decode(token, "yIvbgS$k7Bfc+mpV%TWDZAhje9#uJad4");
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as crypto from "crypto";
|
||||
|
||||
export function hashPassword(password: string): string {
|
||||
const salt = crypto.randomBytes(16).toString("hex");
|
||||
const hash = hashWithGivenSalt(password, salt) + salt;
|
||||
return hash;
|
||||
}
|
||||
|
||||
export function hashWithGivenSalt(password: string, salt: string): string {
|
||||
const hash = crypto.scryptSync(password, salt, 32).toString("hex");
|
||||
return hash;
|
||||
}
|
||||
|
||||
export function validatePassword(known: string, unknown: string): boolean {
|
||||
const salt = known.slice(64);
|
||||
const originalPasswordHash = known.slice(0, 64);
|
||||
const currentPasswordHash = hashWithGivenSalt(unknown, salt)
|
||||
return originalPasswordHash == currentPasswordHash;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
endEnergieVerbrauchVerbrauchsausweis_2016,
|
||||
energetischeNutzflaecheVerbrauchsausweisWohnen_2016,
|
||||
} from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||
import { getKlimafaktoren } from "#lib/getKlimafaktoren";
|
||||
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
||||
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
||||
import {
|
||||
GebaeudeStammdaten,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export { validateAuthorizationHeader } from "./validate";
|
||||
@@ -1,62 +0,0 @@
|
||||
import { decodeToken } from "src/lib/JsonWebToken";
|
||||
import { validatePassword } from "src/lib/Password";
|
||||
import { User } from "src/lib/User";
|
||||
|
||||
export async function validateAuthorizationHeader(
|
||||
request: Request,
|
||||
validAuthenticationMethods: ("Bearer" | "Basic")[]
|
||||
): Promise<User | null> {
|
||||
if (!request.headers.has("authorization")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const header = request.headers.get("authorization") as string;
|
||||
|
||||
const [authorizationType, value] = header.split(" ");
|
||||
|
||||
if (authorizationType == "Basic" && validAuthenticationMethods.indexOf("Basic") > -1) {
|
||||
// Basic user validation;
|
||||
try {
|
||||
const [email, password] = Buffer.from(value, "base64")
|
||||
.toString()
|
||||
.split(":");
|
||||
const user = await User.fromEmail(email);
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!validatePassword(user.passwort, password)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return user;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
} else if (authorizationType == "Bearer" && validAuthenticationMethods.indexOf("Bearer") > -1) {
|
||||
const stringToken = Buffer.from(value, "base64").toString();
|
||||
try {
|
||||
const token = decodeToken<{ id: number; uid: string; exp: string }>(
|
||||
stringToken
|
||||
);
|
||||
const id = token.id;
|
||||
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const user = User.fromPrivateId(id);
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return user;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { initTRPC } from "@trpc/server";
|
||||
import { ZodError } from "zod";
|
||||
import { OpenApiMeta } from "trpc-openapi";
|
||||
|
||||
type Context = {
|
||||
authorization: string | null;
|
||||
ip: string;
|
||||
req: Request;
|
||||
}
|
||||
|
||||
export const t = initTRPC.context<Context>().meta<OpenApiMeta>().create({
|
||||
|
||||
errorFormatter(opts) {
|
||||
const { shape, error } = opts;
|
||||
return {
|
||||
success: false,
|
||||
...shape,
|
||||
data: {
|
||||
zodError:
|
||||
error.code === 'BAD_REQUEST' && error.cause instanceof ZodError
|
||||
? error.cause.flatten()
|
||||
: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { privateProcedure } from "./privateProcedure";
|
||||
|
||||
// NOTE: Muss noch mit der Datenbank eingebunden werden.
|
||||
export const loggedProcedure = privateProcedure.use(async (opts) => {
|
||||
const start = Date.now();
|
||||
|
||||
const result = await opts.next();
|
||||
|
||||
const durationMs = Date.now() - start;
|
||||
|
||||
await prisma.apiRequests.create({
|
||||
data: {
|
||||
ip: opts.ctx.ip,
|
||||
method: opts.type,
|
||||
path: opts.path,
|
||||
responseSize: JSON.stringify(result).length,
|
||||
responseTime: durationMs,
|
||||
userAgent: opts.ctx.req.headers["user-agent"] || "",
|
||||
status: result.ok ? 200 : 500,
|
||||
user_id: opts.ctx.user.id
|
||||
}
|
||||
})
|
||||
|
||||
return result;
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { publicProcedure } from "./publicProcedure";
|
||||
import { decodeToken } from "#lib/JsonWebToken";
|
||||
import { User } from "#lib/User";
|
||||
|
||||
export const privateProcedure = publicProcedure.use(async (opts) => {
|
||||
const { ctx } = opts;
|
||||
|
||||
if (!ctx.authorization) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Für diese Action ist ein Bearer Token verpflichtend." });
|
||||
}
|
||||
|
||||
const [authorizationType, value] = ctx.authorization.split(" ");
|
||||
|
||||
if (authorizationType != "Bearer") {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Für diese Action ist ein Bearer Token verpflichtend." });
|
||||
}
|
||||
|
||||
const stringToken = Buffer.from(value, "base64").toString();
|
||||
try {
|
||||
const token = decodeToken(
|
||||
stringToken
|
||||
);
|
||||
const uid = token.uid;
|
||||
|
||||
if (!uid) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Der gegebene Token ist fehlerhaft." });
|
||||
}
|
||||
|
||||
const user = await User.fromUID(uid);
|
||||
|
||||
if (!user) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Der gegebene Token ist fehlerhaft." });
|
||||
}
|
||||
|
||||
return opts.next({
|
||||
ctx: {
|
||||
user,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Der gegebene Token ist fehlerhaft." });
|
||||
}
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
import { t } from "#lib/trpc/context";
|
||||
|
||||
export const publicProcedure = t.procedure;
|
||||
@@ -1,64 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import moment from "moment";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||
import { encodeToken } from "#lib/JsonWebToken";
|
||||
import { hashPassword } from "#lib/Password";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
export const tRPC_V1_BenutzerErstellenProcedure = publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
email: z.string().email(),
|
||||
passwort: z.string().min(8).max(100),
|
||||
vorname: z.string().min(1).max(100),
|
||||
name: z.string().min(1).max(100),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
uid: z.string().uuid(),
|
||||
token: z.string(),
|
||||
exp: z.number(),
|
||||
})
|
||||
)
|
||||
.query(async (opts) => {
|
||||
const hashedPassword = hashPassword(opts.input.passwort);
|
||||
|
||||
// Vielleicht existiert der Benutzer ja schon?
|
||||
const existingUser = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
email: opts.input.email
|
||||
}
|
||||
})
|
||||
|
||||
if (existingUser) {
|
||||
throw new TRPCError({ code: "CONFLICT", message: "Der Benutzer existiert bereits." });
|
||||
}
|
||||
|
||||
const user = await prisma.benutzer.create({
|
||||
data: {
|
||||
email: opts.input.email,
|
||||
passwort: hashedPassword,
|
||||
vorname: opts.input.vorname,
|
||||
name: opts.input.name
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
uid: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Der Benutzer konnte nicht erstellt werden." });
|
||||
}
|
||||
|
||||
const expiry = moment().add(2, "days").unix();
|
||||
const token = encodeToken({ uid: user.uid, exp: expiry })
|
||||
|
||||
return {
|
||||
uid: user.uid,
|
||||
token: token,
|
||||
exp: expiry
|
||||
}
|
||||
});
|
||||
@@ -1,31 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { BenutzerSchema, prisma } from "@ibcornelsen/database";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { loggedProcedure } from "#lib/trpc/middlewares/loggedProcedure";
|
||||
|
||||
export const tRPC_V1_BenutzerFromPrivateIdProcedure = loggedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
id: z.number(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
BenutzerSchema
|
||||
)
|
||||
.query(async (opts) => {
|
||||
if (opts.ctx.user.id !== opts.input.id) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Sie sind nicht dazu authorisiert die Daten dieses Benutzers einzusehen." });
|
||||
}
|
||||
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
id: opts.input.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht." });
|
||||
}
|
||||
|
||||
return user;
|
||||
});
|
||||
@@ -1,31 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { BenutzerSchema, prisma } from "@ibcornelsen/database";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { loggedProcedure } from "#lib/trpc/middlewares/loggedProcedure";
|
||||
|
||||
export const tRPC_V1_BenutzerFromPublicIdProcedure = loggedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
uid: z.string().uuid(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
BenutzerSchema
|
||||
)
|
||||
.query(async (opts) => {
|
||||
if (opts.ctx.user.uid !== opts.input.uid) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Sie sind nicht dazu authorisiert die Daten dieses Benutzers einzusehen." });
|
||||
}
|
||||
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
uid: opts.input.uid,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht." });
|
||||
}
|
||||
|
||||
return user;
|
||||
});
|
||||
@@ -1,50 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import moment from "moment";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||
import { encodeToken } from "#lib/JsonWebToken";
|
||||
import { hashPassword } from "#lib/Password";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
export const tRPC_V1_BenutzerTokenErneuernProcedure = publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
email: z.string().email(),
|
||||
passwort: z.string().min(8).max(100),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
uid: z.string().uuid(),
|
||||
token: z.string(),
|
||||
exp: z.number(),
|
||||
})
|
||||
)
|
||||
.query(async (opts) => {
|
||||
const hashedPassword = hashPassword(opts.input.passwort);
|
||||
|
||||
// Falls der Nutzer nicht existiert, wird eine Fehlermeldung zurückgegeben.
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
email: opts.input.email
|
||||
}
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht oder das Password ist falsch." });
|
||||
}
|
||||
|
||||
// Falls das Passwort nicht stimmt, wird eine Fehlermeldung zurückgegeben.
|
||||
if (user.passwort !== hashedPassword) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Der gesuchte Benutzer existiert nicht oder das Password ist falsch." });
|
||||
}
|
||||
|
||||
const expiry = moment().add(2, "days").unix();
|
||||
const token = encodeToken({ uid: user.uid, exp: expiry })
|
||||
|
||||
return {
|
||||
uid: user.uid,
|
||||
token: token,
|
||||
exp: expiry
|
||||
}
|
||||
});
|
||||
@@ -1,49 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||
import { decodeToken } from "#lib/JsonWebToken";
|
||||
|
||||
export const tRPC_V1_BenutzerTokenValidierenProcedure = publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
token: z.string(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
uid: z.string().uuid(),
|
||||
valid: z.boolean(),
|
||||
exp: z.number()
|
||||
})
|
||||
)
|
||||
.query(async (opts) => {
|
||||
const decodedToken = decodeToken(opts.input.token);
|
||||
|
||||
if (!decodedToken || !decodedToken.uid || !decodedToken.exp) {
|
||||
return {
|
||||
uid: "",
|
||||
valid: false,
|
||||
exp: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
uid: decodedToken.uid,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return {
|
||||
uid: "",
|
||||
valid: false,
|
||||
exp: 0,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
uid: decodedToken.uid,
|
||||
valid: true,
|
||||
exp: decodedToken.exp
|
||||
};
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
import { t } from "#lib/trpc/context";
|
||||
import { tRPC_V1_KlimafaktorenProcedure } from "./klimafaktoren";
|
||||
import { VerbrauchsausweisWohnen2016Erstellen } from "./verbrauchsausweis-wohnen/2016/erstellen";
|
||||
import { tRPC_V1_BenutzerErstellenProcedure } from "./benutzer/erstellen";
|
||||
import { tRPC_V1_BenutzerTokenErneuernProcedure } from "./benutzer/tokenErneuern";
|
||||
import { tRPC_V1_BenutzerTokenValidierenProcedure } from "./benutzer/tokenValidieren";
|
||||
import { tRPC_V1_BenutzerFromPublicIdProcedure } from "./benutzer/fromPublicId";
|
||||
import { tRPC_V1_BenutzerFromPrivateIdProcedure } from "./benutzer/fromPrivateId";
|
||||
|
||||
const router = t.router;
|
||||
|
||||
export const v1Router = router({
|
||||
verbrauchsausweisWohnen: router({
|
||||
2016: router({
|
||||
erstellen: VerbrauchsausweisWohnen2016Erstellen
|
||||
}),
|
||||
2023: router({
|
||||
|
||||
})
|
||||
}),
|
||||
verbrauchsausweisGewerbe: router({
|
||||
2016: router({
|
||||
|
||||
}),
|
||||
2023: router({
|
||||
|
||||
})
|
||||
}),
|
||||
bedarfsausweisWohen: router({
|
||||
2016: router({
|
||||
|
||||
}),
|
||||
2023: router({
|
||||
|
||||
})
|
||||
}),
|
||||
klimafaktoren: tRPC_V1_KlimafaktorenProcedure,
|
||||
benutzer: router({
|
||||
erstellen: tRPC_V1_BenutzerErstellenProcedure,
|
||||
tokenErneuern: tRPC_V1_BenutzerTokenErneuernProcedure,
|
||||
tokenValidieren: tRPC_V1_BenutzerTokenValidierenProcedure,
|
||||
fromPublicId: tRPC_V1_BenutzerFromPublicIdProcedure,
|
||||
fromPrivateId: tRPC_V1_BenutzerFromPrivateIdProcedure
|
||||
})
|
||||
})
|
||||
@@ -1,78 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import moment from "moment";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||
|
||||
export const tRPC_V1_KlimafaktorenProcedure = publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
plz: z.string().min(4).max(5),
|
||||
startdatum: z.coerce.date(),
|
||||
enddatum: z.coerce.date(),
|
||||
genauigkeit: z.enum(["months", "years"]),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
z.array(
|
||||
z.object({
|
||||
month: z.number(),
|
||||
year: z.number(),
|
||||
klimafaktor: z.number(),
|
||||
})
|
||||
)
|
||||
)
|
||||
.query(async (opts) => {
|
||||
const start = moment(opts.input.startdatum);
|
||||
const end = moment(opts.input.enddatum);
|
||||
|
||||
if (start.isSameOrAfter(end)) {
|
||||
throw new TRPCError({
|
||||
code: "PRECONDITION_FAILED",
|
||||
message: "Das Startdatum kann nicht vor dem Enddatum liegen.",
|
||||
});
|
||||
}
|
||||
|
||||
const intervals = [];
|
||||
|
||||
let currentDate = start.clone();
|
||||
while (currentDate.isSameOrBefore(end)) {
|
||||
let copy = currentDate.clone();
|
||||
intervals.push(copy);
|
||||
currentDate.add(1, opts.input.genauigkeit);
|
||||
}
|
||||
|
||||
let klimafaktoren = await prisma.klimafaktoren.findMany({
|
||||
where: {
|
||||
plz: opts.input.plz,
|
||||
month: intervals[0].month(),
|
||||
OR: intervals.map((date) => {
|
||||
return {
|
||||
year: date.year(),
|
||||
};
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!klimafaktoren) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message:
|
||||
"Die Klimafaktoren konnten nicht geladen werden. Das kann daran liegen, dass sie für diesen Zeitraum oder Ort nicht verfügbar sind.",
|
||||
});
|
||||
}
|
||||
|
||||
if (klimafaktoren.length !== intervals.length) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message:
|
||||
"Für diesen Zeitraum konnten nicht alle Klimafaktoren gefunden werden.",
|
||||
});
|
||||
}
|
||||
|
||||
return klimafaktoren.map((klimafaktor) => ({
|
||||
month: klimafaktor.month,
|
||||
year: klimafaktor.year,
|
||||
klimafaktor: klimafaktor.klimafaktor,
|
||||
}));
|
||||
});
|
||||
@@ -1,143 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { publicProcedure } from "#lib/trpc/middlewares/publicProcedure";
|
||||
|
||||
export const VerbrauchsausweisWohnen2016Erstellen = publicProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: "POST",
|
||||
path: "/v1/verbrauchsausweis-wohnen/2016/erstellen",
|
||||
contentTypes: ["application/json"],
|
||||
description: "Erstellt einen neuen Verbrauchsausweis für Wohngebäude nach dem Schema der EnEV von 2016.",
|
||||
tags: ["Verbrauchsausweis Wohnen"],
|
||||
}
|
||||
})
|
||||
.input(z.object({
|
||||
baujahr_heizung: z.array(z.number()).optional(),
|
||||
zusaetzliche_heizquelle: z.boolean().optional(),
|
||||
brennstoff_1: z.string().max(50).optional(),
|
||||
einheit_1: z.string().max(50).optional(),
|
||||
brennstoff_2: z.string().max(50).optional(),
|
||||
einheit_2: z.string().max(50).optional(),
|
||||
startdatum: z.coerce.date().optional(),
|
||||
enddatum: z.coerce.date().optional(),
|
||||
verbrauch_1: z.number().optional(),
|
||||
verbrauch_2: z.number().optional(),
|
||||
verbrauch_3: z.number().optional(),
|
||||
verbrauch_4: z.number().optional(),
|
||||
verbrauch_5: z.number().optional(),
|
||||
verbrauch_6: z.number().optional(),
|
||||
warmwasser_enthalten: z.boolean().optional(),
|
||||
warmwasser_anteil_bekannt: z.boolean().optional(),
|
||||
wird_gekuehlt: z.boolean().optional(),
|
||||
keller_beheizt: z.boolean().optional(),
|
||||
alternative_heizung: z.boolean().optional(),
|
||||
alternative_warmwasser: z.boolean().optional(),
|
||||
alternative_lueftung: z.boolean().optional(),
|
||||
alternative_kuehlung: z.boolean().optional(),
|
||||
anteil_warmwasser_1: z.number().optional(),
|
||||
anteil_warmwasser_2: z.number().optional(),
|
||||
|
||||
gebaeude_stammdaten: z.string().uuid().or(z.object({
|
||||
gebaeudetyp: z.string().max(255).optional(), // Adjust max length as needed
|
||||
gebaeudeteil: z.string().max(255).optional(), // Adjust max length as needed
|
||||
baujahr_gebaeude: z.array(z.number()).optional(),
|
||||
baujahr_heizung: z.array(z.number()).optional(),
|
||||
baujahr_klima: z.array(z.number()).optional(),
|
||||
einheiten: z.number().optional(),
|
||||
flaeche: z.number().optional(),
|
||||
saniert: z.boolean().optional(),
|
||||
keller: z.number().optional(),
|
||||
dachgeschoss: z.number().optional(),
|
||||
lueftung: z.string().max(50).optional(), // Adjust max length as needed
|
||||
kuehlung: z.string().max(50).optional(), // Adjust max length as needed
|
||||
leerstand: z.number().optional(),
|
||||
plz: z.string().max(5).optional(), // Adjust max length as needed
|
||||
ort: z.string().max(50).optional(), // Adjust max length as needed
|
||||
adresse: z.string().max(100).optional(), // Adjust max length as needed
|
||||
|
||||
zentralheizung: z.boolean().optional(),
|
||||
solarsystem_warmwasser: z.boolean().optional(),
|
||||
warmwasser_rohre_gedaemmt: z.boolean().optional(),
|
||||
niedertemperatur_kessel: z.boolean().optional(),
|
||||
brennwert_kessel: z.boolean().optional(),
|
||||
heizungsrohre_gedaemmt: z.boolean().optional(),
|
||||
standard_kessel: z.boolean().optional(),
|
||||
waermepumpe: z.boolean().optional(),
|
||||
raum_temperatur_regler: z.boolean().optional(),
|
||||
photovoltaik: z.boolean().optional(),
|
||||
durchlauf_erhitzer: z.boolean().optional(),
|
||||
einzelofen: z.boolean().optional(),
|
||||
zirkulation: z.boolean().optional(),
|
||||
einfach_verglasung: z.boolean().optional(),
|
||||
dreifach_verglasung: z.boolean().optional(),
|
||||
fenster_teilweise_undicht: z.boolean().optional(),
|
||||
doppel_verglasung: z.boolean().optional(),
|
||||
fenster_dicht: z.boolean().optional(),
|
||||
rolllaeden_kaesten_gedaemmt: z.boolean().optional(),
|
||||
isolier_verglasung: z.boolean().optional(),
|
||||
tueren_undicht: z.boolean().optional(),
|
||||
tueren_dicht: z.boolean().optional(),
|
||||
dachgeschoss_gedaemmt: z.boolean().optional(),
|
||||
keller_decke_gedaemmt: z.boolean().optional(),
|
||||
keller_wand_gedaemmt: z.boolean().optional(),
|
||||
aussenwand_gedaemmt: z.boolean().optional(),
|
||||
oberste_geschossdecke_gedaemmt: z.boolean().optional(),
|
||||
aussenwand_min_12cm_gedaemmt: z.boolean().optional(),
|
||||
dachgeschoss_min_12cm_gedaemmt: z.boolean().optional(),
|
||||
oberste_geschossdecke_min_12cm_gedaemmt: z.boolean().optional(),
|
||||
}))
|
||||
}))
|
||||
.output(
|
||||
z.object({
|
||||
uid: z.string().uuid(),
|
||||
})
|
||||
)
|
||||
.mutation(async (opts) => {
|
||||
|
||||
// Es kann sein, dass ein Gebäude bereits existiert. In diesem Fall wird es nicht neu erstellt, sondern nur der Verbrauchsausweis.
|
||||
// Das können wir ganz einfach überprüfen, indem wir schauen, ob eine UUID für das Gebäude übergeben wurde.
|
||||
if (typeof opts.input.gebaeude_stammdaten === "string") {
|
||||
// Gebäude existiert bereits
|
||||
const gebaeude = await prisma.gebaeudeStammdaten.findUnique({
|
||||
where: {
|
||||
uid: opts.input.gebaeude_stammdaten
|
||||
}
|
||||
});
|
||||
|
||||
if (!gebaeude) {
|
||||
throw new Error("Das Gebäude mit der übergebenen UUID existiert nicht.");
|
||||
}
|
||||
|
||||
const verbrauchsausweis = await prisma.verbrauchsausweisWohnen.create({
|
||||
data: {
|
||||
...opts.input,
|
||||
gebaeude_stammdaten: {
|
||||
connect: {
|
||||
uid: opts.input.gebaeude_stammdaten
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { uid: verbrauchsausweis.uid };
|
||||
} else {
|
||||
// Gebäude existiert noch nicht
|
||||
const gebaeude = await prisma.gebaeudeStammdaten.create({
|
||||
data: opts.input.gebaeude_stammdaten
|
||||
});
|
||||
|
||||
const verbrauchsausweis = await prisma.verbrauchsausweisWohnen.create({
|
||||
data: {
|
||||
...opts.input,
|
||||
gebaeude_stammdaten: {
|
||||
connect: {
|
||||
uid: gebaeude.uid
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { uid: verbrauchsausweis.uid };
|
||||
}
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
import type { APIRoute } from "astro";
|
||||
import { MissingEntityError, error } from "src/lib/APIResponse";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
import { xmlVerbrauchsausweisWohnen_2016 } from "#lib/XML/VerbrauchsausweisWohnen/xmlVerbrauchsausweisWohnen_2016";
|
||||
import uuid from "uuid";
|
||||
|
||||
export const get: APIRoute = async ({ url }) => {
|
||||
const body = url.searchParams;
|
||||
const uid = body.get("uid");
|
||||
|
||||
if (!body.has("uid") || !uid) {
|
||||
return error(["Missing 'uid' in request body."]);
|
||||
}
|
||||
|
||||
if (!uuid.validate(uid)) {
|
||||
return error(["'uid' in request body must follow the UUID v4 format."]);
|
||||
}
|
||||
|
||||
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid,
|
||||
},
|
||||
include: {
|
||||
gebaeude_stammdaten: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!ausweis) {
|
||||
return MissingEntityError(uid);
|
||||
}
|
||||
|
||||
const xml = await xmlVerbrauchsausweisWohnen_2016(ausweis);
|
||||
|
||||
const response = new Response(xml, {
|
||||
headers: {
|
||||
"Content-Type": "application/xml",
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
};
|
||||
@@ -63,16 +63,13 @@
|
||||
|
||||
|
||||
async function ausweisAbschicken() {
|
||||
console.log(ausweis);
|
||||
|
||||
overlay.ariaHidden = "false";
|
||||
const response = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
|
||||
...ausweis,
|
||||
gebaeude_stammdaten: gebaeude
|
||||
})
|
||||
|
||||
console.log(response.uid);
|
||||
|
||||
window.location.href = `/kundendaten?uid=${response.uid}`;
|
||||
}
|
||||
|
||||
let overlay: HTMLDivElement;
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
<script lang="ts">
|
||||
import ProgressBar from "#components/Ausweis/Progressbar.svelte";
|
||||
import HelpLabel from "#components/HelpLabel.svelte";
|
||||
import ZipSearch from "../ZIPSearch.svelte";
|
||||
import Label from "../Label.svelte";
|
||||
import ZipSearch from "../components/ZIPSearch.svelte";
|
||||
import Label from "../components/Label.svelte";
|
||||
import PriceContainer from "#components/Kaufabschluss/PriceContainer.svelte";
|
||||
import { Benutzer, Bezahlmethoden, Enums, Rechnungen, VerbrauchsausweisWohnen } from "@ibcornelsen/database";
|
||||
import PaymentOption from "#components/PaymentOption.svelte";
|
||||
|
||||
let deliveryAddress: boolean = false;
|
||||
export let user: Benutzer;
|
||||
export let ausweis: VerbrauchsausweisWohnen
|
||||
let rechnung: Rechnungen = {} as Rechnungen;
|
||||
|
||||
let mailAddressCity: string = "";
|
||||
let mailAddressZipCode: string = "";
|
||||
|
||||
let invoiceAddressCity: string = "";
|
||||
let invoiceAddressZipCode: string = "";
|
||||
|
||||
export let paymentType:
|
||||
| "paypal"
|
||||
| "kreditkarte"
|
||||
| "giropay"
|
||||
| "sofort"
|
||||
| "rechnung"
|
||||
| "sepa" = "paypal";
|
||||
export let selectedPaymentType: Bezahlmethoden = Enums.Bezahlmethoden.PAYPAL;
|
||||
|
||||
let agbAkzeptiert: boolean;
|
||||
let datenschutzAkzeptiert: boolean;
|
||||
@@ -33,24 +25,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form
|
||||
method="post"
|
||||
target="_self"
|
||||
novalidate
|
||||
<div
|
||||
class="w-full"
|
||||
action="/kaufabschluss"
|
||||
>
|
||||
<fieldset class="flex flex-row gap-8">
|
||||
<div class="flex flex-row gap-8">
|
||||
<div class="w-3/5">
|
||||
<div class="GRB3">
|
||||
<HelpLabel title="Ansprechpartner" />
|
||||
<hr />
|
||||
<div class="grid grid-cols-5 gap-4">
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<!-- Anrede -->
|
||||
<div>
|
||||
<Label>Anrede *</Label>
|
||||
<div>
|
||||
<select name="Aanrede" class="">
|
||||
<select name="anrede" bind:value={user.anrede}>
|
||||
<option>bitte auswählen</option>
|
||||
<option value="Herr">Herr</option>
|
||||
<option value="Frau">Frau</option>
|
||||
@@ -61,25 +49,26 @@
|
||||
<!-- Vorname -->
|
||||
<div>
|
||||
<Label>Vorname *</Label>
|
||||
<input name="Avorname" type="text" required />
|
||||
<input name="vorname" type="text" bind:value={user.vorname} required />
|
||||
</div>
|
||||
|
||||
<!-- Nachname -->
|
||||
<div>
|
||||
<Label>Nachname *</Label>
|
||||
<input name="Anachname" type="text" required />
|
||||
<input name="nachname" type="text" bind:value={user.name} required />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- Telefon -->
|
||||
<div>
|
||||
<Label>Telefon</Label>
|
||||
<input name="Atelefon" class="" type="text" />
|
||||
<input name="telefon" bind:value={user.telefon} type="text" />
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div>
|
||||
<Label>E-Mail *</Label>
|
||||
<input name="Aemail" type="email" required />
|
||||
<input name="email" type="email" bind:value={user.email} required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,12 +80,13 @@
|
||||
<hr />
|
||||
<!-- Empfänger -->
|
||||
|
||||
<div class="grid grid-cols-5 gap-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label>Empfänger *</Label>
|
||||
<input
|
||||
name="Rempfaenger"
|
||||
type="text"
|
||||
bind:value={rechnung.empfaenger}
|
||||
required
|
||||
data-rule-maxlength="100"
|
||||
data-msg-maxlength="max. 100 Zeichen"
|
||||
@@ -113,12 +103,14 @@
|
||||
data-msg-maxlength="max. 80 Zeichen"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<!-- Strasse -->
|
||||
<div>
|
||||
<Label>Straße, Hausnummer *</Label>
|
||||
<input
|
||||
name="Rstrasse"
|
||||
bind:value={rechnung.strasse}
|
||||
type="text"
|
||||
required
|
||||
data-rule-maxlength="40"
|
||||
@@ -128,33 +120,34 @@
|
||||
|
||||
<!-- PLZ -->
|
||||
<ZipSearch
|
||||
name="vplz"
|
||||
bind:zip={invoiceAddressZipCode}
|
||||
bind:city={invoiceAddressCity}
|
||||
name="versand_plz"
|
||||
bind:zip={rechnung.plz}
|
||||
bind:city={rechnung.ort}
|
||||
/>
|
||||
|
||||
<!-- Ort -->
|
||||
<div>
|
||||
<Label>Ort *</Label>
|
||||
<input
|
||||
name="Rort"
|
||||
name="rechnung_ort"
|
||||
readonly
|
||||
type="text"
|
||||
required
|
||||
value={invoiceAddressCity}
|
||||
value={rechnung.ort}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- Telefon -->
|
||||
<div>
|
||||
<Label>Telefon</Label>
|
||||
<input name="Rtelefon" class="" type="text" />
|
||||
<input name="Rtelefon" bind:value={rechnung.telefon} type="text" />
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div>
|
||||
<Label>E-Mail</Label>
|
||||
<input name="Remail" type="email" />
|
||||
<input name="Remail" bind:value={rechnung.email} type="email" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -164,24 +157,24 @@
|
||||
<div class="GRB3">
|
||||
<HelpLabel title="Versandadresse" />
|
||||
<hr />
|
||||
<div class="grid grid-cols-5 gap-4">
|
||||
<div class="flex flex-row gap-2 items-center">
|
||||
<input
|
||||
class="w-[15px] h-[15px]"
|
||||
type="checkbox"
|
||||
id="deliveryAddress"
|
||||
bind:checked={deliveryAddress}
|
||||
bind:checked={rechnung.abweichende_versand_adresse}
|
||||
/>
|
||||
<Label>Abweichende Versandadresse</Label>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- Empfänger -->
|
||||
<div>
|
||||
<Label>Empfänger *</Label>
|
||||
<input
|
||||
name="Vempfaenger"
|
||||
type="text"
|
||||
readonly={!deliveryAddress}
|
||||
readonly={!rechnung.abweichende_versand_adresse}
|
||||
bind:value={rechnung.versand_empfaenger}
|
||||
required
|
||||
data-rule-maxlength="100"
|
||||
data-msg-maxlength="max. 100 Zeichen"
|
||||
@@ -194,19 +187,22 @@
|
||||
<input
|
||||
name="Vzusatzzeile"
|
||||
type="text"
|
||||
readonly={!deliveryAddress}
|
||||
readonly={!rechnung.abweichende_versand_adresse}
|
||||
bind:value={rechnung.versand_zusatzzeile}
|
||||
data-rule-maxlength="80"
|
||||
data-msg-maxlength="max. 80 Zeichen"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<!-- Strasse -->
|
||||
<div>
|
||||
<Label>Straße, Hausnummer *</Label>
|
||||
<input
|
||||
name="Vstrasse"
|
||||
type="text"
|
||||
readonly={!deliveryAddress}
|
||||
readonly={!rechnung.abweichende_versand_adresse}
|
||||
bind:value={rechnung.strasse}
|
||||
required
|
||||
data-rule-maxlength="40"
|
||||
data-msg-maxlength="max. 40 Zeichen"
|
||||
@@ -216,9 +212,9 @@
|
||||
<!-- PLZ -->
|
||||
<ZipSearch
|
||||
name="rplz"
|
||||
readonly={!deliveryAddress}
|
||||
bind:zip={mailAddressZipCode}
|
||||
bind:city={mailAddressCity}
|
||||
readonly={!rechnung.abweichende_versand_adresse}
|
||||
bind:zip={rechnung.versand_plz}
|
||||
bind:city={rechnung.versand_ort}
|
||||
/>
|
||||
|
||||
<!-- Ort -->
|
||||
@@ -229,7 +225,7 @@
|
||||
type="text"
|
||||
readonly
|
||||
required
|
||||
value={mailAddressCity}
|
||||
bind:value={rechnung.versand_ort}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -237,96 +233,28 @@
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="yellow-box">
|
||||
<h4>Bitte wählen sie ihre Bezahlmethode aus.</h4>
|
||||
<div class="flex flex-row gap-4">
|
||||
<div class="w-1/2">
|
||||
<div>
|
||||
<div class="payment-option-card">
|
||||
<img
|
||||
src="/images/paypal.png"
|
||||
alt="PayPal"
|
||||
/>
|
||||
<div
|
||||
class="payment-option-label"
|
||||
aria-label="Zahlen mit PayPal"
|
||||
>
|
||||
Zahlen mit PayPal
|
||||
</div>
|
||||
</div>
|
||||
<div class="payment-option-card">
|
||||
<img
|
||||
src="/images/giropay.png"
|
||||
alt="Giropay"
|
||||
/>
|
||||
<div
|
||||
class="payment-option-label"
|
||||
aria-label="Zahlen mit Giropay"
|
||||
>
|
||||
Zahlen mit Giropay
|
||||
</div>
|
||||
</div>
|
||||
<div class="payment-option-card">
|
||||
<img
|
||||
src="/images/sofort.png"
|
||||
alt="Sofort"
|
||||
/>
|
||||
<div
|
||||
class="payment-option-label"
|
||||
aria-label="Zahlen mit Sofort"
|
||||
>
|
||||
Zahlen mit Sofort
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="payment-option-card">
|
||||
<img
|
||||
src="/images/mastercard.png"
|
||||
alt="Mastercard"
|
||||
/>
|
||||
<div
|
||||
class="payment-option-label"
|
||||
aria-label="Zahlen mit Kreditkarte"
|
||||
>
|
||||
Zahlen mit Kreditkarte
|
||||
</div>
|
||||
</div>
|
||||
<div class="payment-option-card">
|
||||
<img
|
||||
src="/images/rechnung.png"
|
||||
alt="Rechnung"
|
||||
/>
|
||||
<div
|
||||
class="payment-option-label"
|
||||
aria-label="Zahlen mit Rechnung"
|
||||
>
|
||||
Zahlen mit Rechnung
|
||||
</div>
|
||||
</div>
|
||||
<div class="payment-option-card">
|
||||
<img src="/images/sepa.png" alt="SEPA" />
|
||||
<div
|
||||
class="payment-option-label"
|
||||
aria-label="Zahlen mit SEPA über PayPal"
|
||||
>
|
||||
SEPA über PayPal
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="GRB3">
|
||||
<HelpLabel title="Bezahlmethode" />
|
||||
<hr />
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<PaymentOption paymentType={Enums.Bezahlmethoden.PAYPAL} bind:selectedPaymentType name={"PayPal"} icon={"/images/paypal.png"}></PaymentOption>
|
||||
<PaymentOption paymentType={Enums.Bezahlmethoden.SOFORT} bind:selectedPaymentType name={"Sofort"} icon={"/images/sofort.png"}></PaymentOption>
|
||||
<PaymentOption paymentType={Enums.Bezahlmethoden.GIROPAY} bind:selectedPaymentType name={"Giropay"} icon={"/images/giropay.png"}></PaymentOption>
|
||||
<PaymentOption paymentType={Enums.Bezahlmethoden.KREDITKARTE} bind:selectedPaymentType name={"Kreditkarte"} icon={"/images/mastercard.png"}></PaymentOption>
|
||||
<PaymentOption paymentType={Enums.Bezahlmethoden.RECHNUNG} bind:selectedPaymentType name={"Rechnung"} icon={"/images/rechnung.png"}></PaymentOption>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="flex-row justify-between">
|
||||
<h5>{paymentType}</h5>
|
||||
<h5>{selectedPaymentType}</h5>
|
||||
<img
|
||||
src="../../images/{paymentType ==
|
||||
'kreditkarte'
|
||||
src="../../images/{selectedPaymentType ==
|
||||
Enums.Bezahlmethoden.KREDITKARTE
|
||||
? 'mastercard'
|
||||
: paymentType}.png"
|
||||
: selectedPaymentType}.png"
|
||||
class="payment-option-logo"
|
||||
/>
|
||||
</div>
|
||||
{#if paymentType == "rechnung"}
|
||||
{#if selectedPaymentType == Enums.Bezahlmethoden.RECHNUNG}
|
||||
<p>
|
||||
Sobald sie AGB und Datenschutzerklärung
|
||||
gelesen und akzeptiert haben können sie den
|
||||
@@ -342,7 +270,7 @@
|
||||
gelesen und akzeptiert haben können sie den
|
||||
Kauf fortsetzen. Durch das Klicken auf
|
||||
'Kostenpflichtig Bestellen' werden sie zu <strong
|
||||
>{paymentType}</strong
|
||||
>{selectedPaymentType}</strong
|
||||
> weitergeleitet.
|
||||
</p>
|
||||
{/if}
|
||||
@@ -379,7 +307,6 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
@@ -390,8 +317,8 @@
|
||||
<div class="w-2/5">
|
||||
<PriceContainer prices={[45, 60, 160]} />
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -7,12 +7,20 @@
|
||||
let passwort: string;
|
||||
|
||||
async function login() {
|
||||
const response = await client.v1.benutzer.tokenErneuern.query({
|
||||
try {
|
||||
const response = await client.v1.benutzer.getRefreshToken.query({
|
||||
email,
|
||||
passwort
|
||||
})
|
||||
|
||||
if (!response.token || !response.exp) {
|
||||
const options = {
|
||||
domain: `.${window.location.hostname}`,
|
||||
path: "/",
|
||||
expires: response.exp
|
||||
}
|
||||
Cookies.set("accessToken", response.accessToken, options);
|
||||
Cookies.set("refreshToken", response.refreshToken, options);
|
||||
window.location.href = "/user";
|
||||
} catch (e) {
|
||||
addNotification({
|
||||
message: "Ups...",
|
||||
subtext: "Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?",
|
||||
@@ -20,16 +28,7 @@
|
||||
timeout: 6000,
|
||||
dismissable: true
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
domain: `.${window.location.hostname}`,
|
||||
path: "/",
|
||||
expires: response.exp
|
||||
}
|
||||
Cookies.set("token", response.token, options);
|
||||
window.location.href = "/user";
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { addNotification } from "@ibcornelsen/ui";
|
||||
import Cookies from "js-cookie";
|
||||
import {client} from "src/trpc";
|
||||
|
||||
let passwort: string;
|
||||
@@ -9,22 +8,15 @@
|
||||
let name: string;
|
||||
|
||||
async function login() {
|
||||
try {
|
||||
const response = await client.v1.benutzer.erstellen.query({
|
||||
email,
|
||||
passwort,
|
||||
vorname,
|
||||
name
|
||||
})
|
||||
|
||||
if (response.token) {
|
||||
const options = {
|
||||
domain: `.${window.location.hostname}`,
|
||||
path: "/",
|
||||
expires: response.exp
|
||||
}
|
||||
Cookies.set("token", response.token, options);
|
||||
window.location.href = "/login";
|
||||
} else {
|
||||
} catch (e) {
|
||||
addNotification({
|
||||
message: "Ups...",
|
||||
subtext: "Da ist wohl etwas schiefgelaufen... Diese Email Adresse ist bereits in Benutzung, haben sie vielleicht bereits ein Konto bei uns?",
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// NOTE: Öffentliche API benötigt OpenApiMeta. Das Package bräuchte momentan noch einen extra Server, deshalb nehmen wir es momentan noch nicht mit rein.
|
||||
//import { OpenApiMeta } from "trpc-openapi";
|
||||
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
|
||||
import { APIRoute } from "astro";
|
||||
import { t } from "../../lib/trpc/context";
|
||||
import { v1Router } from "#lib/trpc/procedures/v1";
|
||||
|
||||
export const appRouter = t.router({
|
||||
v1: v1Router,
|
||||
});
|
||||
|
||||
export const all: APIRoute = ({ request }) => {
|
||||
return fetchRequestHandler({
|
||||
req: request,
|
||||
endpoint: "/api",
|
||||
router: appRouter,
|
||||
createContext: async ({ req }) => {
|
||||
const ip = req.headers.get("x-forwarded-for");
|
||||
const authorization = req.headers.get("authorization") || null;
|
||||
|
||||
return {
|
||||
authorization,
|
||||
ip: ip?.toString() || "",
|
||||
req: req,
|
||||
};
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export function tRPCCaller(request: Request) {
|
||||
const { authorization } = {
|
||||
authorization: request.headers.get("authorization") || "",
|
||||
};
|
||||
const createCaller = t.createCallerFactory(appRouter);
|
||||
return createCaller({
|
||||
authorization,
|
||||
req: request,
|
||||
ip: request.headers.get("x-forwarded-for") || "",
|
||||
});
|
||||
}
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
@@ -1,46 +0,0 @@
|
||||
import type { APIRoute } from "astro";
|
||||
import {
|
||||
MissingEntityError,
|
||||
error,
|
||||
} from "src/lib/APIResponse";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
|
||||
export const get: APIRoute = async ({ url }) => {
|
||||
const body = url.searchParams
|
||||
const uid = body.get("uid")
|
||||
|
||||
if (!body.has("uid") || !uid) {
|
||||
return error(["Missing 'uid' in request body."])
|
||||
}
|
||||
|
||||
const image = await prisma.gebaeudeBilder.findUnique({
|
||||
where: {
|
||||
uid
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
kategorie: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!image) {
|
||||
return MissingEntityError("image")
|
||||
}
|
||||
|
||||
// Check if the image exists on disk
|
||||
const location = path.join("/persistent/uploads/images", `${image.uid}.jpg`);
|
||||
|
||||
if (!fs.existsSync(location)) {
|
||||
return MissingEntityError("image")
|
||||
}
|
||||
|
||||
const data = fs.readFileSync(location);
|
||||
|
||||
return new Response(data, {
|
||||
headers: {
|
||||
"Content-Type": "image/jpeg"
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,131 +0,0 @@
|
||||
import type { APIRoute } from "astro";
|
||||
import {
|
||||
ActionFailedError,
|
||||
MissingEntityError,
|
||||
error,
|
||||
success,
|
||||
} from "src/lib/APIResponse";
|
||||
import * as jimp from "jimp";
|
||||
import { z } from "zod";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import { prisma } from "@ibcornelsen/database";
|
||||
|
||||
const ImageUploadChecker = z.object({
|
||||
data: z.string(),
|
||||
name: z.string(),
|
||||
gebaeude_uid: z.string().optional(),
|
||||
kategorie: z.string(),
|
||||
});
|
||||
|
||||
export const get: APIRoute = async ({ url }) => {
|
||||
const body = url.searchParams
|
||||
const uid = body.get("uid")
|
||||
|
||||
if (!body.has("uid") || !uid) {
|
||||
return error(["Missing 'uid' in request body."])
|
||||
}
|
||||
|
||||
const image = await prisma.gebaeudeBilder.findUnique({
|
||||
where: {
|
||||
uid
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
kategorie: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!image) {
|
||||
return MissingEntityError("image")
|
||||
}
|
||||
|
||||
// Check if the image exists on disk
|
||||
const location = path.join("/persistent/uploads/images", `${image.uid}.jpg`);
|
||||
|
||||
if (!fs.existsSync(location)) {
|
||||
return MissingEntityError("image")
|
||||
}
|
||||
|
||||
const data = fs.readFileSync(location, { encoding: "base64" });
|
||||
|
||||
return success(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Speichert ein Bild auf unserem Server ab und gibt die UID des Bildes zurück
|
||||
* @param param0
|
||||
* @returns
|
||||
*/
|
||||
export const put: APIRoute = async ({ request }) => {
|
||||
const body: z.infer<typeof ImageUploadChecker> = await request.json();
|
||||
|
||||
const validation = ImageUploadChecker.safeParse(body);
|
||||
|
||||
if (!validation.success) {
|
||||
return error(validation.error.issues);
|
||||
}
|
||||
|
||||
const image = Buffer.from(body.data, "base64url");
|
||||
|
||||
let jimpResult;
|
||||
try {
|
||||
jimpResult = await jimp.read(image);
|
||||
} catch (e) {
|
||||
return ActionFailedError();
|
||||
}
|
||||
|
||||
let gebaeude;
|
||||
if (!body.gebaeude_uid) {
|
||||
gebaeude = await prisma.gebaeudeStammdaten.create({
|
||||
data: {},
|
||||
select: {
|
||||
uid: true,
|
||||
id: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!gebaeude) {
|
||||
return ActionFailedError();
|
||||
}
|
||||
} else {
|
||||
gebaeude = await prisma.gebaeudeStammdaten.findUnique({
|
||||
where: {
|
||||
uid: body.gebaeude_uid
|
||||
}
|
||||
})
|
||||
|
||||
if (!gebaeude) {
|
||||
return MissingEntityError("gebaeude");
|
||||
}
|
||||
}
|
||||
|
||||
const result = await prisma.gebaeudeBilder.create({
|
||||
data: {
|
||||
gebaeude_stammdaten_id: gebaeude.id,
|
||||
kategorie: body.kategorie
|
||||
},
|
||||
select: {
|
||||
uid: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!result) {
|
||||
return ActionFailedError();
|
||||
}
|
||||
|
||||
const location = path.join("/persistent/uploads", `${result.uid}.jpg`);
|
||||
|
||||
const buffer = await jimpResult.getBufferAsync(jimp.MIME_JPEG)
|
||||
|
||||
if (buffer.length > 3_000_000) {
|
||||
jimpResult.quality(75).write(location);
|
||||
} else {
|
||||
jimpResult.write(location);
|
||||
}
|
||||
|
||||
return success({
|
||||
uid: result.uid,
|
||||
gebaeude_uid: gebaeude.uid,
|
||||
});
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||
import BedarfsausweisContent from "#components/Bedarfsausweis/BedarfsausweisContent.svelte";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
---
|
||||
<AusweisLayout title="Bedarfsausweis erstellen | IBCornelsen">
|
||||
<BedarfsausweisContent client:load></BedarfsausweisContent>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import Layout from "#layouts/Layout.astro";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
---
|
||||
|
||||
<Layout title="Für Entwickler - IBCornelsen">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import Layout from "#layouts/Layout.astro";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
---
|
||||
|
||||
<Layout title="FAQ - IBCornelsen"></Layout>
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import { BoxWithHeading } from "@ibcornelsen/ui";
|
||||
import Widget from "#components/Widget.svelte";
|
||||
import Layout from "#layouts/Layout.astro";
|
||||
import FeatureCard from "#components/FeatureCard.svelte";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
---
|
||||
|
||||
<Layout title="Energieausweis online erstellen - Online Energieausweis">
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
import Kaufabschluss from "#components/Kaufabschluss/Kaufabschluss.svelte";
|
||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||
|
||||
changeLanguage("de");
|
||||
---
|
||||
|
||||
<AusweisLayout title="Kaufabschluss Verbrauchsausweis - IBCornelsen">
|
||||
<Kaufabschluss client:load></Kaufabschluss>
|
||||
</AusweisLayout>
|
||||
@@ -1,12 +1,40 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
import Kundendaten from "#components/Ausweis/Kundendaten.svelte";
|
||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||
|
||||
changeLanguage("de");
|
||||
import KundendatenModule from "#modules/KundendatenModule.svelte";
|
||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||
import { Benutzer, Enums, prisma } from "@ibcornelsen/database";
|
||||
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
where: {
|
||||
id: 1,
|
||||
},
|
||||
}) as Benutzer;
|
||||
|
||||
// Man sollte nur auf diese Seite kommen, wenn ein Ausweis bereits vorliegt und in der Datenbank abgespeichert wurde.
|
||||
const uid = Astro.url.searchParams.get("uid");
|
||||
|
||||
if (!uid) {
|
||||
return Astro.redirect("/");
|
||||
}
|
||||
|
||||
// NOTE: Muss umgestellt werden, wir brauchen einen Kundendaten Abschluss für jede Ausweisart.
|
||||
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid,
|
||||
},
|
||||
});
|
||||
|
||||
if (!ausweis) {
|
||||
return Astro.redirect("/");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<AusweisLayout title="Kundendaten Aufnehmen - IBCornelsen">
|
||||
<Kundendaten client:load></Kundendaten>
|
||||
<KundendatenModule user={user} ausweis={ausweis} selectedPaymentType={Enums.Bezahlmethoden.PAYPAL} client:load></KundendatenModule>
|
||||
</AusweisLayout>
|
||||
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
import moment from "moment";
|
||||
import LoginModule from "../modules/LoginModule.svelte";
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
|
||||
const token = Astro.cookies.get("token").value;
|
||||
const expires = Astro.cookies.get("expires").number();
|
||||
const now = moment().unix();
|
||||
if (token && now < expires) {
|
||||
return Astro.redirect(`/user`);
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title="Login">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
|
||||
|
||||
Astro.cookies.delete("token");
|
||||
Astro.cookies.delete("expires");
|
||||
|
||||
@@ -1,23 +1,42 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import moment from "moment";
|
||||
import { Ausweis } from "src/lib/Ausweis";
|
||||
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
||||
import Checkbox from "#components/Checkbox.svelte";
|
||||
import PDFHeader from "#components/PDF/PDFHeader.svelte";
|
||||
import PDFSectionHeader from "#components/PDF/PDFSectionHeader.svelte";
|
||||
import PDFLayout from "#layouts/PDFLayout.astro";
|
||||
import { VerbrauchsausweisWohnen, GebaeudeStammdaten, prisma } from "@ibcornelsen/database";
|
||||
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
const base64 = Astro.url.searchParams.get("base64");
|
||||
if (!base64) {
|
||||
let ausweis: (Partial<VerbrauchsausweisWohnen> & { gebaeude_stammdaten: Partial<GebaeudeStammdaten> }) | null = null;
|
||||
if (base64) {
|
||||
const buffer = Buffer.from(base64, "base64");
|
||||
const json = buffer.toString("utf-8");
|
||||
ausweis = JSON.parse(json);
|
||||
} else {
|
||||
const uidAusweis = Astro.url.searchParams.get("ausweis_uid");
|
||||
|
||||
if (!uidAusweis) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
const ausweis = Verbrauchsausweis.fromBase64(base64);
|
||||
|
||||
ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid: uidAusweis,
|
||||
},
|
||||
include: {
|
||||
gebaeude_stammdaten: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!ausweis) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
|
||||
const gebaeude = ausweis.gebaeude_stammdaten;
|
||||
---
|
||||
|
||||
<PDFLayout title="Ansichtsausweis">
|
||||
@@ -45,30 +64,30 @@ if (!ausweis) {
|
||||
<table>
|
||||
<tr>
|
||||
<td>Gebäudetyp</td>
|
||||
<td>{ausweis.objekt_typ}</td>
|
||||
<td>{gebaeude.gebaeudetyp}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Adresse</td>
|
||||
<td>{ausweis.objekt_strasse}</td>
|
||||
<td>{gebaeude.adresse}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gebäudeteil</td>
|
||||
<td>{ausweis.objekt_gebaeudeteil}</td>
|
||||
<td>{gebaeude.gebaeudeteil}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Baujahr Gebäude ³</td>
|
||||
<td>{ausweis.baujahr_gebaeude}</td>
|
||||
<td>{gebaeude.baujahr_gebaeude}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
>Baujahr Wärmeerzeuger <sup>3</sup>
|
||||
<sup>4</sup></td
|
||||
>
|
||||
<td>{ausweis.baujahr_anlage}</td>
|
||||
<td>{gebaeude.baujahr_heizung}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Anzahl Wohnungen</td>
|
||||
<td>{ausweis.anzahl_einheiten}</td>
|
||||
<td>{gebaeude.einheiten}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gebäudenutzfläche (A<sub>N</sub>)</td>
|
||||
|
||||
@@ -1,79 +1,136 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
import moment from "moment";
|
||||
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
||||
import { Dachgeschoss } from "src/lib/Ausweis/types";
|
||||
import Checkbox from "#components/Checkbox.svelte";
|
||||
import DatenblattFooter from "#components/DatenblattFooter.svelte";
|
||||
import DatenblattHeader from "#components/DatenblattHeader.svelte";
|
||||
import PDFHeader from "#components/PDF/PDFHeader.svelte";
|
||||
import PDFSectionHeader from "#components/PDF/PDFSectionHeader.svelte";
|
||||
import PDFLayout from "#layouts/PDFLayout.astro";
|
||||
|
||||
changeLanguage("de");
|
||||
import { GebaeudeStammdaten, VerbrauchsausweisWohnen, prisma } from "@ibcornelsen/database";
|
||||
|
||||
const base64 = Astro.url.searchParams.get("base64");
|
||||
if (!base64) {
|
||||
let ausweis: (Partial<VerbrauchsausweisWohnen> & { gebaeude_stammdaten: Partial<GebaeudeStammdaten> }) | null = null;
|
||||
if (base64) {
|
||||
const buffer = Buffer.from(base64, "base64");
|
||||
const json = buffer.toString("utf-8");
|
||||
ausweis = JSON.parse(json);
|
||||
} else {
|
||||
const uidAusweis = Astro.url.searchParams.get("ausweis_uid");
|
||||
|
||||
if (!uidAusweis) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
const ausweis = Verbrauchsausweis.fromBase64(base64);
|
||||
|
||||
ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid: uidAusweis,
|
||||
},
|
||||
include: {
|
||||
gebaeude_stammdaten: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!ausweis) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
|
||||
const gebaeude = ausweis.gebaeude_stammdaten;
|
||||
---
|
||||
|
||||
<PDFLayout title="Datenblatt">
|
||||
<div class="flex flex-col gap-20">
|
||||
<div class="flex flex-col gap-4">
|
||||
<DatenblattHeader></DatenblattHeader>
|
||||
<DatenblattHeader />
|
||||
<div class="px-12 py-20 flex flex-col gap-2">
|
||||
<div class="flex flex-row justify-between items-center">
|
||||
<h2>Datenblatt Energieausweis</h2>
|
||||
<h2>Ausweis ID:</h2>
|
||||
</div>
|
||||
<h3>Gebäudedaten:</h3>
|
||||
<p>Adresse: {ausweis.objekt_strasse}, {ausweis.objekt_plz} {ausweis.objekt_ort}</p>
|
||||
<p>
|
||||
Adresse: {gebaeude.adresse}, {
|
||||
gebaeude.plz
|
||||
}
|
||||
{gebaeude.ort}
|
||||
</p>
|
||||
<div class="flex justify-between">
|
||||
<Checkbox checked={ausweis.ausstellgrund == "Neubau"}>Neubau</Checkbox>
|
||||
<Checkbox checked={ausweis.ausstellgrund == "Vermietung" || ausweis.ausstellgrund == "Verkauf"}>Vermietung/Verkauf</Checkbox>
|
||||
<Checkbox checked={ausweis.ausstellgrund == "Modernisierung"}>Modernisierung</Checkbox>
|
||||
<Checkbox checked={ausweis.ausstellgrund == "Sonstiges"}>Sonstiges</Checkbox>
|
||||
<Checkbox checked={ausweis.ausstellgrund == "Neubau"}>
|
||||
Neubau
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={ausweis.ausstellgrund == "Vermietung" ||
|
||||
ausweis.ausstellgrund == "Verkauf"}
|
||||
>
|
||||
Vermietung/Verkauf
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={ausweis.ausstellgrund == "Modernisierung"}
|
||||
>
|
||||
Modernisierung
|
||||
</Checkbox>
|
||||
<Checkbox checked={ausweis.ausstellgrund == "Sonstiges"}>
|
||||
Sonstiges
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div class="flex justify-between gap-4">
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<tbody
|
||||
><tr>
|
||||
<td>Baujahr Gebäude:</td>
|
||||
<td>{ausweis.baujahr_gebaeude}</td>
|
||||
<td
|
||||
>{
|
||||
gebaeude.baujahr_gebaeude
|
||||
}</td
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Baujahr Heizung:</td>
|
||||
<td>{ausweis.baujahr_anlage}</td>
|
||||
<td
|
||||
>{
|
||||
gebaeude.baujahr_heizung
|
||||
}</td
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wohnfläche:</td>
|
||||
<td>{ausweis.wohnflaeche}</td>
|
||||
<td>{gebaeude.flaeche}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lüftungskonzept:</td>
|
||||
<td>{ausweis.lueftungskonzept}</td>
|
||||
<td>{gebaeude.lueftung}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gebäudetyp:</td>
|
||||
<td>{ausweis.objekt_typ}</td>
|
||||
</tr></tbody>
|
||||
<td
|
||||
>{
|
||||
gebaeude.gebaeudetyp
|
||||
}</td
|
||||
>
|
||||
</tr></tbody
|
||||
>
|
||||
</table>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<tbody
|
||||
><tr>
|
||||
<td>Dachgeschoss:</td>
|
||||
<td>{ausweis.dachgeschoss == Dachgeschoss.BEHEIZT ? "Beheizt" : (ausweis.dachgeschoss == Dachgeschoss.UNBEHEIZT ? "Unbeheizt" : "Nicht Vorhanden")}</td>
|
||||
<td
|
||||
>{
|
||||
gebaeude.dachgeschoss
|
||||
? "Beheizt"
|
||||
: gebaeude
|
||||
.dachgeschoss
|
||||
? "Unbeheizt"
|
||||
: "Nicht Vorhanden"
|
||||
}</td
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beheizter Keller:</td>
|
||||
<td>{ausweis.keller_beheizt ? "Ja" : "Nein"}</td>
|
||||
<td>{ausweis.keller_beheizt ? "Ja" : "Nein"}</td
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wohnungen:</td>
|
||||
<td>{ausweis.anzahl_einheiten}</td>
|
||||
<td>{gebaeude.einheiten}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Anlage zur Kühlung:</td>
|
||||
@@ -81,40 +138,75 @@ if (!ausweis) {
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Leerstand:</td>
|
||||
<td>{ausweis.leerstand}%</td>
|
||||
</tr></tbody>
|
||||
|
||||
<td>{gebaeude.leerstand}%</td
|
||||
>
|
||||
</tr></tbody
|
||||
>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex flex-row gap-8">
|
||||
<div class="flex flex-col">
|
||||
<h2>Heizverbrauch</h2>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>Von: {moment(ausweis.energieverbrauch_zeitraum).format("MM.YYYY")}</p>
|
||||
<p>Bis: {moment(ausweis.energieverbrauch_zeitraum).add("1", "year").format("MM.YYYY")}</p>
|
||||
<p>
|
||||
Von: {
|
||||
moment(ausweis.startdatum).format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
Bis: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("1", "year")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>Von: {moment(ausweis.energieverbrauch_zeitraum).add("1", "year").format("MM.YYYY")}</p>
|
||||
<p>Bis: {moment(ausweis.energieverbrauch_zeitraum).add("2", "years").format("MM.YYYY")}</p>
|
||||
<p>
|
||||
Von: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("1", "year")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
Bis: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("2", "years")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>Von: {moment(ausweis.energieverbrauch_zeitraum).add("2", "years").format("MM.YYYY")}</p>
|
||||
<p>Bis: {moment(ausweis.energieverbrauch_zeitraum).add("3", "years").format("MM.YYYY")}</p>
|
||||
<p>
|
||||
Von: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("2", "years")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
Bis: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("3", "years")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h2>{ausweis.energietraeger_1}</h2>
|
||||
<h2>{ausweis.brennstoff_1}</h2>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>{ausweis.energieverbrauch_1_heizquelle_1}</p>
|
||||
<p>{ausweis.energietraeger_einheit_heizquelle_1}</p>
|
||||
<p>{ausweis.verbrauch_1}</p>
|
||||
<p>{ausweis.einheit_1}</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>{ausweis.energieverbrauch_2_heizquelle_1}</p>
|
||||
<p>{ausweis.energietraeger_einheit_heizquelle_1}</p>
|
||||
<p>{ausweis.verbrauch_2}</p>
|
||||
<p>{ausweis.einheit_1}</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>{ausweis.energieverbrauch_3_heizquelle_1}</p>
|
||||
<p>{ausweis.energietraeger_einheit_heizquelle_1}</p>
|
||||
<p>{ausweis.verbrauch_3}</p>
|
||||
<p>{ausweis.einheit_1}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -122,85 +214,266 @@ if (!ausweis) {
|
||||
<div class="flex flex-col">
|
||||
<h2>Heizverbrauch (Heizwert)</h2>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>Von: {moment(ausweis.energieverbrauch_zeitraum).format("MM.YYYY")}</p>
|
||||
<p>Bis: {moment(ausweis.energieverbrauch_zeitraum).add("1", "year").format("MM.YYYY")}</p>
|
||||
<p>
|
||||
Von: {
|
||||
moment(ausweis.startdatum).format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
Bis: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("1", "year")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>Von: {moment(ausweis.energieverbrauch_zeitraum).add("1", "year").format("MM.YYYY")}</p>
|
||||
<p>Bis: {moment(ausweis.energieverbrauch_zeitraum).add("2", "years").format("MM.YYYY")}</p>
|
||||
<p>
|
||||
Von: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("1", "year")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
Bis: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("2", "years")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>Von: {moment(ausweis.energieverbrauch_zeitraum).add("2", "years").format("MM.YYYY")}</p>
|
||||
<p>Bis: {moment(ausweis.energieverbrauch_zeitraum).add("3", "years").format("MM.YYYY")}</p>
|
||||
<p>
|
||||
Von: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("2", "years")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
Bis: {
|
||||
moment(ausweis.startdatum)
|
||||
.add("3", "years")
|
||||
.format("MM.YYYY")
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h2>{ausweis.energietraeger_1}</h2>
|
||||
<h2>{ausweis.brennstoff_1}</h2>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>{ausweis.energieverbrauch_1_heizquelle_1}</p>
|
||||
<p>{ausweis.energietraeger_einheit_heizquelle_1}</p>
|
||||
<p>{ausweis.verbrauch_1}</p>
|
||||
<p>{ausweis.einheit_1}</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>{ausweis.energieverbrauch_2_heizquelle_1}</p>
|
||||
<p>{ausweis.energietraeger_einheit_heizquelle_1}</p>
|
||||
<p>{ausweis.verbrauch_2}</p>
|
||||
<p>{ausweis.einheit_1}</p>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-4">
|
||||
<p>{ausweis.energieverbrauch_3_heizquelle_1}</p>
|
||||
<p>{ausweis.energietraeger_einheit_heizquelle_1}</p>
|
||||
<p>{ausweis.verbrauch_3}</p>
|
||||
<p>{ausweis.einheit_1}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>Warmwasser enthalten: {ausweis.warmwasser_enthalten ? "Ja" : "Nein"}</p>
|
||||
<p>
|
||||
Warmwasser enthalten: {
|
||||
ausweis.warmwasser_enthalten ? "Ja" : "Nein"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<DatenblattFooter></DatenblattFooter>
|
||||
<DatenblattFooter />
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<DatenblattHeader></DatenblattHeader>
|
||||
<DatenblattHeader />
|
||||
<div class="px-12 py-20 flex flex-col gap-2">
|
||||
<h2>Modernisierungsstand</h2>
|
||||
<h3>Heizungsanlage</h3>
|
||||
<div class="grid grid-cols-3">
|
||||
<Checkbox checked={ausweis.versorgungssysteme[0]}>Zentral/Etage</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[1]}>Einzelöfen</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[2]}>Durchlauferhitzer</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[3]}>Standardkessel</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[4]}>Solarsystem für Warmwasser</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[5]}>Wärmepumpe</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[6]}>Niedertemperaturkessel</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[7]}>Brennwertkessel/Therme</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[8]}>Warmwasserrohre gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[9]}>Heizungsrohre gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[10]}>Zirkulation</Checkbox>
|
||||
<Checkbox checked={ausweis.versorgungssysteme[11]}>Raumtemperraturregler</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.zentralheizung ||
|
||||
false}
|
||||
>
|
||||
Zentral/Etage
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.einzelofen ||
|
||||
false}
|
||||
>
|
||||
Einzelöfen
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.durchlauf_erhitzer || false}
|
||||
>
|
||||
Durchlauferhitzer
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.standard_kessel ||
|
||||
false}
|
||||
>
|
||||
Standardkessel
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.solarsystem_warmwasser || false}
|
||||
>
|
||||
Solarsystem für Warmwasser
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.waermepumpe ||
|
||||
false}
|
||||
>
|
||||
Wärmepumpe
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.niedertemperatur_kessel || false}
|
||||
>
|
||||
Niedertemperaturkessel
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.brennwert_kessel ||
|
||||
false}
|
||||
>
|
||||
Brennwertkessel/Therme
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.warmwasser_rohre_gedaemmt || false}
|
||||
>
|
||||
Warmwasserrohre gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.heizungsrohre_gedaemmt || false}
|
||||
>
|
||||
Heizungsrohre gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.zirkulation ||
|
||||
false}
|
||||
>
|
||||
Zirkulation
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.raum_temperatur_regler || false}
|
||||
>
|
||||
Raumtemperraturregler
|
||||
</Checkbox>
|
||||
</div>
|
||||
<h3>Fenster/Dachfenster/Türen</h3>
|
||||
<div class="grid grid-cols-3">
|
||||
<Checkbox checked={ausweis.fenster_dach[0]}>Einfachglas</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[1]}>Doppelverglasung</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[2]}>Isolierverglasung</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[3]}>Dreifachverglasung</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[4]}>Alle Fenster dicht</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[5]}>Fenster teilweise undicht</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[6]}>Alle Türen dicht</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[7]}>Türen teilweise undicht</Checkbox>
|
||||
<Checkbox checked={ausweis.fenster_dach[8]}>Rolladenkästen gedämmt</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.einfach_verglasung || false}
|
||||
>
|
||||
Einfachglas
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.doppel_verglasung || false}
|
||||
>
|
||||
Doppelverglasung
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.isolier_verglasung || false}
|
||||
>
|
||||
Isolierverglasung
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.dreifach_verglasung || false}
|
||||
>
|
||||
Dreifachverglasung
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.fenster_dicht ||
|
||||
false}
|
||||
>
|
||||
Alle Fenster dicht
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.fenster_teilweise_undicht || false}
|
||||
>
|
||||
Fenster teilweise undicht
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.tueren_dicht ||
|
||||
false}
|
||||
>
|
||||
Alle Türen dicht
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude.tueren_undicht ||
|
||||
false}
|
||||
>
|
||||
Türen teilweise undicht
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.rolllaeden_kaesten_gedaemmt || false}
|
||||
>
|
||||
Rolladenkästen gedämmt
|
||||
</Checkbox>
|
||||
</div>
|
||||
<h3>Wärmedämmung</h3>
|
||||
<div class="grid grid-cols-2">
|
||||
<Checkbox checked={ausweis.daemmung[0]}>Außenwand gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.daemmung[1]}>Kelleraußenwand gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.daemmung[2]}>Kellerdecke gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.daemmung[3]}>Dachgeschoss gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.daemmung[4]}>Oberste Geschossdecke gedämmt</Checkbox>
|
||||
<Checkbox checked={ausweis.daemmung[5]}>Oberste Geschossdecke min. 12cm gedämmt</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.aussenwand_gedaemmt || false}
|
||||
>
|
||||
Außenwand gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.keller_wand_gedaemmt || false}
|
||||
>
|
||||
Kelleraußenwand gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.keller_decke_gedaemmt || false}
|
||||
>
|
||||
Kellerdecke gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.dachgeschoss_gedaemmt || false}
|
||||
>
|
||||
Dachgeschoss gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.oberste_geschossdecke_gedaemmt || false}
|
||||
>
|
||||
Oberste Geschossdecke gedämmt
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={gebaeude
|
||||
.oberste_geschossdecke_min_12cm_gedaemmt || false}
|
||||
>
|
||||
Oberste Geschossdecke min. 12cm gedämmt
|
||||
</Checkbox>
|
||||
</div>
|
||||
<Checkbox checked={true}>Die Angaben sind richtig und entsprechen dem aktuellen Stand.</Checkbox>
|
||||
<Checkbox checked={true}>Ich habe die AGB gelesen und akzeptiert.</Checkbox>
|
||||
<p>Die Angaben auf diesem Datenblatt wurden uns übermittelt und werden zur Berechnung und
|
||||
Ausstellung des Ausweises herangezogen.</p>
|
||||
<Checkbox checked={true}>
|
||||
Die Angaben sind richtig und entsprechen dem aktuellen
|
||||
Stand.
|
||||
</Checkbox>
|
||||
<Checkbox checked={true}>
|
||||
Ich habe die AGB gelesen und akzeptiert.
|
||||
</Checkbox>
|
||||
<p>
|
||||
Die Angaben auf diesem Datenblatt wurden uns übermittelt und
|
||||
werden zur Berechnung und Ausstellung des Ausweises
|
||||
herangezogen.
|
||||
</p>
|
||||
</div>
|
||||
<DatenblattFooter></DatenblattFooter>
|
||||
<DatenblattFooter />
|
||||
</div>
|
||||
</div>
|
||||
</PDFLayout>
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
import moment from "moment";
|
||||
import RegisterView from "../modules/RegisterModule.svelte";
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
const token = Astro.cookies.get("token").value;
|
||||
const expires = Astro.cookies.get("expires").number();
|
||||
const now = moment().unix();
|
||||
|
||||
@@ -1,32 +1,10 @@
|
||||
---
|
||||
import UserLayout from "#layouts/UserLayout.astro";
|
||||
import { User } from "#lib/User";
|
||||
import { tRPCCaller } from "../api/[trpc]";
|
||||
|
||||
const token = Astro.cookies.get("token").value;
|
||||
|
||||
if (!token) {
|
||||
Astro.cookies.delete("token");
|
||||
return Astro.redirect(`/login`);
|
||||
}
|
||||
|
||||
const response = await tRPCCaller(Astro.request).v1.benutzer.tokenValidieren({ token });
|
||||
|
||||
if (!response.valid) {
|
||||
Astro.cookies.delete("token");
|
||||
return Astro.redirect(`/login`);
|
||||
}
|
||||
|
||||
const user = await User.fromUID(response.uid);
|
||||
|
||||
if (!user) {
|
||||
Astro.cookies.delete("token");
|
||||
return Astro.redirect(`/login`);
|
||||
}
|
||||
---
|
||||
|
||||
<UserLayout title="Dashboard">
|
||||
<h1>Willkommen zurück <b>{user.email}</b></h1>
|
||||
<h1>Willkommen zurück</h1>
|
||||
|
||||
<h2>Ihre Ausweise</h2>
|
||||
<div class="grid grid-flow-row grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||
import VerbrauchsausweisGewerbeContent from "#components/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbeContent.svelte";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
---
|
||||
|
||||
<AusweisLayout title="Verbrauchsausweis Gewerbe erstellen | IBCornelsen">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
import { changeLanguage } from "i18next";
|
||||
|
||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||
import VerbrauchsausweisWohnenModule from "#modules/Ausweise/VerbrauchsausweisWohnenModule.svelte";
|
||||
|
||||
changeLanguage("de");
|
||||
|
||||
|
||||
const uid = Astro.cookies.get("ausweis_uid").value;
|
||||
---
|
||||
|
||||
@@ -31,9 +31,6 @@ body {
|
||||
}
|
||||
|
||||
.stretch-2 {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 1;
|
||||
-ms-grid-column-span: 4;
|
||||
grid-area: 1/1/1/4;
|
||||
}
|
||||
|
||||
@@ -43,9 +40,6 @@ body {
|
||||
|
||||
.right-sidebar {
|
||||
display: none;
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 1;
|
||||
-ms-grid-column-span: 3;
|
||||
grid-area: 1/1/1/3;
|
||||
padding-top: 0px;
|
||||
margin-top: 0px;
|
||||
@@ -62,7 +56,7 @@ body {
|
||||
}
|
||||
|
||||
.mainContent a {
|
||||
color: #3A4AB5;
|
||||
color: #3a4ab5;
|
||||
text-decoration: none;
|
||||
display: inline;
|
||||
}
|
||||
@@ -78,8 +72,6 @@ body {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
footer a {
|
||||
display: inline;
|
||||
color: #fff;
|
||||
@@ -87,7 +79,6 @@ footer a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*- Branding: -*/
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
@@ -130,12 +121,11 @@ footer a {
|
||||
}
|
||||
|
||||
.nav-head {
|
||||
background-color: #444F94;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
background-color: #444f94;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
|
||||
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-pack: end;
|
||||
@@ -156,13 +146,12 @@ footer a {
|
||||
max-height: 100%;
|
||||
padding-bottom: 0px;
|
||||
padding-top: 0px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
background-color: #444F94;
|
||||
background-color: #444f94;
|
||||
}
|
||||
|
||||
header a {
|
||||
@@ -186,31 +175,17 @@ header a {
|
||||
background-color: #ff7d26;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.headerButton.active {
|
||||
background-color: rgb(58, 74, 181);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*- -*/
|
||||
|
||||
.justify-between {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@@ -225,12 +200,12 @@ header a {
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #CECECE;
|
||||
border-bottom: 1px solid #cecece;
|
||||
margin: 1em 0 1em 0;
|
||||
}
|
||||
|
||||
ul hr {
|
||||
margin: .5em 0 !important;
|
||||
margin: 0.5em 0 !important;
|
||||
}
|
||||
|
||||
.nopad {
|
||||
@@ -263,9 +238,7 @@ ul hr {
|
||||
padding: 0;
|
||||
margin: 0 10px 0 0;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 4px rgba(0, 0, 0, .24);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 4px rgba(0, 0, 0, .24);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
.rplg .rplg-social-logo svg {
|
||||
@@ -280,10 +253,8 @@ ul hr {
|
||||
}
|
||||
|
||||
.rplgsw-wrapper {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
overflow: hidden
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rplg-box * {
|
||||
@@ -312,8 +283,6 @@ ul hr {
|
||||
}
|
||||
|
||||
.rplg-row {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@@ -321,8 +290,6 @@ ul hr {
|
||||
}
|
||||
|
||||
.rplg-trim {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@@ -338,7 +305,6 @@ ul hr {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Login - Hausbox
|
||||
@@ -347,8 +313,7 @@ Login - Hausbox
|
||||
|
||||
.haus_info_box {
|
||||
width: 100%;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@@ -384,8 +349,8 @@ Login - Hausbox
|
||||
|
||||
.haus-box {
|
||||
border-radius: 8px;
|
||||
-webkit-box-shadow: 0 0 .5em #ccc;
|
||||
box-shadow: 0 0 .5em #ccc;
|
||||
-webkit-box-shadow: 0 0 0.5em #ccc;
|
||||
box-shadow: 0 0 0.5em #ccc;
|
||||
width: 300px !important;
|
||||
}
|
||||
|
||||
@@ -408,8 +373,7 @@ Login - Hausbox
|
||||
|
||||
.image-box {
|
||||
width: auto;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
-webkit-box-align: center;
|
||||
@@ -427,8 +391,8 @@ Login - Hausbox
|
||||
.ampel-img {
|
||||
height: 100px;
|
||||
width: 35px !important;
|
||||
-webkit-box-shadow: 0 0 .5em #ccc;
|
||||
box-shadow: 0 0 .5em #ccc;
|
||||
-webkit-box-shadow: 0 0 0.5em #ccc;
|
||||
box-shadow: 0 0 0.5em #ccc;
|
||||
}
|
||||
|
||||
.haus-content {
|
||||
@@ -451,8 +415,8 @@ Login - Hausbox
|
||||
|
||||
.energieausweis-img {
|
||||
width: 33%;
|
||||
-webkit-box-shadow: 0 0 .5em #ccc;
|
||||
box-shadow: 0 0 .5em #ccc;
|
||||
-webkit-box-shadow: 0 0 0.5em #ccc;
|
||||
box-shadow: 0 0 0.5em #ccc;
|
||||
}
|
||||
|
||||
.energieausweis-img img {
|
||||
@@ -468,15 +432,14 @@ Login - Hausbox
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
border-radius: 1em;
|
||||
-webkit-box-shadow: .1em .1em .2em #bbb;
|
||||
box-shadow: .1em .1em .2em #bbb;
|
||||
-webkit-box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
}
|
||||
|
||||
.kbutton:focus {
|
||||
background-color: #384da3;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Input, textarea styling (forms)
|
||||
@@ -524,7 +487,7 @@ textarea {
|
||||
width: -webkit-max-content;
|
||||
width: -moz-max-content;
|
||||
width: max-content;
|
||||
padding: .375rem .75rem;
|
||||
padding: 0.375rem 0.75rem;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
@@ -554,7 +517,7 @@ textarea {
|
||||
.caption-text {
|
||||
font-size: 75%;
|
||||
padding-top: 5px;
|
||||
opacity: .8;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.image-list img {
|
||||
@@ -570,15 +533,15 @@ textarea {
|
||||
width: 1.3em;
|
||||
height: auto;
|
||||
background: none;
|
||||
left: -.6em;
|
||||
top: .3em;
|
||||
left: -0.6em;
|
||||
top: 0.3em;
|
||||
}
|
||||
|
||||
.kost-tbl {
|
||||
width: 100%;
|
||||
margin: 0 0 2em 0;
|
||||
-webkit-box-shadow: .2em .2em .4em #ccc;
|
||||
box-shadow: .2em .2em .4em #ccc;
|
||||
-webkit-box-shadow: 0.2em 0.2em 0.4em #ccc;
|
||||
box-shadow: 0.2em 0.2em 0.4em #ccc;
|
||||
}
|
||||
|
||||
.haus_ul1,
|
||||
@@ -592,7 +555,7 @@ textarea {
|
||||
.haus_ul2 li {
|
||||
position: relative;
|
||||
font-size: 1.1em;
|
||||
padding: .3em .3em .3em 1.3em;
|
||||
padding: 0.3em 0.3em 0.3em 1.3em;
|
||||
}
|
||||
|
||||
.haus_ul1 li::before {
|
||||
@@ -604,8 +567,8 @@ textarea {
|
||||
width: 1.3em;
|
||||
height: auto;
|
||||
background: none;
|
||||
left: -.6em;
|
||||
top: .3em;
|
||||
left: -0.6em;
|
||||
top: 0.3em;
|
||||
}
|
||||
|
||||
.kost-tbl thead td {
|
||||
@@ -631,8 +594,6 @@ table {
|
||||
grid-gap: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.start_infobox_img {
|
||||
float: right;
|
||||
width: 23% !important;
|
||||
@@ -653,23 +614,23 @@ table {
|
||||
.start_infobox_button a:hover {
|
||||
background-color: #ff7d26;
|
||||
color: #fff !important;
|
||||
padding: .15em 1em .15em 1em;
|
||||
border-radius: .8em;
|
||||
padding: 0.15em 1em 0.15em 1em;
|
||||
border-radius: 0.8em;
|
||||
font-size: 1.3em;
|
||||
font-weight: 600;
|
||||
-webkit-box-shadow: .1em .1em .2em #bbb;
|
||||
box-shadow: .1em .1em .2em #bbb;
|
||||
-webkit-box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
}
|
||||
|
||||
.start_infobox_button a {
|
||||
background-color: #3a4ab5;
|
||||
color: #fff !important;
|
||||
padding: .2em 1em .2em 1em;
|
||||
border-radius: .8em;
|
||||
padding: 0.2em 1em 0.2em 1em;
|
||||
border-radius: 0.8em;
|
||||
font-size: 1.3em;
|
||||
font-weight: 600;
|
||||
-webkit-box-shadow: .1em .1em .2em #bbb;
|
||||
box-shadow: .1em .1em .2em #bbb;
|
||||
-webkit-box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
}
|
||||
|
||||
.start_infobox_button {
|
||||
@@ -682,8 +643,8 @@ table {
|
||||
margin: 2em auto;
|
||||
border: 2px dotted #ff7d26;
|
||||
border-radius: 1em;
|
||||
-webkit-box-shadow: 0 0 .5em #ccc;
|
||||
box-shadow: 0 0 .5em #ccc;
|
||||
-webkit-box-shadow: 0 0 0.5em #ccc;
|
||||
box-shadow: 0 0 0.5em #ccc;
|
||||
}
|
||||
|
||||
.start_infobox ul li::before {
|
||||
@@ -694,7 +655,7 @@ table {
|
||||
height: 7px;
|
||||
background-color: #ddd;
|
||||
position: absolute;
|
||||
border-radius: .1em;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
.start_infobox .title,
|
||||
@@ -702,7 +663,7 @@ table {
|
||||
color: #ff7d26 !important;
|
||||
margin: 0;
|
||||
font-size: 1.4em;
|
||||
margin-bottom: -.3em;
|
||||
margin-bottom: -0.3em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -728,7 +689,7 @@ table {
|
||||
|
||||
.pdf {
|
||||
position: relative;
|
||||
padding: 0 0 .5em 3.5em;
|
||||
padding: 0 0 0.5em 3.5em;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
@@ -742,9 +703,9 @@ table {
|
||||
.bedarfsausweis-wohngebaeude-beispiel,
|
||||
.verbrauchsausweis-wohngebaeude-beispiel {
|
||||
width: 100%;
|
||||
margin: 0 .5% 2em .5%;
|
||||
margin: 0 0.5% 2em 0.5%;
|
||||
font-size: 1.1em;
|
||||
padding: .5em .5%;
|
||||
padding: 0.5em 0.5%;
|
||||
float: left;
|
||||
text-align: center;
|
||||
border-top-left-radius: 1em;
|
||||
@@ -762,9 +723,9 @@ table {
|
||||
.buynow-btn {
|
||||
background-color: #4251a3;
|
||||
border-radius: 1em;
|
||||
padding: .2em 1em;
|
||||
-webkit-box-shadow: .1em .1em .2em #bbb;
|
||||
box-shadow: .1em .1em .2em #bbb;
|
||||
padding: 0.2em 1em;
|
||||
-webkit-box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
white-space: nowrap;
|
||||
border: 2px solid #fff;
|
||||
color: #fff !important;
|
||||
@@ -774,13 +735,11 @@ table {
|
||||
|
||||
.buynow-btn:hover {
|
||||
background-color: #ff7d26;
|
||||
-webkit-box-shadow: .1em .1em .2em #bbb;
|
||||
box-shadow: .1em .1em .2em #bbb;
|
||||
-webkit-box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.row * {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
@@ -800,9 +759,6 @@ table {
|
||||
}
|
||||
|
||||
.row {
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
@@ -811,18 +767,14 @@ table {
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
|
||||
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@@ -833,16 +785,11 @@ table {
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
block {
|
||||
display: block;
|
||||
position: relative;
|
||||
@@ -870,14 +817,9 @@ cbutton {
|
||||
width: -moz-min-content;
|
||||
width: min-content;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
:root {
|
||||
--theme-primary: #fff;
|
||||
--theme-orange: rgb(255, 125, 38);
|
||||
@@ -886,8 +828,6 @@ cbutton {
|
||||
--std-font: Abel, Roboto, sand-serif;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.section_1 > *:nth-child(1) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 1;
|
||||
@@ -936,18 +876,9 @@ cbutton {
|
||||
}
|
||||
|
||||
.block_4 {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-align: start;
|
||||
-ms-flex-align: start;
|
||||
align-items: start;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
width: inherit;
|
||||
padding: 0px;
|
||||
@@ -955,21 +886,16 @@ cbutton {
|
||||
}
|
||||
|
||||
.block_5 {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
|
||||
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
-webkit-box-align: start;
|
||||
-ms-flex-align: start;
|
||||
align-items: start;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
|
||||
align-items: flex-start;
|
||||
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@@ -1064,12 +990,8 @@ content {
|
||||
margin: 10px auto;
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
-webkit-column-gap: 20px;
|
||||
-moz-column-gap: 20px;
|
||||
column-gap: 20px;
|
||||
-ms-grid-columns: 2fr 20px 6fr 20px 2fr;
|
||||
grid-template-columns: 2fr 6fr 2fr;
|
||||
-ms-grid-rows: auto;
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
|
||||
@@ -1093,7 +1015,6 @@ content>*:nth-child(3) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.rpt_plan img {
|
||||
width: 50%;
|
||||
margin: 15px auto;
|
||||
@@ -1107,20 +1028,17 @@ content>*:nth-child(3) {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
line-height: 1.2em;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
padding: 14px 18px;
|
||||
background: #4251a3;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
border-top-left-radius: .4em;
|
||||
border-top-right-radius: .4em;
|
||||
border-top-left-radius: 0.4em;
|
||||
border-top-right-radius: 0.4em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -1128,10 +1046,10 @@ content>*:nth-child(3) {
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
text-shadow: 1px 2px 7px rgba(0, 0, 0, .6);
|
||||
text-shadow: 1px 2px 7px rgba(0, 0, 0, 0.6);
|
||||
font-size: 5em;
|
||||
font-weight: bold;
|
||||
padding-bottom: .2em;
|
||||
padding-bottom: 0.2em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -1206,17 +1124,12 @@ content>*:nth-child(3) {
|
||||
width: 100%;
|
||||
min-width: 152px;
|
||||
@apply border shadow-md;
|
||||
border-radius: .4em;
|
||||
border-radius: 0.4em;
|
||||
background: #f5f5f5;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
|
||||
flex-direction: column;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -1229,7 +1142,7 @@ content>*:nth-child(3) {
|
||||
height: 7px;
|
||||
background-color: #ddd;
|
||||
position: absolute;
|
||||
border-radius: .1em;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
.widget_nav ul li {
|
||||
@@ -1262,12 +1175,11 @@ content>*:nth-child(3) {
|
||||
.large-button {
|
||||
background: #3a4ab5;
|
||||
color: #fff;
|
||||
padding: .2em 1em .2em 1em;
|
||||
border-radius: .8em;
|
||||
padding: 0.2em 1em 0.2em 1em;
|
||||
border-radius: 0.8em;
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
-webkit-box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
box-shadow: 0.1em 0.1em 0.2em #bbb;
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
@@ -1305,7 +1217,7 @@ ul li {
|
||||
}
|
||||
|
||||
ul li::before {
|
||||
content: '';
|
||||
content: "";
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
left: 0;
|
||||
@@ -1313,7 +1225,7 @@ ul li::before {
|
||||
margin-left: 0;
|
||||
background: #ff7d26;
|
||||
position: absolute;
|
||||
border-radius: .1em;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
.img-subtitle {
|
||||
@@ -1323,18 +1235,13 @@ ul li::before {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
footer {
|
||||
background: rgb(255, 125, 38);
|
||||
height: 40px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
|
||||
justify-content: space-between;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
padding: 0 30px;
|
||||
width: auto;
|
||||
@@ -1344,17 +1251,10 @@ footer {
|
||||
}
|
||||
|
||||
#pwtester {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 10px 0 0 0;
|
||||
-webkit-box-pack: space-evenly;
|
||||
-ms-flex-pack: space-evenly;
|
||||
justify-content: space-evenly;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
@@ -1363,17 +1263,14 @@ footer {
|
||||
width: 24%;
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
background: #B7B7B7;
|
||||
background: #b7b7b7;
|
||||
}
|
||||
|
||||
.objekt_card {
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
-ms-grid-columns: 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
-ms-grid-rows: 375px 5px 125px;
|
||||
grid-template-rows: 375px 125px;
|
||||
-webkit-box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
||||
box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
||||
background: #fff;
|
||||
margin: 0 auto;
|
||||
@@ -1383,9 +1280,6 @@ footer {
|
||||
grid-row-gap: 5px;
|
||||
max-width: 1100px;
|
||||
position: relative;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
margin-bottom: 30px;
|
||||
@@ -1432,8 +1326,7 @@ body .objekt_card:first-of-type {
|
||||
.objekt_previewImage {
|
||||
-o-object-fit: contain;
|
||||
object-fit: contain;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -1462,22 +1355,14 @@ body .objekt_card:first-of-type {
|
||||
.objekt_makler {
|
||||
margin: 0 20px 20px 20px;
|
||||
padding-left: 20px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border-top: 1px solid rgb(223, 223, 223);
|
||||
}
|
||||
|
||||
.objekt_images {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
@@ -1494,12 +1379,8 @@ body .objekt_card:first-of-type {
|
||||
|
||||
/* NOTE MAKLER SYSTEM */
|
||||
.card_container {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@@ -1513,8 +1394,6 @@ body .objekt_card:first-of-type {
|
||||
}
|
||||
|
||||
.justify_left {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -1564,9 +1443,7 @@ body .objekt_card:first-of-type {
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
grid-template-areas: "main detail" "main info";
|
||||
-ms-grid-columns: 3.8fr 20px 1.2fr;
|
||||
grid-template-columns: 3.8fr 1.2fr;
|
||||
-ms-grid-rows: 250px 20px auto;
|
||||
grid-template-rows: 250px auto;
|
||||
grid-gap: 20px;
|
||||
}
|
||||
@@ -1583,7 +1460,6 @@ body .objekt_card:first-of-type {
|
||||
|
||||
.text_container {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-row-span: 3;
|
||||
-ms-grid-column: 1;
|
||||
grid-area: main;
|
||||
background: #fff;
|
||||
@@ -1606,18 +1482,11 @@ body .objekt_card:first-of-type {
|
||||
}
|
||||
|
||||
.image_slideshow {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
margin-right: 10px;
|
||||
gap: 10px;
|
||||
overflow: hidden;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
--image-width: 1200px;
|
||||
--image-margin: 6px;
|
||||
@@ -1630,31 +1499,20 @@ body .objekt_card:first-of-type {
|
||||
.image_slideshow img {
|
||||
width: 1200px;
|
||||
height: 500px;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
-webkit-transition: all .4s ease;
|
||||
-o-transition: all .4s ease;
|
||||
transition: all .4s ease;
|
||||
-webkit-box-shadow: 1px 1px 2px 1px rgba(24, 24, 24, 0.178);
|
||||
transition: all 0.4s ease;
|
||||
box-shadow: 1px 1px 2px 1px rgba(24, 24, 24, 0.178);
|
||||
}
|
||||
|
||||
.image_slideshow .control_wrapper {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: calc(1200px + 60px);
|
||||
height: 500px;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
|
||||
justify-content: space-between;
|
||||
-webkit-transition: all 0.4s ease;
|
||||
-o-transition: all 0.4s ease;
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
|
||||
@@ -1662,9 +1520,6 @@ body .objekt_card:first-of-type {
|
||||
position: relative;
|
||||
width: 1200px;
|
||||
height: 530px;
|
||||
/*margin: 0 6px;*/
|
||||
-webkit-transition: all 0.4s ease;
|
||||
-o-transition: all 0.4s ease;
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
|
||||
@@ -1679,21 +1534,13 @@ body .objekt_card:first-of-type {
|
||||
border-radius: 50%;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
color: #000;
|
||||
-webkit-transition: all .3s ease;
|
||||
-o-transition: all .3s ease;
|
||||
transition: all .3s ease;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
-webkit-box-shadow: 1px 1px 2px 1px rgba(24, 24, 24, 0.178);
|
||||
box-shadow: 1px 1px 2px 1px rgba(24, 24, 24, 0.178);
|
||||
}
|
||||
|
||||
@@ -1711,7 +1558,6 @@ body .objekt_card:first-of-type {
|
||||
-ms-grid-columns: 2fr 20px 1fr;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
grid-gap: 20px;
|
||||
-ms-grid-rows: auto;
|
||||
grid-template-rows: auto;
|
||||
grid-template-areas: "profile_info menu_buttons" ". menu_buttons";
|
||||
}
|
||||
@@ -1725,7 +1571,6 @@ body .objekt_card:first-of-type {
|
||||
|
||||
.span-2 {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-row-span: 2;
|
||||
-ms-grid-column: 1;
|
||||
grid-area: 1/1 / span 2 / 1;
|
||||
}
|
||||
@@ -1803,7 +1648,6 @@ body .objekt_card:first-of-type {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.login-container {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
@@ -127,11 +127,11 @@
|
||||
|
||||
.nav-head {
|
||||
background-color: rgb(255, 125, 38);
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-pack: end;
|
||||
@@ -154,8 +154,8 @@
|
||||
max-height: 100%;
|
||||
padding-bottom: 0px;
|
||||
padding-top: 0px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
||||
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
||||
import cookies from 'js-cookie';
|
||||
import type { AppRouter } from 'src/pages/api/[trpc]';
|
||||
import type { AppRouter } from '@ibcornelsen/api';
|
||||
|
||||
export const client = createTRPCProxyClient<AppRouter>({
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: 'http://localhost:3000/api',
|
||||
url: 'http://localhost:3001/',
|
||||
headers() {
|
||||
return {
|
||||
'Authorization': `Bearer ${cookies.get('uid')}`,
|
||||
'Authorization': `Bearer ${cookies.get('accessToken')}`,
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
10
test.ts
10
test.ts
@@ -1,10 +0,0 @@
|
||||
import { AppRouter } from "src/pages/api/[trpc]"
|
||||
import { createOpenApiExpressMiddleware } from "trpc-openapi"
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
app.use(createOpenApiExpressMiddleware({ router: AppRouter }));
|
||||
|
||||
app.listen(5555);
|
||||
|
||||
console.log("Server listening on port 80");
|
||||
Reference in New Issue
Block a user