Notifications + Plausibilitätsprüfung
This commit is contained in:
@@ -2,9 +2,16 @@
|
|||||||
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
||||||
import { Gebaeude } from "src/lib/Gebaeude";
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
import HelpLabel from "~/components/HelpLabel.svelte";
|
import HelpLabel from "~/components/HelpLabel.svelte";
|
||||||
|
import { auditHeizungGebaeudeBaujahr } from "../Verbrauchsausweis/audits/HeizungGebaeudeBaujahr";
|
||||||
|
import { addNotification, deleteNotification } from "../Notifications/shared";
|
||||||
|
import TagInput from "../TagInput.svelte";
|
||||||
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
export let gebaeude: Gebaeude;
|
export let gebaeude: Gebaeude;
|
||||||
|
|
||||||
|
// TODO: Das ist scheise
|
||||||
|
let tags = writable([]);
|
||||||
|
|
||||||
$: ausweis = gebaeude.ausweis || new Verbrauchsausweis();
|
$: ausweis = gebaeude.ausweis || new Verbrauchsausweis();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -71,11 +78,27 @@
|
|||||||
/>z.B. 1994-2001.
|
/>z.B. 1994-2001.
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<TagInput
|
||||||
name="IGheizung"
|
name="IGheizung"
|
||||||
type="number"
|
type="number"
|
||||||
|
onlyUnique={true}
|
||||||
|
onFocusIn={() => {
|
||||||
|
addNotification({
|
||||||
|
message: "Info",
|
||||||
|
subtext: "Wussten sie, dass sie mehrere Jahre angeben können in denen z.B. Renovierungen an ihrer Heizung durchgeführt wurden. Drücken sie dafür einfach <kbd>Enter</kbd> oder <kbd>Space</kbd> nach jedem Jahr.",
|
||||||
|
dismissable: true,
|
||||||
|
uid: "HEIZUNG_BAUJAHR",
|
||||||
|
timeout: 0,
|
||||||
|
type: "info"
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onFocusOut={() => {
|
||||||
|
deleteNotification("HEIZUNG_BAUJAHR")
|
||||||
|
}}
|
||||||
|
className="{auditHeizungGebaeudeBaujahr(gebaeude) ? "linked" : ""}"
|
||||||
required
|
required
|
||||||
bind:value={ausweis.baujahr_anlage}
|
autocomplete="off"
|
||||||
|
bind:tags
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -92,12 +115,27 @@
|
|||||||
-saniert- angeben.
|
-saniert- angeben.
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<TagInput
|
||||||
name="IGbaujahr"
|
name="IGbaujahr"
|
||||||
type="number"
|
type="number"
|
||||||
|
onlyUnique={true}
|
||||||
|
onFocusIn={() => {
|
||||||
|
addNotification({
|
||||||
|
message: "Info",
|
||||||
|
subtext: "Wussten sie, dass sie mehrere Jahre angeben können in denen z.B. Renovierungen an ihrem Gebäude durchgeführt wurden. Drücken sie dafür einfach <kbd>Enter</kbd> oder <kbd>Space</kbd> nach jedem Jahr.",
|
||||||
|
dismissable: true,
|
||||||
|
uid: "GEBAEUDE_BAUJAHR",
|
||||||
|
timeout: 0,
|
||||||
|
type: "info"
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onFocusOut={() => {
|
||||||
|
deleteNotification("GEBAEUDE_BAUJAHR")
|
||||||
|
}}
|
||||||
|
className="{auditHeizungGebaeudeBaujahr(gebaeude) ? "linked" : ""}"
|
||||||
required
|
required
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
bind:value={gebaeude.baujahr}
|
bind:tags
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
import Label from "../Label.svelte";
|
import Label from "../Label.svelte";
|
||||||
import fuelList from "./fuelList";
|
import fuelList from "./fuelList";
|
||||||
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
||||||
import { VerbrauchsausweisGewerbe } from "src/lib/Ausweis/VerbrauchsausweisGewerbe";
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
import { Bedarfsausweis } from "src/lib/Ausweis/Bedarfsausweis";
|
import { auditVerbrauchAbweichung } from "../Verbrauchsausweis/audits/VerbrauchAbweichung";
|
||||||
|
|
||||||
let availableYears = [
|
let availableYears = [
|
||||||
2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
|
2018, 2019,
|
||||||
];
|
];
|
||||||
let availableMonths = [
|
let availableMonths = [
|
||||||
"Januar",
|
"Januar",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"Dezember",
|
"Dezember",
|
||||||
];
|
];
|
||||||
|
|
||||||
export let ausweis: Verbrauchsausweis |VerbrauchsausweisGewerbe | Bedarfsausweis;
|
export let gebaeude: Gebaeude;
|
||||||
|
|
||||||
const fuelMap: Record<string, string[]> = {};
|
const fuelMap: Record<string, string[]> = {};
|
||||||
for (const fuel of fuelList) {
|
for (const fuel of fuelList) {
|
||||||
@@ -37,11 +37,15 @@
|
|||||||
let month: string = "01";
|
let month: string = "01";
|
||||||
let year: string = "2018";
|
let year: string = "2018";
|
||||||
|
|
||||||
|
$: ausweis = gebaeude.ausweis || new Verbrauchsausweis();
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (month && year) {
|
if (month && year) {
|
||||||
ausweis.energieverbrauch_zeitraum = moment(`${month}.01.${year}`);
|
ausweis.kennwerte.zeitraum = moment(`${month}.01.${year}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: abweichung = auditVerbrauchAbweichung(gebaeude);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full flex flex-col gap-4">
|
<div class="w-full flex flex-col gap-4">
|
||||||
@@ -56,7 +60,7 @@
|
|||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="IGzus1verbrauch1"
|
class="IGzus1verbrauch1"
|
||||||
bind:checked={ausweis.zusaetzliche_heizquelle}
|
bind:checked={ausweis.kennwerte.zusaetzliche_heizquelle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -88,7 +92,7 @@
|
|||||||
<b>Koks:</b> Stark kohlenstoffhaltiger Brennstoff.<br /><br />
|
<b>Koks:</b> Stark kohlenstoffhaltiger Brennstoff.<br /><br />
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select name="energietraeger_1" required bind:value={ausweis.energietraeger_1}>
|
<select name="energietraeger_1" required bind:value={ausweis.kennwerte.energietraeger_1}>
|
||||||
<option>Bitte auswählen</option>
|
<option>Bitte auswählen</option>
|
||||||
{#each Object.keys(fuelMap) as fuel}
|
{#each Object.keys(fuelMap) as fuel}
|
||||||
<option value={fuel}>{fuel}</option>
|
<option value={fuel}>{fuel}</option>
|
||||||
@@ -107,10 +111,10 @@
|
|||||||
<select
|
<select
|
||||||
name="energietraeger_einheit_heizquelle_1"
|
name="energietraeger_einheit_heizquelle_1"
|
||||||
required
|
required
|
||||||
bind:value={ausweis.energietraeger_einheit_heizquelle_1}
|
bind:value={ausweis.kennwerte.einheit_1}
|
||||||
>
|
>
|
||||||
<option>Bitte auswählen</option>
|
<option>Bitte auswählen</option>
|
||||||
{#each (fuelMap.hasOwnProperty(ausweis.energietraeger_1) ? fuelMap[ausweis.energietraeger_1] : []) as unit}
|
{#each (fuelMap.hasOwnProperty(ausweis.kennwerte.energietraeger_1) ? fuelMap[ausweis.kennwerte.energietraeger_1] : []) as unit}
|
||||||
<option value={unit}>{unit}</option>
|
<option value={unit}>{unit}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
@@ -122,8 +126,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="energietraeger_2"
|
name="energietraeger_2"
|
||||||
bind:value={ausweis.energietraeger_2}
|
bind:value={ausweis.kennwerte.energietraeger_2}
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
disabled={!ausweis.kennwerte.zusaetzliche_heizquelle}
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option> Bitte auswählen</option>
|
<option> Bitte auswählen</option>
|
||||||
@@ -139,12 +143,12 @@
|
|||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="energietraeger_einheit_heizquelle_2"
|
name="energietraeger_einheit_heizquelle_2"
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
disabled={!ausweis.kennwerte.zusaetzliche_heizquelle}
|
||||||
bind:value={ausweis.energietraeger_einheit_heizquelle_2}
|
bind:value={ausweis.kennwerte.einheit_2}
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option>Bitte auswählen</option>
|
<option>Bitte auswählen</option>
|
||||||
{#each (fuelMap.hasOwnProperty(ausweis.energietraeger_2) ? fuelMap[ausweis.energietraeger_2] : []) as unit}
|
{#each (fuelMap.hasOwnProperty(ausweis.kennwerte.energietraeger_2) ? fuelMap[ausweis.kennwerte.energietraeger_2] : []) as unit}
|
||||||
<option value={unit}>{unit}</option>
|
<option value={unit}>{unit}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
@@ -184,7 +188,7 @@
|
|||||||
<span>von</span>
|
<span>von</span>
|
||||||
<input
|
<input
|
||||||
class="klima"
|
class="klima"
|
||||||
value={moment(ausweis.energieverbrauch_zeitraum)
|
value={moment(ausweis.kennwerte.zeitraum)
|
||||||
.add("1", "year")
|
.add("1", "year")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
readonly
|
readonly
|
||||||
@@ -194,7 +198,7 @@
|
|||||||
<span>von</span>
|
<span>von</span>
|
||||||
<input
|
<input
|
||||||
class="klima"
|
class="klima"
|
||||||
value={moment(ausweis.energieverbrauch_zeitraum)
|
value={moment(ausweis.kennwerte.zeitraum)
|
||||||
.add("2", "years")
|
.add("2", "years")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
readonly
|
readonly
|
||||||
@@ -206,7 +210,7 @@
|
|||||||
<span>bis</span>
|
<span>bis</span>
|
||||||
<input
|
<input
|
||||||
class=""
|
class=""
|
||||||
value={moment(ausweis.energieverbrauch_zeitraum)
|
value={moment(ausweis.kennwerte.zeitraum)
|
||||||
.add("1", "year")
|
.add("1", "year")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
readonly
|
readonly
|
||||||
@@ -216,7 +220,7 @@
|
|||||||
<span>bis</span>
|
<span>bis</span>
|
||||||
<input
|
<input
|
||||||
class=""
|
class=""
|
||||||
value={moment(ausweis.energieverbrauch_zeitraum)
|
value={moment(ausweis.kennwerte.zeitraum)
|
||||||
.add("2", "years")
|
.add("2", "years")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
readonly
|
readonly
|
||||||
@@ -226,7 +230,7 @@
|
|||||||
<span>bis</span>
|
<span>bis</span>
|
||||||
<input
|
<input
|
||||||
class=""
|
class=""
|
||||||
value={moment(ausweis.energieverbrauch_zeitraum)
|
value={moment(ausweis.kennwerte.zeitraum)
|
||||||
.add("3", "years")
|
.add("3", "years")
|
||||||
.format("MM.Y")}
|
.format("MM.Y")}
|
||||||
readonly
|
readonly
|
||||||
@@ -239,7 +243,8 @@
|
|||||||
<input
|
<input
|
||||||
name="energieverbrauch_1_heizquelle_1"
|
name="energieverbrauch_1_heizquelle_1"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.energieverbrauch_1_heizquelle_1}
|
class:linked={abweichung.indexOf(1) > -1}
|
||||||
|
bind:value={ausweis.kennwerte.verbrauch_1}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -248,7 +253,8 @@
|
|||||||
<input
|
<input
|
||||||
name="energieverbrauch_2_heizquelle_1"
|
name="energieverbrauch_2_heizquelle_1"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.energieverbrauch_2_heizquelle_1}
|
class:linked={abweichung.indexOf(2) > -1}
|
||||||
|
bind:value={ausweis.kennwerte.verbrauch_2}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -257,7 +263,8 @@
|
|||||||
<input
|
<input
|
||||||
name="energieverbrauch_3_heizquelle_1"
|
name="energieverbrauch_3_heizquelle_1"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.energieverbrauch_3_heizquelle_1}
|
class:linked={abweichung.indexOf(3) > -1}
|
||||||
|
bind:value={ausweis.kennwerte.verbrauch_3}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -268,8 +275,9 @@
|
|||||||
<input
|
<input
|
||||||
name="energieverbrauch_1_heizquelle_2"
|
name="energieverbrauch_1_heizquelle_2"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.energieverbrauch_1_heizquelle_2}
|
bind:value={ausweis.kennwerte.verbrauch_4}
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
class:linked={abweichung.indexOf(4) > -1}
|
||||||
|
disabled={!ausweis.kennwerte.zusaetzliche_heizquelle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
@@ -277,8 +285,9 @@
|
|||||||
<input
|
<input
|
||||||
name="energieverbrauch_2_heizquelle_2"
|
name="energieverbrauch_2_heizquelle_2"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.energieverbrauch_2_heizquelle_2}
|
bind:value={ausweis.kennwerte.verbrauch_5}
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
class:linked={abweichung.indexOf(5) > -1}
|
||||||
|
disabled={!ausweis.kennwerte.zusaetzliche_heizquelle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
@@ -286,8 +295,9 @@
|
|||||||
<input
|
<input
|
||||||
name="energieverbrauch_3_heizquelle_2"
|
name="energieverbrauch_3_heizquelle_2"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.energieverbrauch_3_heizquelle_2}
|
bind:value={ausweis.kennwerte.verbrauch_6}
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle}
|
class:linked={abweichung.indexOf(6) > -1}
|
||||||
|
disabled={!ausweis.kennwerte.zusaetzliche_heizquelle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ const loggedIn = isLoggedIn(Astro);
|
|||||||
alt="IBCornelsen - Logo"
|
alt="IBCornelsen - Logo"
|
||||||
onclick="window.location.href = '/'"
|
onclick="window.location.href = '/'"
|
||||||
/>
|
/>
|
||||||
<h2 class="MajorHeading">Energieausweis online erstellen</h2>
|
<h2 class="text-secondary font-semibold text-2xl absolute top-8 right-0">Energieausweis online erstellen</h2>
|
||||||
<h2 class="MajorHeading smaller">Energieausweise nach aktueller GEG</h2>
|
<h2 class="text-primary font-semibold text-xl absolute top-16 right-0">Energieausweise nach aktueller GEG</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import cookie from "cookiejs";
|
import cookie from "cookiejs";
|
||||||
|
import { addNotification } from "./Notifications/shared";
|
||||||
|
|
||||||
let email: string;
|
let email: string;
|
||||||
let password: string;
|
let password: string;
|
||||||
let hasError: boolean;
|
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
const response = await fetch("/api/login", {
|
const response = await fetch("/api/login", {
|
||||||
@@ -23,8 +23,14 @@
|
|||||||
localStorage.setItem("expires", json.data.expires);
|
localStorage.setItem("expires", json.data.expires);
|
||||||
window.location.href = "/user";
|
window.location.href = "/user";
|
||||||
} else {
|
} else {
|
||||||
hasError = true;
|
|
||||||
setTimeout(() => (hasError = false), 3000);
|
addNotification({
|
||||||
|
message: "Ups...",
|
||||||
|
subtext: "Das hat leider nicht geklappt, haben sie ihr Passwort und ihre Email Adresse richtig eingegeben?",
|
||||||
|
type: "error",
|
||||||
|
timeout: 6000,
|
||||||
|
dismissable: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -52,13 +58,7 @@
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button on:click={login}>Einloggen</button>
|
<button class="button" on:click={login}>Einloggen</button>
|
||||||
{#if hasError}
|
|
||||||
<p>
|
|
||||||
Das hat leider nicht geklappt, haben sie ihr Passwort und den
|
|
||||||
Nutzernamen richtig eingegeben?
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
<div class="flex-row justify-between" style="margin-top: 10px">
|
<div class="flex-row justify-between" style="margin-top: 10px">
|
||||||
<a href="/signup">Registrieren</a>
|
<a href="/signup">Registrieren</a>
|
||||||
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
|
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
|
||||||
|
|||||||
10
src/components/Notifications/Notification.svelte
Normal file
10
src/components/Notifications/Notification.svelte
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import RawNotification from "./RawNotification.svelte";
|
||||||
|
import { Notification } from "./shared";
|
||||||
|
|
||||||
|
export let notification: Notification & { uid: string };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<RawNotification {notification}>
|
||||||
|
<p class="text-gray-600 text-lg">{@html notification.subtext}</p>
|
||||||
|
</RawNotification>
|
||||||
12
src/components/Notifications/NotificationWrapper.svelte
Normal file
12
src/components/Notifications/NotificationWrapper.svelte
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Notification from "./Notification.svelte";
|
||||||
|
import RawNotificationWrapper from "./RawNotificationWrapper.svelte";
|
||||||
|
|
||||||
|
import { notifications } from "./shared";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<RawNotificationWrapper>
|
||||||
|
{#each Object.entries($notifications) as [uid, notification] (uid)}
|
||||||
|
<Notification notification={{...notification, uid }}></Notification>
|
||||||
|
{/each}
|
||||||
|
</RawNotificationWrapper>
|
||||||
44
src/components/Notifications/RawNotification.svelte
Normal file
44
src/components/Notifications/RawNotification.svelte
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Notification, deleteNotification } from "./shared";
|
||||||
|
import { fly } from "svelte/transition";
|
||||||
|
|
||||||
|
export let notification: Partial<Notification> & { uid: string };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="border rounded-lg bg-white shadow-md flex flex-row border-l-8" in:fly={{x: 200, duration: 200}} out:fly={{x: 200, duration: 200}}
|
||||||
|
class:border-l-red-400={notification.type == "error"}
|
||||||
|
class:border-l-blue-400={notification.type == "info"}
|
||||||
|
class:border-l-green-400={notification.type == "success"}
|
||||||
|
class:border-l-yellow-400={notification.type == "warning"}
|
||||||
|
>
|
||||||
|
<div class="flex flex-col px-4 py-2">
|
||||||
|
<h2 class="text-xl font-semibold">{@html notification.message}</h2>
|
||||||
|
<p class="text-gray-600 text-lg"><slot></slot></p>
|
||||||
|
</div>
|
||||||
|
{#if notification.dismissable}
|
||||||
|
<button
|
||||||
|
class="border-l px-4 py-2 hover:bg-gray-100"
|
||||||
|
on:click={() => {
|
||||||
|
deleteNotification(notification.uid);
|
||||||
|
if (notification.onUserDismiss) {
|
||||||
|
notification.onUserDismiss()
|
||||||
|
}
|
||||||
|
}}>X</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:global(a) {
|
||||||
|
@apply text-blue-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(a:hover) {
|
||||||
|
@apply underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(kbd) {
|
||||||
|
@apply rounded-lg shadow-md border bg-gray-50 px-1.5 py-1 text-sm;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="fixed right-8 bottom-8 max-w-[400px] flex flex-col gap-4 z-50">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
80
src/components/Notifications/shared.ts
Normal file
80
src/components/Notifications/shared.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import { Writable, writable } from "svelte/store";
|
||||||
|
import { v4 as uuid } from "uuid";
|
||||||
|
|
||||||
|
export const notifications: Writable<Record<string, Notification>> = writable({});
|
||||||
|
|
||||||
|
const defaults = {
|
||||||
|
message: "",
|
||||||
|
dismissable: false,
|
||||||
|
timeout: 4000,
|
||||||
|
subtext: "",
|
||||||
|
type: "error",
|
||||||
|
onUserDismiss: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface Notification {
|
||||||
|
message: string;
|
||||||
|
dismissable: boolean;
|
||||||
|
timeout: number;
|
||||||
|
subtext: string;
|
||||||
|
type: "error" | "success" | "info" | "warning";
|
||||||
|
onUserDismiss: () => any;
|
||||||
|
uid?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateNotification(uid: string, updater: Partial<Notification>) {
|
||||||
|
notifications.update((value) => {
|
||||||
|
value[uid] = { ...defaults, ...value[uid], ...updater } as Notification;
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addNotification(notification: Partial<Notification>): string {
|
||||||
|
let uid = uuid();
|
||||||
|
|
||||||
|
if (notification.uid) {
|
||||||
|
uid = notification.uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const object: Notification = { ...defaults, ...notification } as Notification;
|
||||||
|
|
||||||
|
notifications.update((value) => {
|
||||||
|
value[uid] = object;
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
|
||||||
|
if (object.timeout) {
|
||||||
|
setTimeout(() => {
|
||||||
|
deleteNotification(uid);
|
||||||
|
}, object.timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteNotification(uid: string) {
|
||||||
|
notifications.update((value) => {
|
||||||
|
delete value[uid];
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showLinkedElement(query: string) {
|
||||||
|
const element = document.querySelector(query);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.classList.add("linked");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hideLinkedElement(query: string) {
|
||||||
|
const element = document.querySelector(query);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.classList.remove("linked");
|
||||||
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let password: string;
|
import { addNotification } from "./Notifications/shared";
|
||||||
|
|
||||||
|
let passwort: string;
|
||||||
let email: string;
|
let email: string;
|
||||||
let hasError: boolean;
|
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
const response = await fetch("/api/user", {
|
const response = await fetch("/api/user", {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
password, email
|
passwort, email
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -16,19 +17,22 @@
|
|||||||
if (json.success == true) {
|
if (json.success == true) {
|
||||||
window.location.href = "/login";
|
window.location.href = "/login";
|
||||||
} else {
|
} else {
|
||||||
hasError = true;
|
addNotification({
|
||||||
|
message: "Ups...",
|
||||||
|
subtext: "Da ist wohl etwas schiefgelaufen... Diese Email Adresse ist bereits in Benutzung, haben sie vielleicht bereits ein Konto bei uns?",
|
||||||
|
type: "error",
|
||||||
|
timeout: 0,
|
||||||
|
dismissable: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style="width:50%;margin: 0 auto">
|
<div style="width:50%;margin: 0 auto">
|
||||||
<h1>Registrieren:</h1>
|
<h1>Registrieren:</h1>
|
||||||
<div class="login_page">
|
<div class="flex flex-col gap-4">
|
||||||
{#if hasError}
|
<div>
|
||||||
<p>Leider ist diese Email bereits vergeben.</p>
|
<h4>Email</h4>
|
||||||
{/if}
|
|
||||||
<div class="block_4" style="margin-top: 25px;">
|
|
||||||
<h4 class="heading_3">Email</h4>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
@@ -37,26 +41,23 @@
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="block_4">
|
<div>
|
||||||
<h4 class="heading_3">Passwort</h4>
|
<h4>Passwort</h4>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="********"
|
placeholder="********"
|
||||||
class="formInput"
|
class="formInput"
|
||||||
bind:value={password}
|
bind:value={passwort}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 flex flex-row justify-between">
|
<button class="button" on:click={login}
|
||||||
<button on:click={login}
|
|
||||||
>Registrieren</button
|
>Registrieren</button
|
||||||
>
|
>
|
||||||
<a class="button"
|
<div class="flex-row justify-between" style="margin-top: 10px">
|
||||||
|
<a
|
||||||
href="/login">Einloggen</a
|
href="/login">Einloggen</a
|
||||||
>
|
>
|
||||||
</div>
|
|
||||||
<div class="flex-row justify-between" style="margin-top: 10px">
|
|
||||||
<a href="/">Home</a>
|
|
||||||
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
|
<a href="/user/passwort_vergessen">Passwort Vergessen?</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="left-sidebar">
|
<div class="flex flex-col gap-6">
|
||||||
<nav>
|
<nav>
|
||||||
<div class="nav-card">
|
<div class="nav-card">
|
||||||
<div class="card-menu-option dropdown">
|
<div class="card-menu-option dropdown">
|
||||||
@@ -159,13 +159,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.nav-card {
|
||||||
|
@apply rounded-lg w-full flex flex-col shadow-md border;
|
||||||
|
}
|
||||||
|
|
||||||
.infoCard {
|
.infoCard {
|
||||||
@apply bg-white rounded-none;
|
@apply bg-white rounded-lg border p-4 shadow-md;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content > .card-menu-option,
|
.dropdown-content > .card-menu-option,
|
||||||
.dropdown-content > a {
|
.dropdown-content > a {
|
||||||
@apply block w-[350px] bg-gray-100 border text-lg px-4 py-2;
|
@apply block w-[350px] bg-gray-50 border text-lg px-4 py-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content > a:first-child {
|
||||||
|
@apply rounded-tr-lg rounded-tl-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content > a:last-child {
|
||||||
|
@apply rounded-br-lg rounded-bl-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content > .card-menu-option:hover,
|
.dropdown-content > .card-menu-option:hover,
|
||||||
@@ -175,7 +187,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content {
|
.dropdown-content {
|
||||||
@apply absolute bg-white left-full top-[-1px] shadow-md z-10 hidden;
|
@apply absolute bg-white left-full top-[-1px] shadow-md z-10 hidden rounded-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown:hover > .dropdown-content {
|
.dropdown:hover > .dropdown-content {
|
||||||
@@ -231,15 +243,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-card .card-menu-option:first-child {
|
.nav-card .card-menu-option:first-child {
|
||||||
border-top: 0px solid #fff;
|
@apply rounded-tr-lg rounded-tl-lg;
|
||||||
border-top-left-radius: 0px;
|
|
||||||
border-top-right-radius: 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-card .card-menu-option:last-child {
|
.nav-card .card-menu-option:last-child {
|
||||||
border-bottom: 0px solid #fff;
|
@apply rounded-br-lg rounded-bl-lg;
|
||||||
border-bottom-left-radius: 0px;
|
|
||||||
border-bottom-right-radius: 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-card .card-menu-option a {
|
.nav-card .card-menu-option a {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="right-sidebar">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="infoCard">
|
<div class="infoCard">
|
||||||
<h2 style="font-weight: bold; font-size: 1.2em; color: #3A4AB5;">
|
<h2 style="font-weight: bold; font-size: 1.2em; color: #3A4AB5;">
|
||||||
Rufen Sie uns an<br /> Wir sind gerne für Sie da
|
Rufen Sie uns an<br /> Wir sind gerne für Sie da
|
||||||
@@ -128,6 +128,6 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.infoCard {
|
.infoCard {
|
||||||
@apply bg-white rounded-none;
|
@apply bg-white rounded-lg border p-4 shadow-md;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
89
src/components/TagInput.svelte
Normal file
89
src/components/TagInput.svelte
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Writable, writable } from "svelte/store";
|
||||||
|
|
||||||
|
let tag = "";
|
||||||
|
|
||||||
|
export let tags: Writable<string[]> = writable([]);
|
||||||
|
export let addKeys: number[] = [13];
|
||||||
|
export let maxTags: number;
|
||||||
|
export let onlyUnique: boolean = false;
|
||||||
|
export let removeKeys: number[] = [8];
|
||||||
|
export let placeholder: string = "";
|
||||||
|
export let allowPaste: boolean = true;
|
||||||
|
export let allowDrop: boolean = false;
|
||||||
|
export let splitWith: string = ",";
|
||||||
|
export let name: string = "";
|
||||||
|
export let id: string = "";
|
||||||
|
export let allowBlur: boolean = true;
|
||||||
|
export let disable: boolean = false;
|
||||||
|
export let minChars: number = 0;
|
||||||
|
export let labelText;
|
||||||
|
export let labelShow;
|
||||||
|
export let readonly: boolean = false;
|
||||||
|
export let onTagClick: Function;
|
||||||
|
export let onFocusIn: () => any;
|
||||||
|
export let onFocusOut: () => any;
|
||||||
|
export let className: string;
|
||||||
|
|
||||||
|
function addTag(tag: string) {
|
||||||
|
if (onlyUnique && $tags.indexOf(tag) > -1) {
|
||||||
|
tag = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tags.update(value => {
|
||||||
|
return [...value, tag];
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTag(i: number) {
|
||||||
|
tags.update(value => {
|
||||||
|
value.splice(i, 1)
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeydown(e: KeyboardEvent) {
|
||||||
|
if (addKeys.indexOf(e.keyCode) > -1) {
|
||||||
|
e.preventDefault();
|
||||||
|
addTag(tag);
|
||||||
|
tag = "";
|
||||||
|
} else if (removeKeys.indexOf(e.keyCode) > -1 && tag.length == 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
removeTag($tags.length - 1);
|
||||||
|
tag = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex flex-row gap-1 input"
|
||||||
|
style="padding: 0 !important;"
|
||||||
|
>
|
||||||
|
{#if $tags.length > 0}
|
||||||
|
{#each $tags as tag, i}
|
||||||
|
<button class="rounded-lg bg-white px-1.5 border flex flex-row items-center justify-between gap-2" on:click={onTagClick(tag)}>
|
||||||
|
{tag}
|
||||||
|
{#if !disable && !readonly}
|
||||||
|
<span
|
||||||
|
class="svelte-tags-input-tag-remove"
|
||||||
|
on:pointerdown={() => removeTag(i)}
|
||||||
|
>
|
||||||
|
×</span
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={tag}
|
||||||
|
on:keydown={onKeydown}
|
||||||
|
on:focusin={onFocusIn}
|
||||||
|
on:focusout={onFocusOut}
|
||||||
|
class="border-none h-full w-full {className}"
|
||||||
|
disabled={disable || readonly}
|
||||||
|
autocomplete="off"
|
||||||
|
{...$$restProps}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
@@ -11,44 +11,57 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import BilderZusatzsysteme from "../Ausweis/BilderZusatzsysteme.svelte";
|
import BilderZusatzsysteme from "../Ausweis/BilderZusatzsysteme.svelte";
|
||||||
import { Gebaeude } from "src/lib/Gebaeude";
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
|
import { hideLinkedElement, notifications } from "../Notifications/shared";
|
||||||
|
import { gebaeude } from "./shared";
|
||||||
|
import RawNotificationWrapper from "../Notifications/RawNotificationWrapper.svelte";
|
||||||
|
import RawNotification from "../Notifications/RawNotification.svelte";
|
||||||
|
import { auditHeizungGebaeudeBaujahr } from "./audits/HeizungGebaeudeBaujahr";
|
||||||
|
import { AuditType, hidden } from "./audits/hidden";
|
||||||
|
import { auditBedarfsausweisBenoetigt } from "./audits/BedarfsausweisBenoetigt";
|
||||||
|
import { auditVerbrauchAbweichung } from "./audits/VerbrauchAbweichung";
|
||||||
|
|
||||||
export let gebaeude: Gebaeude;
|
export let uid: string = "";
|
||||||
|
|
||||||
|
gebaeude.set(new Gebaeude());
|
||||||
|
$gebaeude.ausweis = new Verbrauchsausweis();
|
||||||
|
$gebaeude.ausweis.gebaeude = $gebaeude;
|
||||||
|
if (uid) {
|
||||||
|
(async () => {
|
||||||
|
const result = await fetch(`/api/verbrauchsausweis?uid=${uid}`, {
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
|
||||||
$: ausweis = gebaeude.ausweis || new Verbrauchsausweis();
|
const json = await result.json();
|
||||||
|
|
||||||
let needsRequirementCertificate: boolean = false;
|
if (json.success) {
|
||||||
|
gebaeude.set(new Gebaeude(json.data.gebaeude));
|
||||||
|
$gebaeude.ausweis = new Verbrauchsausweis(json.data.ausweis);
|
||||||
|
$gebaeude.ausweis.gebaeude = $gebaeude;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
$: needsRequirementCertificate =
|
$: ausweis = $gebaeude.ausweis || new Verbrauchsausweis();
|
||||||
(gebaeude.baujahr < 1978 &&
|
|
||||||
gebaeude.einheiten <= 4 &&
|
|
||||||
gebaeude.saniert == false &&
|
|
||||||
(ausweis.ausstellgrund == "Vermietung" ||
|
|
||||||
ausweis.ausstellgrund == "Sonstiges")) ||
|
|
||||||
ausweis.ausstellgrund == "Neubau" ||
|
|
||||||
ausweis.ausstellgrund == "Modernisierung" ||
|
|
||||||
ausweis.ausstellgrund == "Verkauf";
|
|
||||||
|
|
||||||
function automatischAusfüllen() {
|
function automatischAusfüllen() {
|
||||||
gebaeude.baujahr = 1962;
|
$gebaeude.baujahr = 1962;
|
||||||
ausweis.baujahr_anlage = 1974;
|
ausweis.baujahr_anlage = 1952;
|
||||||
gebaeude.saniert = true;
|
$gebaeude.saniert = true;
|
||||||
gebaeude.einheiten = 1;
|
$gebaeude.einheiten = 1;
|
||||||
ausweis.ausstellgrund = "Vermietung";
|
ausweis.ausstellgrund = "Vermietung";
|
||||||
ausweis.kennwerte.verbrauch_1 = 15000;
|
ausweis.kennwerte.verbrauch_1 = 15000;
|
||||||
ausweis.kennwerte.verbrauch_2 = 14000;
|
ausweis.kennwerte.verbrauch_2 = 14000;
|
||||||
ausweis.kennwerte.verbrauch_3 = 16000;
|
ausweis.kennwerte.verbrauch_3 = 16000;
|
||||||
gebaeude.wohnflaeche = 152;
|
$gebaeude.wohnflaeche = 152;
|
||||||
gebaeude.keller_beheizt = true;
|
$gebaeude.keller_beheizt = true;
|
||||||
ausweis.kennwerte.energietraeger_1 = "Erdgas H";
|
ausweis.kennwerte.energietraeger_1 = "Erdgas H";
|
||||||
ausweis.kennwerte.einheit_1 = "kWh";
|
ausweis.kennwerte.einheit_1 = "kWh";
|
||||||
ausweis.kennwerte.anteil_warmwasser_1 = 18;
|
ausweis.kennwerte.anteil_warmwasser_1 = 18;
|
||||||
ausweis.kennwerte.zeitraum = moment("12.01.2019");
|
ausweis.kennwerte.zeitraum = moment("12.01.2019");
|
||||||
gebaeude.plz = "21039";
|
$gebaeude.plz = "21039";
|
||||||
gebaeude.ort = "Hamburg";
|
$gebaeude.ort = "Hamburg";
|
||||||
gebaeude.strasse = "Curslacker Deich 170";
|
$gebaeude.strasse = "Curslacker Deich 170";
|
||||||
gebaeude.gebaeudeteil = "Gesamtgebäude";
|
$gebaeude.gebaeudeteil = "Gesamtgebäude";
|
||||||
//ausweis.upload();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -81,29 +94,7 @@
|
|||||||
|
|
||||||
<Label>A - Prüfung der Ausweisart</Label>
|
<Label>A - Prüfung der Ausweisart</Label>
|
||||||
|
|
||||||
<Ausweisart bind:gebaeude />
|
<Ausweisart bind:gebaeude={$gebaeude} />
|
||||||
|
|
||||||
<div
|
|
||||||
class="flex flex-col p-4"
|
|
||||||
class:hidden={!needsRequirementCertificate}
|
|
||||||
>
|
|
||||||
<div class="form-group col-md-9">
|
|
||||||
<HelpLabel
|
|
||||||
title="Sie benötigen einen Bedarfsausweis. Bitte führen Sie hier Ihre Eingabe für den Bedarfsausweis fort und klicken auf den Button:"
|
|
||||||
>
|
|
||||||
Der Bedarfsausweis ist die etwas umfangreichere Berechnung.
|
|
||||||
Sie benötigen z.B. Länge, Breite und Geschoßhöhe des
|
|
||||||
Gebäudes. Auch müssen genauere Angaben zur Anlagentechnik
|
|
||||||
gemacht werden.
|
|
||||||
</HelpLabel>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-md-3">
|
|
||||||
<a class="button" href="/bedarfsausweis"
|
|
||||||
>Bedarfsausweis erstellen</a
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
@@ -128,7 +119,7 @@
|
|||||||
required
|
required
|
||||||
data-msg-minlength="min. 5 Zeichen"
|
data-msg-minlength="min. 5 Zeichen"
|
||||||
data-msg-maxlength="max. 40 Zeichen"
|
data-msg-maxlength="max. 40 Zeichen"
|
||||||
bind:value={gebaeude.strasse}
|
bind:value={$gebaeude.strasse}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,8 +127,8 @@
|
|||||||
<!-- PLZ -->
|
<!-- PLZ -->
|
||||||
<div class="form-group col-md-4 PLZ">
|
<div class="form-group col-md-4 PLZ">
|
||||||
<ZipSearch
|
<ZipSearch
|
||||||
bind:zip={gebaeude.plz}
|
bind:zip={$gebaeude.plz}
|
||||||
bind:city={gebaeude.ort}
|
bind:city={$gebaeude.ort}
|
||||||
name="zip"
|
name="zip"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -151,7 +142,7 @@
|
|||||||
<input
|
<input
|
||||||
name="IGort"
|
name="IGort"
|
||||||
readonly={true}
|
readonly={true}
|
||||||
bind:value={gebaeude.ort}
|
bind:value={$gebaeude.ort}
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -173,7 +164,7 @@
|
|||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
data-rule-minlength="2"
|
data-rule-minlength="2"
|
||||||
data-msg-minlength="min. 2 Zeichen"
|
data-msg-minlength="min. 2 Zeichen"
|
||||||
bind:value={gebaeude.wohnflaeche}
|
bind:value={$gebaeude.wohnflaeche}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -185,7 +176,7 @@
|
|||||||
<select
|
<select
|
||||||
name="IGkeller"
|
name="IGkeller"
|
||||||
required
|
required
|
||||||
bind:value={gebaeude.keller_beheizt}
|
bind:value={$gebaeude.keller_beheizt}
|
||||||
>
|
>
|
||||||
<option>Bitte auswählen</option>
|
<option>Bitte auswählen</option>
|
||||||
<option value={false}>nicht vorhanden</option>
|
<option value={false}>nicht vorhanden</option>
|
||||||
@@ -214,7 +205,7 @@
|
|||||||
<Label>C - Eingabe von 3 zusammenhängenden Verbrauchsjahren</Label>
|
<Label>C - Eingabe von 3 zusammenhängenden Verbrauchsjahren</Label>
|
||||||
|
|
||||||
<div class="GRB">
|
<div class="GRB">
|
||||||
<Verbrauch bind:ausweis />
|
<Verbrauch bind:gebaeude={$gebaeude} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -287,7 +278,7 @@
|
|||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="IGversorgungssysteme1"
|
name="IGversorgungssysteme1"
|
||||||
bind:checked={gebaeude.energiequelle_2_nutzung[0]}
|
bind:checked={$gebaeude.energiequelle_2_nutzung[0]}
|
||||||
value="Heizung"
|
value="Heizung"
|
||||||
/>Heizung</label
|
/>Heizung</label
|
||||||
>
|
>
|
||||||
@@ -295,7 +286,7 @@
|
|||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="IGversorgungssysteme2"
|
name="IGversorgungssysteme2"
|
||||||
bind:checked={gebaeude.energiequelle_2_nutzung[1]}
|
bind:checked={$gebaeude.energiequelle_2_nutzung[1]}
|
||||||
value="Warmwasser"
|
value="Warmwasser"
|
||||||
/>Warmwasser</label
|
/>Warmwasser</label
|
||||||
>
|
>
|
||||||
@@ -303,7 +294,7 @@
|
|||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="IGversorgungssysteme3"
|
name="IGversorgungssysteme3"
|
||||||
bind:checked={gebaeude.energiequelle_2_nutzung[2]}
|
bind:checked={$gebaeude.energiequelle_2_nutzung[2]}
|
||||||
value="Lüftung"
|
value="Lüftung"
|
||||||
/>Lüftung</label
|
/>Lüftung</label
|
||||||
>
|
>
|
||||||
@@ -311,7 +302,7 @@
|
|||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="IGversorgungssysteme4"
|
name="IGversorgungssysteme4"
|
||||||
bind:checked={gebaeude.energiequelle_2_nutzung[3]}
|
bind:checked={$gebaeude.energiequelle_2_nutzung[3]}
|
||||||
value="Kühlung"
|
value="Kühlung"
|
||||||
/>Kühlung</label
|
/>Kühlung</label
|
||||||
>
|
>
|
||||||
@@ -450,7 +441,7 @@
|
|||||||
>F - Bitte prüfen Sie hier die Angaben zum Sanierungszustand des
|
>F - Bitte prüfen Sie hier die Angaben zum Sanierungszustand des
|
||||||
Gebäudes</Label
|
Gebäudes</Label
|
||||||
>
|
>
|
||||||
<BilderZusatzsysteme {gebaeude} />
|
<BilderZusatzsysteme gebaeude={$gebaeude} />
|
||||||
<hr />
|
<hr />
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<Hilfe />
|
<Hilfe />
|
||||||
@@ -458,3 +449,63 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<RawNotificationWrapper>
|
||||||
|
|
||||||
|
{#each Object.entries($notifications) as [uid, notification] (uid)}
|
||||||
|
<RawNotification notification={{...notification, uid }}>
|
||||||
|
{@html notification.subtext}
|
||||||
|
</RawNotification>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
{#if auditBedarfsausweisBenoetigt($gebaeude)}
|
||||||
|
<RawNotification notification={{
|
||||||
|
message: "Bedarfsausweis benötigt!",
|
||||||
|
timeout: 0,
|
||||||
|
uid: "BEDARFSAUSWEIS",
|
||||||
|
dismissable: false,
|
||||||
|
type: "info"
|
||||||
|
}}>
|
||||||
|
Sie benötigen einen Bedarfsausweis. <a href='/bedarfsausweis'>Bitte führen Sie hier Ihre Eingabe für den Bedarfsausweis fort</a>.
|
||||||
|
</RawNotification>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if auditHeizungGebaeudeBaujahr($gebaeude)}
|
||||||
|
<RawNotification notification={{
|
||||||
|
message: "Plausibilitätsprüfung",
|
||||||
|
timeout: 0,
|
||||||
|
uid: "HEIZUNG_VOR_GEBAEUDE",
|
||||||
|
dismissable: true,
|
||||||
|
onUserDismiss: () => {
|
||||||
|
hidden.add(AuditType.HEIZUNG_GEBAEUDE_BAUJAHR)
|
||||||
|
$gebaeude = $gebaeude;
|
||||||
|
},
|
||||||
|
type: "warning"
|
||||||
|
}}>
|
||||||
|
Sie haben angegeben, dass ihre Heizung vor ihrem Gebäude konstruiert wurde. Sind sie sich sicher, dass das stimmt?
|
||||||
|
</RawNotification>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if auditVerbrauchAbweichung($gebaeude).length > 0}
|
||||||
|
<RawNotification notification={{
|
||||||
|
message: "Plausibilitätsprüfung",
|
||||||
|
timeout: 0,
|
||||||
|
uid: "VERBRAUCH_ABWEICHUNG",
|
||||||
|
dismissable: true,
|
||||||
|
onUserDismiss: () => {
|
||||||
|
hidden.add(AuditType.VERBRAUCH_ABWEICHUNG)
|
||||||
|
$gebaeude = $gebaeude;
|
||||||
|
},
|
||||||
|
type: "warning"
|
||||||
|
}}>
|
||||||
|
Die Abweichung der Verbräuche zwischen Zeitraum {auditVerbrauchAbweichung($gebaeude)[0]} und {auditVerbrauchAbweichung($gebaeude)[1]} beträgt mehr als 25% und sie haben keinen Leerstand angegeben. Sind sie sich sicher, dass das stimmt?
|
||||||
|
</RawNotification>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
</RawNotificationWrapper>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:global(.linked) {
|
||||||
|
@apply border-2 border-red-400;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
41
src/components/Verbrauchsausweis/audits.ts
Normal file
41
src/components/Verbrauchsausweis/audits.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
export function lookupAudit(audit: keyof typeof audits): boolean {
|
||||||
|
if (!audits.hasOwnProperty(audit)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const valid = audits[audit].validator(hidden);
|
||||||
|
|
||||||
|
if (valid && !hidden.has(audit)) {
|
||||||
|
audits[audit].trueAction(hidden);
|
||||||
|
} else {
|
||||||
|
audits[audit].falseAction(hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Action = (x: typeof hidden) => void;
|
||||||
|
|
||||||
|
export function addAudit(
|
||||||
|
name: string,
|
||||||
|
validator: (x: typeof hidden) => boolean,
|
||||||
|
trueAction: Action,
|
||||||
|
falseAction: Action
|
||||||
|
) {
|
||||||
|
audits[name] = {
|
||||||
|
validator,
|
||||||
|
trueAction,
|
||||||
|
falseAction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const audits: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
validator: (x: typeof hidden) => boolean;
|
||||||
|
trueAction: Action;
|
||||||
|
falseAction: Action;
|
||||||
|
}
|
||||||
|
> = {};
|
||||||
|
|
||||||
|
export const hidden: Set<keyof typeof audits> = new Set();
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
|
|
||||||
|
export function auditBedarfsausweisBenoetigt(gebaeude: Gebaeude): boolean {
|
||||||
|
let ausweis = gebaeude.ausweis;
|
||||||
|
if (!ausweis) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((gebaeude.baujahr < 1978 &&
|
||||||
|
gebaeude.einheiten <= 4 &&
|
||||||
|
gebaeude.saniert == false &&
|
||||||
|
(ausweis.ausstellgrund == "Vermietung" ||
|
||||||
|
ausweis.ausstellgrund == "Sonstiges")) ||
|
||||||
|
ausweis.ausstellgrund == "Neubau" ||
|
||||||
|
ausweis.ausstellgrund == "Modernisierung" ||
|
||||||
|
ausweis.ausstellgrund == "Verkauf");
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
|
import { AuditType, hidden } from "../audits/hidden";
|
||||||
|
|
||||||
|
export function auditHeizungGebaeudeBaujahr(gebaeude: Gebaeude): boolean {
|
||||||
|
let ausweis = gebaeude.ausweis;
|
||||||
|
if (!ausweis) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ausweis.baujahr_anlage > 1500 &&
|
||||||
|
gebaeude.baujahr > 1500 &&
|
||||||
|
ausweis.baujahr_anlage < gebaeude.baujahr
|
||||||
|
&& !hidden.has(AuditType.HEIZUNG_GEBAEUDE_BAUJAHR)
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
|
import { AuditType, hidden } from "./hidden";
|
||||||
|
|
||||||
|
export function auditVerbrauchAbweichung(gebaeude: Gebaeude): number[] {
|
||||||
|
let ausweis = gebaeude.ausweis;
|
||||||
|
if (!ausweis || gebaeude.leerstand > 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hidden.has(AuditType.VERBRAUCH_ABWEICHUNG)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAbweichung(ausweis.kennwerte.verbrauch_1, ausweis.kennwerte.verbrauch_2) > 0.25) {
|
||||||
|
return [1, 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAbweichung(ausweis.kennwerte.verbrauch_2, ausweis.kennwerte.verbrauch_3) > 0.25) {
|
||||||
|
return [2, 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAbweichung(ausweis.kennwerte.verbrauch_4, ausweis.kennwerte.verbrauch_5) > 0.25) {
|
||||||
|
return [4, 5];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getAbweichung(ausweis.kennwerte.verbrauch_5, ausweis.kennwerte.verbrauch_6) > 0.25) {
|
||||||
|
return [5, 6];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAbweichung(x: number, y: number): number {
|
||||||
|
console.log(x, y, Math.abs((x - y) / ((x + y) / 2)));
|
||||||
|
|
||||||
|
return Math.abs((x - y) / ((x + y) / 2));
|
||||||
|
}
|
||||||
6
src/components/Verbrauchsausweis/audits/hidden.ts
Normal file
6
src/components/Verbrauchsausweis/audits/hidden.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export const hidden = new Set<AuditType>()
|
||||||
|
|
||||||
|
export enum AuditType {
|
||||||
|
HEIZUNG_GEBAEUDE_BAUJAHR,
|
||||||
|
VERBRAUCH_ABWEICHUNG
|
||||||
|
}
|
||||||
4
src/components/Verbrauchsausweis/shared.ts
Normal file
4
src/components/Verbrauchsausweis/shared.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
|
import { Writable, writable } from "svelte/store";
|
||||||
|
|
||||||
|
export const gebaeude: Writable<Gebaeude> = writable();
|
||||||
@@ -3,7 +3,7 @@ import "../style/global.scss"
|
|||||||
import Footer from '../components/Footer.astro';
|
import Footer from '../components/Footer.astro';
|
||||||
import Header from '../components/Header.astro';
|
import Header from '../components/Header.astro';
|
||||||
import SidebarLeft from '../components/SidebarLeft.astro';
|
import SidebarLeft from '../components/SidebarLeft.astro';
|
||||||
import SidebarRight from '../components/SidebarRight.astro';
|
import NotificationWrapper from "~/components/Notifications/NotificationWrapper.svelte";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -110,8 +110,8 @@ const schema = JSON.stringify({
|
|||||||
@apply text-xl font-medium mt-6 mb-4;
|
@apply text-xl font-medium mt-6 mb-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
input, select, textarea {
|
input, select, textarea, .input {
|
||||||
@apply py-1.5 px-2.5 rounded-lg w-full outline-none text-base text-slate-800 border;
|
@apply py-1.5 px-2.5 rounded-lg w-full outline-none text-base text-slate-800 border bg-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:disabled, input:read-only, select:disabled {
|
input:disabled, input:read-only, select:disabled {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Footer from '../components/Footer.astro';
|
|||||||
import Header from '../components/Header.astro';
|
import Header from '../components/Header.astro';
|
||||||
import SidebarLeft from '../components/SidebarLeft.astro';
|
import SidebarLeft from '../components/SidebarLeft.astro';
|
||||||
import SidebarRight from '../components/SidebarRight.astro';
|
import SidebarRight from '../components/SidebarRight.astro';
|
||||||
|
import NotificationWrapper from "~/components/Notifications/NotificationWrapper.svelte";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -94,6 +95,7 @@ const schema = JSON.stringify({
|
|||||||
<SidebarRight></SidebarRight>
|
<SidebarRight></SidebarRight>
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
<NotificationWrapper client:load></NotificationWrapper>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ const schema = JSON.stringify({
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
button, .button {
|
.button {
|
||||||
@apply px-8 py-2 bg-secondary rounded-lg text-white font-medium hover:shadow-lg transition-all hover:underline active:bg-blue-900 text-center cursor-pointer;
|
@apply px-8 py-2 bg-secondary rounded-lg text-white font-medium hover:shadow-lg transition-all hover:underline active:bg-blue-900 text-center cursor-pointer;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
@@ -112,7 +114,11 @@ const schema = JSON.stringify({
|
|||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@apply py-1 px-2 w-full rounded-lg outline-none text-lg text-slate-800 border;
|
@apply py-1.5 px-4 w-full rounded-lg outline-none text-lg text-slate-700 border bg-gray-50 transition-colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover, input:focus {
|
||||||
|
@apply bg-gray-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export class Verbrauchsausweis {
|
|||||||
public warmwasser_enthalten: boolean = true;
|
public warmwasser_enthalten: boolean = true;
|
||||||
public id?: number;
|
public id?: number;
|
||||||
public uid?: string;
|
public uid?: string;
|
||||||
public baujahr_anlage: number = 0;
|
public baujahr_anlage: number[] = [];
|
||||||
|
|
||||||
public get energetische_nutzfläche(): number {
|
public get energetische_nutzfläche(): number {
|
||||||
return (
|
return (
|
||||||
@@ -24,7 +24,12 @@ export class Verbrauchsausweis {
|
|||||||
public kennwerte: Energiekennwerte = new Energiekennwerte();
|
public kennwerte: Energiekennwerte = new Energiekennwerte();
|
||||||
public gebaeude: Gebaeude = new Gebaeude();
|
public gebaeude: Gebaeude = new Gebaeude();
|
||||||
|
|
||||||
public constructor() {}
|
public constructor(initializer?: Verbrauchsausweis) {
|
||||||
|
if (initializer) {
|
||||||
|
this.ausweisart = initializer.ausweisart;
|
||||||
|
this.kennwerte = initializer.kennwerte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static fromBase64(base64: string): Verbrauchsausweis | null {
|
public static fromBase64(base64: string): Verbrauchsausweis | null {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import { Ausweis } from "./Ausweis/Ausweis";
|
import { Ausweis } from "./Ausweis/Ausweis";
|
||||||
|
import { Verbrauchsausweis } from "./Ausweis/Verbrauchsausweis";
|
||||||
import { Dachgeschoss, Lueftungskonzept } from "./Ausweis/types";
|
import { Dachgeschoss, Lueftungskonzept } from "./Ausweis/types";
|
||||||
import { BitChecker } from "./BitChecker";
|
import { BitChecker } from "./BitChecker";
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ export class Gebaeude {
|
|||||||
public energiequelle_2_nutzung: boolean[] = BitChecker(0);
|
public energiequelle_2_nutzung: boolean[] = BitChecker(0);
|
||||||
public daemmung: boolean[] = BitChecker(0);
|
public daemmung: boolean[] = BitChecker(0);
|
||||||
|
|
||||||
public ausweis?: Ausweis;
|
public ausweis: Ausweis;
|
||||||
|
|
||||||
public uid?: string;
|
public uid?: string;
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export class User {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await db<UserType>("users").select("*").where("uid", uid).first();
|
const user = await db<UserType>("benutzer").select("*").where("uid", uid).first();
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return null;
|
return null;
|
||||||
@@ -29,7 +29,7 @@ export class User {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await db<UserType>("users").select("*").where("email", email).first();
|
const user = await db<UserType>("benutzer").select("*").where("email", email).first();
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return null;
|
return null;
|
||||||
@@ -48,7 +48,7 @@ export class User {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await db<UserType>("users").select("*").where("id", id).first();
|
const user = await db<UserType>("benutzer").select("*").where("id", id).first();
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return null;
|
return null;
|
||||||
@@ -63,11 +63,11 @@ export class User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uid = uuid();
|
const uid = uuid();
|
||||||
const hashedPassword = hashPassword(user.password);
|
const hashedPassword = hashPassword(user.passwort);
|
||||||
|
|
||||||
const result = await db<UserType>("users").insert({
|
const result = await db<UserType>("benutzer").insert({
|
||||||
email: user.email,
|
email: user.email,
|
||||||
password: hashedPassword,
|
passwort: hashedPassword,
|
||||||
uid: uid
|
uid: uid
|
||||||
}, ["id"])
|
}, ["id"])
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ export const UserTypeValidator = z.object({
|
|||||||
id: z.number(),
|
id: z.number(),
|
||||||
uid: z.string().length(36),
|
uid: z.string().length(36),
|
||||||
email: z.string().max(255),
|
email: z.string().max(255),
|
||||||
password: z.string().min(6),
|
passwort: z.string().min(6),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const UserRegisterValidator = z.object({
|
export const UserRegisterValidator = z.object({
|
||||||
email: z.string().max(255),
|
email: z.string().max(255),
|
||||||
password: z.string().min(6),
|
passwort: z.string().min(6),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type UserType = z.infer<typeof UserTypeValidator>
|
export type UserType = z.infer<typeof UserTypeValidator>
|
||||||
130
src/lib/client/Ausweis/Verbrauchsausweis.ts
Normal file
130
src/lib/client/Ausweis/Verbrauchsausweis.ts
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import { Ausstellgrund, Ausweisart } from "src/lib/Ausweis/types";
|
||||||
|
import { Energiekennwerte } from "src/lib/Energiekennwerte";
|
||||||
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
|
import { getKlimafaktorenClient } from "src/lib/Klimafaktoren";
|
||||||
|
import { getHeizwertfaktorClient } from "src/lib/server/Heizwertfaktor";
|
||||||
|
|
||||||
|
|
||||||
|
export default class Verbrauchsausweis {
|
||||||
|
public ausweisart: Ausweisart = "VA";
|
||||||
|
public ausstellgrund: Ausstellgrund = "Vermietung";
|
||||||
|
public warmwasser_enthalten: boolean = true;
|
||||||
|
public uid?: string;
|
||||||
|
public baujahr_anlage: number[] = [];
|
||||||
|
|
||||||
|
public get energetische_nutzfläche(): number {
|
||||||
|
return (
|
||||||
|
this.gebaeude.wohnflaeche *
|
||||||
|
(this.gebaeude.keller_beheizt ? 1.35 : 1.2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public regnummer?: string;
|
||||||
|
|
||||||
|
public kennwerte: Energiekennwerte = new Energiekennwerte();
|
||||||
|
public gebaeude: Gebaeude = new Gebaeude();
|
||||||
|
|
||||||
|
public constructor(initializer?: Verbrauchsausweis) {
|
||||||
|
if (initializer) {
|
||||||
|
this.ausweisart = initializer.ausweisart;
|
||||||
|
this.kennwerte = initializer.kennwerte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get primaer_energie_verbrauch(): Promise<number> {
|
||||||
|
return (async () => {
|
||||||
|
const Endenergieverbrauch = await this.end_energie_verbrauch;
|
||||||
|
|
||||||
|
const brennstoff_1 = getHeizwertfaktorClient(
|
||||||
|
this.kennwerte.energietraeger_1,
|
||||||
|
this.kennwerte.einheit_1
|
||||||
|
);
|
||||||
|
|
||||||
|
return Endenergieverbrauch * brennstoff_1.primärenergiefaktor;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get end_energie_verbrauch(): Promise<number> {
|
||||||
|
return (async () => {
|
||||||
|
const date = this.kennwerte.zeitraum;
|
||||||
|
const klimafaktoren = await getKlimafaktorenClient(
|
||||||
|
date,
|
||||||
|
this.gebaeude.plz
|
||||||
|
);
|
||||||
|
|
||||||
|
// Endenergieverbrauch
|
||||||
|
// Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden.
|
||||||
|
let brennstoff_1 = getHeizwertfaktorClient(
|
||||||
|
this.kennwerte.energietraeger_1,
|
||||||
|
this.kennwerte.einheit_1
|
||||||
|
);
|
||||||
|
let brennstoff_2 = getHeizwertfaktorClient(
|
||||||
|
this.kennwerte.energietraeger_2,
|
||||||
|
this.kennwerte.einheit_2
|
||||||
|
);
|
||||||
|
|
||||||
|
let verbrauch_1_kwh =
|
||||||
|
this.kennwerte.verbrauch_1 * brennstoff_1.umrechnungsfaktor;
|
||||||
|
let verbrauch_2_kwh =
|
||||||
|
this.kennwerte.verbrauch_2 * brennstoff_1.umrechnungsfaktor;
|
||||||
|
let verbrauch_3_kwh =
|
||||||
|
this.kennwerte.verbrauch_3 * brennstoff_1.umrechnungsfaktor;
|
||||||
|
let verbrauch_4_kwh =
|
||||||
|
this.kennwerte.verbrauch_4 * brennstoff_2.umrechnungsfaktor;
|
||||||
|
let verbrauch_5_kwh =
|
||||||
|
this.kennwerte.verbrauch_5 * brennstoff_2.umrechnungsfaktor;
|
||||||
|
let verbrauch_6_kwh =
|
||||||
|
this.kennwerte.verbrauch_6 * brennstoff_2.umrechnungsfaktor;
|
||||||
|
|
||||||
|
let warmwasserZuschlag = 0;
|
||||||
|
let leerstandsZuschlag = 0;
|
||||||
|
let kuehlungsZuschlag = 0;
|
||||||
|
if (this.kennwerte.anteil_warmwasser_1 == 0) {
|
||||||
|
warmwasserZuschlag = 20 * this.energetische_nutzfläche * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.gebaeude.leerstand > 0) {
|
||||||
|
let durchschnittsKlimafaktor =
|
||||||
|
klimafaktoren.reduce((a, b) => a + b, 0) / 3;
|
||||||
|
|
||||||
|
leerstandsZuschlag =
|
||||||
|
((verbrauch_1_kwh +
|
||||||
|
verbrauch_2_kwh +
|
||||||
|
verbrauch_3_kwh +
|
||||||
|
verbrauch_4_kwh +
|
||||||
|
verbrauch_5_kwh +
|
||||||
|
verbrauch_6_kwh) *
|
||||||
|
(this.gebaeude.leerstand / 100)) /
|
||||||
|
durchschnittsKlimafaktor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.gebaeude.energiequelle_2_nutzung[3]) {
|
||||||
|
kuehlungsZuschlag = 6 * this.energetische_nutzfläche * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
let anteil_heizung = 1 - this.kennwerte.anteil_warmwasser_1 / 100;
|
||||||
|
let anteil_warmwasser = this.kennwerte.anteil_warmwasser_1 / 100;
|
||||||
|
|
||||||
|
let Energieverbrauchskennwert =
|
||||||
|
(anteil_heizung *
|
||||||
|
(verbrauch_1_kwh + verbrauch_4_kwh) *
|
||||||
|
klimafaktoren[0] +
|
||||||
|
anteil_warmwasser * (verbrauch_1_kwh + verbrauch_4_kwh) +
|
||||||
|
anteil_heizung *
|
||||||
|
(verbrauch_2_kwh + verbrauch_5_kwh) *
|
||||||
|
klimafaktoren[1] +
|
||||||
|
anteil_warmwasser * (verbrauch_2_kwh + verbrauch_5_kwh) +
|
||||||
|
anteil_heizung *
|
||||||
|
(verbrauch_3_kwh + verbrauch_6_kwh) *
|
||||||
|
klimafaktoren[2] +
|
||||||
|
anteil_warmwasser * (verbrauch_3_kwh + verbrauch_6_kwh) +
|
||||||
|
warmwasserZuschlag +
|
||||||
|
leerstandsZuschlag +
|
||||||
|
kuehlungsZuschlag) /
|
||||||
|
3 /
|
||||||
|
this.energetische_nutzfläche;
|
||||||
|
|
||||||
|
return Energieverbrauchskennwert;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/lib/client/Ausweis/index.ts
Normal file
1
src/lib/client/Ausweis/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default as Verbrauchsausweis } from "./Verbrauchsausweis";
|
||||||
36
src/lib/client/Gebaeude/Gebaeude.ts
Normal file
36
src/lib/client/Gebaeude/Gebaeude.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { Ausweis } from "src/lib/Ausweis/Ausweis";
|
||||||
|
import { Dachgeschoss, Lueftungskonzept } from "src/lib/Ausweis/types";
|
||||||
|
import { BitChecker } from "src/lib/BitChecker";
|
||||||
|
|
||||||
|
export class Gebaeude {
|
||||||
|
public typ: string = "";
|
||||||
|
public plz: string = "";
|
||||||
|
public ort: string = "";
|
||||||
|
public strasse: string = "";
|
||||||
|
public gebaeudeteil: string = "";
|
||||||
|
public saniert: boolean = false;
|
||||||
|
public baujahr: number = 0;
|
||||||
|
public einheiten: number = 0;
|
||||||
|
public wohnflaeche: number = 0;
|
||||||
|
public keller_beheizt: boolean = false;
|
||||||
|
public dachgeschoss_beheizt: Dachgeschoss = Dachgeschoss.UNBEHEIZT;
|
||||||
|
public lueftungskonzept: Lueftungskonzept = "Fensterlüftung";
|
||||||
|
public wird_gekuehlt: boolean = false;
|
||||||
|
public leerstand: number = 0;
|
||||||
|
public versorgungssysteme: boolean[] = BitChecker(0);
|
||||||
|
public fenster_dach: boolean[] = BitChecker(0);
|
||||||
|
public energiequelle_2_nutzung: boolean[] = BitChecker(0);
|
||||||
|
public daemmung: boolean[] = BitChecker(0);
|
||||||
|
|
||||||
|
public ausweis?: Ausweis;
|
||||||
|
|
||||||
|
public uid?: string;
|
||||||
|
|
||||||
|
public constructor(initializer?: Gebaeude) {
|
||||||
|
if (initializer) {
|
||||||
|
this.typ = initializer.typ;
|
||||||
|
this.plz = initializer.plz;
|
||||||
|
this.ort = initializer.ort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/lib/client/Gebaeude/index.ts
Normal file
0
src/lib/client/Gebaeude/index.ts
Normal file
@@ -1,5 +1,8 @@
|
|||||||
import type { APIRoute } from "astro";
|
import type { APIRoute } from "astro";
|
||||||
import { ActionFailedError, error, success } from "src/lib/APIResponse";
|
import { ActionFailedError, MissingEntityError, error, success } from "src/lib/APIResponse";
|
||||||
|
import { Ausweis } from "src/lib/Ausweis/Ausweis";
|
||||||
|
import { Energiekennwerte } from "src/lib/Energiekennwerte";
|
||||||
|
import { Gebaeude } from "src/lib/Gebaeude";
|
||||||
import { db } from "src/lib/shared";
|
import { db } from "src/lib/shared";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -62,6 +65,10 @@ const AusweisUploadChecker = z.object({
|
|||||||
ausweis_uid: z.string().optional(),
|
ausweis_uid: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const AusweisDownloadChecker = z.object({
|
||||||
|
uid: z.string()
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt einen Verbrauchsausweis anhand der gegebenen Daten und trägt ihn in die Datenbank ein.
|
* Erstellt einen Verbrauchsausweis anhand der gegebenen Daten und trägt ihn in die Datenbank ein.
|
||||||
* @param param0
|
* @param param0
|
||||||
@@ -136,3 +143,39 @@ export const post: APIRoute = async ({ request }) => {
|
|||||||
gebaeude: gebaeude[0],
|
gebaeude: gebaeude[0],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const get: APIRoute = async ({ request }) => {
|
||||||
|
const body: z.infer<typeof AusweisDownloadChecker> = await request.json();
|
||||||
|
|
||||||
|
const validation = AusweisDownloadChecker.safeParse(body);
|
||||||
|
|
||||||
|
if (!validation.success) {
|
||||||
|
return error(validation.error.issues);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = await db<{ gebaeude: Gebaeude, kennwerte: Energiekennwerte, ausweis: Ausweis}>("gebaeude")
|
||||||
|
.select([
|
||||||
|
db.raw("(json_agg(gebaeude)->0) AS gebaeude"),
|
||||||
|
db.raw("(json_agg(energiekennwerte)->0) AS kennwerte"),
|
||||||
|
db.raw("(json_agg(energieausweise)->0) AS ausweis"),
|
||||||
|
])
|
||||||
|
.leftJoin(
|
||||||
|
"energiekennwerte",
|
||||||
|
"energiekennwerte.gebaeude_id",
|
||||||
|
"gebaeude.id"
|
||||||
|
)
|
||||||
|
.leftJoin(
|
||||||
|
"energieausweise",
|
||||||
|
"energieausweise.gebaeude_id",
|
||||||
|
"gebaeude.id"
|
||||||
|
)
|
||||||
|
.where("gebaeude.uid", body.uid)
|
||||||
|
.groupBy("gebaeude.id")
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return MissingEntityError("gebäude");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
@@ -23,7 +23,7 @@ export const post: APIRoute = async ({ request }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate Password
|
// Validate Password
|
||||||
if (!validatePassword(user.password, body.password)) {
|
if (!validatePassword(user.passwort, body.password)) {
|
||||||
return error(["Invalid email or password."]);
|
return error(["Invalid email or password."]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import type { APIRoute } from "astro";
|
import type { APIRoute } from "astro";
|
||||||
import { success, MissingPropertyError, MissingEntityError, ActionFailedError, InvalidDataError } from "../../lib/APIResponse";
|
import { success, MissingPropertyError, MissingEntityError, ActionFailedError, InvalidDataError, error } from "../../lib/APIResponse";
|
||||||
import { User } from "../../lib/User";
|
import { User } from "../../lib/User";
|
||||||
import { UserRegisterValidator, UserType, UserTypeValidator } from "../../lib/User/type";
|
import { UserRegisterValidator, UserType, UserTypeValidator } from "../../lib/User/type";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ruft einen Nutzer anhand seiner uid aus der Datenbank ab.
|
* Ruft einen Nutzer anhand seiner uid aus der Datenbank ab.
|
||||||
@@ -24,7 +25,7 @@ export const get: APIRoute = async ({ request }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const put: APIRoute = async ({ request }) => {
|
export const put: APIRoute = async ({ request }) => {
|
||||||
const body = await request.json();
|
const body: z.infer<typeof UserRegisterValidator> = await request.json();
|
||||||
|
|
||||||
const validate = UserRegisterValidator.safeParse(body);
|
const validate = UserRegisterValidator.safeParse(body);
|
||||||
|
|
||||||
@@ -32,6 +33,12 @@ export const put: APIRoute = async ({ request }) => {
|
|||||||
return InvalidDataError(validate.error);
|
return InvalidDataError(validate.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const user = await User.fromEmail(body.email);
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
return error(["Email address is already being used."]);
|
||||||
|
}
|
||||||
|
|
||||||
const result = await User.create(body as UserType);
|
const result = await User.create(body as UserType);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|||||||
@@ -1,44 +1,10 @@
|
|||||||
---
|
---
|
||||||
import AusweisLayout from "~/layouts/AusweisLayout.astro";
|
import AusweisLayout from "~/layouts/AusweisLayout.astro";
|
||||||
import VerbrauchsausweisContent from "~/components/Verbrauchsausweis/VerbrauchsausweisContent.svelte";
|
import VerbrauchsausweisContent from "~/components/Verbrauchsausweis/VerbrauchsausweisContent.svelte";
|
||||||
import { Verbrauchsausweis } from "src/lib/Ausweis/Verbrauchsausweis";
|
|
||||||
import { db } from "src/lib/shared";
|
|
||||||
import { Gebaeude } from "src/lib/Gebaeude";
|
|
||||||
import { Energiekennwerte } from "src/lib/Energiekennwerte";
|
|
||||||
import { Ausweis, getAusweis } from "src/lib/Ausweis/Ausweis";
|
|
||||||
|
|
||||||
let gebaeude = new Gebaeude();
|
const uid = Astro.cookies.get("ausweis_uid").value;
|
||||||
if (Astro.cookies.has("ausweis_uid")) {
|
|
||||||
const uid = Astro.cookies.get("ausweis_uid").value;
|
|
||||||
let result = await db<{ gebaeude: Gebaeude, kennwerte: Energiekennwerte, ausweis: Ausweis}>("gebaeude")
|
|
||||||
.select([
|
|
||||||
db.raw("(json_agg(gebaeude)->0) AS gebaeude"),
|
|
||||||
db.raw("(json_agg(energiekennwerte)->0) AS kennwerte"),
|
|
||||||
db.raw("(json_agg(energieausweise)->0) AS ausweis"),
|
|
||||||
])
|
|
||||||
.leftJoin(
|
|
||||||
"energiekennwerte",
|
|
||||||
"energiekennwerte.gebaeude_id",
|
|
||||||
"gebaeude.id"
|
|
||||||
)
|
|
||||||
.leftJoin(
|
|
||||||
"energieausweise",
|
|
||||||
"energieausweise.gebaeude_id",
|
|
||||||
"gebaeude.id"
|
|
||||||
)
|
|
||||||
.where("gebaeude.uid", uid)
|
|
||||||
.groupBy("gebaeude.id")
|
|
||||||
.first();
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
gebaeude = new Gebaeude(result.gebaeude);
|
|
||||||
gebaeude.ausweis = getAusweis(result.ausweis.ausweisart, result.ausweis);
|
|
||||||
gebaeude.ausweis.gebaeude = gebaeude;
|
|
||||||
gebaeude.ausweis.kennwerte = new Energiekennwerte(result.kennwerte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<AusweisLayout title="Verbrauchsausweis erstellen">
|
<AusweisLayout title="Verbrauchsausweis erstellen">
|
||||||
<VerbrauchsausweisContent client:load gebaeude={gebaeude} />
|
<VerbrauchsausweisContent client:load uid={uid} />
|
||||||
</AusweisLayout>
|
</AusweisLayout>
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #fff;
|
background-color: #fafafa;
|
||||||
background-image: url(../images/pattern.png);
|
overflow-x: hidden;
|
||||||
|
/* background-image: url(../images/pattern.png); */
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
@@ -37,28 +38,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mainContent {
|
.mainContent {
|
||||||
position: relative;
|
@apply relative w-full rounded-lg border shadow-md px-6 py-8 bg-white;
|
||||||
-webkit-box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
background-color: rgb(255, 255, 255);
|
|
||||||
margin-top: 0px;
|
|
||||||
padding: 0% 2%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.only-form-mainContent {
|
|
||||||
|
|
||||||
padding: 20px 10px;
|
|
||||||
width: calc(100% - 4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-sidebar {
|
|
||||||
-ms-grid-row: 1;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
grid-area: 1/1/1/3;
|
|
||||||
padding-top: 0px;
|
|
||||||
margin-top: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-sidebar {
|
.right-sidebar {
|
||||||
@@ -81,16 +61,6 @@ body {
|
|||||||
margin: 1em 0em;
|
margin: 1em 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainContent h2 {
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 1rem;
|
|
||||||
position: relative;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
margin: 1em 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainContent a {
|
.mainContent a {
|
||||||
color: #3A4AB5;
|
color: #3A4AB5;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -159,23 +129,6 @@ footer a {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MajorHeading {
|
|
||||||
color: rgb(58, 74, 181);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 12px;
|
|
||||||
position: absolute;
|
|
||||||
top: 22px;
|
|
||||||
right: 0px;
|
|
||||||
line-height: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MajorHeading.smaller {
|
|
||||||
color: rgb(255, 125, 38);
|
|
||||||
margin-top: 59px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-head {
|
.nav-head {
|
||||||
background-color: #444F94;
|
background-color: #444F94;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
@@ -588,12 +541,6 @@ textarea {
|
|||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-sidebar img,
|
|
||||||
.left-sidebar img {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear {
|
.clear {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
@@ -895,17 +842,6 @@ table {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-sidebar img,
|
|
||||||
.left-sidebar img {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-sidebar .large-button,
|
|
||||||
.left-sidebar .large-button {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
block {
|
block {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -1330,16 +1266,6 @@ content>*:nth-child(3) {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: Right Sidebar */
|
|
||||||
.infoCard {
|
|
||||||
-webkit-box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
background: rgba(255, 255, 255, 0.4);
|
|
||||||
border-radius: 1em;
|
|
||||||
padding: 1em;
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.large-button {
|
.large-button {
|
||||||
background: #3a4ab5;
|
background: #3a4ab5;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|||||||
@@ -13,15 +13,6 @@
|
|||||||
grid-template-rows: auto;
|
grid-template-rows: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainContent {
|
|
||||||
display: block;
|
|
||||||
-webkit-box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
background-color: rgb(255, 255, 255);
|
|
||||||
margin-top: 0px;
|
|
||||||
padding: 20px 1.5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stretch-2 {
|
.stretch-2 {
|
||||||
-ms-grid-row: 1;
|
-ms-grid-row: 1;
|
||||||
-ms-grid-column: 1;
|
-ms-grid-column: 1;
|
||||||
@@ -35,17 +26,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-sidebar {
|
|
||||||
display: block;
|
|
||||||
max-width: 940px;
|
|
||||||
-ms-grid-row: 1;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
grid-area: 1/1/1/1;
|
|
||||||
padding-top: 0px;
|
|
||||||
margin-top: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-sidebar {
|
.right-sidebar {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 940px;
|
max-width: 940px;
|
||||||
|
|||||||
@@ -20,17 +20,6 @@
|
|||||||
grid-template-rows: auto;
|
grid-template-rows: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainContent {
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
background-color: rgb(255, 255, 255);
|
|
||||||
margin-top: 0px;
|
|
||||||
padding: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stretch-2 {
|
.stretch-2 {
|
||||||
-ms-grid-row: 1;
|
-ms-grid-row: 1;
|
||||||
-ms-grid-column: 2;
|
-ms-grid-column: 2;
|
||||||
@@ -56,17 +45,6 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-sidebar {
|
|
||||||
display: block;
|
|
||||||
max-width: 940px;
|
|
||||||
-ms-grid-row: 1;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
grid-area: 1/1/1/1;
|
|
||||||
padding-top: 0px;
|
|
||||||
margin-top: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-sidebar {
|
.right-sidebar {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 940px;
|
max-width: 940px;
|
||||||
@@ -87,16 +65,6 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainContent h2 {
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
position: relative;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
margin: 1em 0em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainContent a {
|
.mainContent a {
|
||||||
color: #3A4AB5;
|
color: #3A4AB5;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -157,23 +125,6 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.MajorHeading {
|
|
||||||
color: rgb(58, 74, 181);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 26px;
|
|
||||||
position: absolute;
|
|
||||||
top: 30px;
|
|
||||||
right: 0px;
|
|
||||||
line-height: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MajorHeading.smaller {
|
|
||||||
color: rgb(255, 125, 38);
|
|
||||||
margin-top: 35px;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-head {
|
.nav-head {
|
||||||
background-color: rgb(255, 125, 38);
|
background-color: rgb(255, 125, 38);
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
@@ -195,7 +146,7 @@
|
|||||||
|
|
||||||
.headerButton {
|
.headerButton {
|
||||||
width: auto;
|
width: auto;
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: rgb(255, 255, 255);
|
color: rgb(255, 255, 255);
|
||||||
background-color: rgb(255, 125, 38);
|
background-color: rgb(255, 125, 38);
|
||||||
@@ -244,25 +195,6 @@
|
|||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.nav-card {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
position: relative;
|
|
||||||
background-color: #fff;
|
|
||||||
-webkit-box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
box-shadow: rgb(162, 162, 162) 1px 1px 3px 1px;
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-box-direction: normal;
|
|
||||||
-ms-flex-direction: column;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
background-color: none;
|
background-color: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user