Dashboard

This commit is contained in:
Jens Cornelsen
2025-02-23 04:35:02 +01:00
parent f8f53d0ac9
commit 8f9f79a02d
7 changed files with 117 additions and 70 deletions

View File

@@ -102,7 +102,7 @@
} }
</script> </script>
<div class="carousel"> <div class="carousel w-100">
<div class="slides" bind:this={siema}> <div class="slides" bind:this={siema}>
<slot></slot> <slot></slot>
</div> </div>

View File

@@ -115,7 +115,7 @@
</div> </div>
<div class="flex flex-row flex-wrap gap-2"> <div class="flex flex-row flex-wrap gap-2">
{#if ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen} {#if ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen}
<div class="badge badge-accent font-semibold"> <div class="badge badge-accent font-semibold text-secondary text-lg">
Verbrauchsausweis Wohnen Verbrauchsausweis Wohnen
</div> </div>
{:else if ausweisart == Enums.Ausweisart.BedarfsausweisWohnen} {:else if ausweisart == Enums.Ausweisart.BedarfsausweisWohnen}
@@ -132,7 +132,7 @@
<div class="badge badge-success font-semibold">Ausgestellt</div> <div class="badge badge-success font-semibold">Ausgestellt</div>
{/if} {/if}
</div> </div>
<h2 class="card-title">{objekt.adresse}</h2> <div class="badge badge-accent font-semibold text-black text-m">{objekt.adresse}</div>
<div class="mb-4 flex flex-row items-center gap-4"> <div class="mb-4 flex flex-row items-center gap-4">
<progress class="progress w-full" value={progress} max="100" <progress class="progress w-full" value={progress} max="100"
></progress> ></progress>
@@ -192,8 +192,14 @@
<a <a
class="button text-sm" class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?uid={ausweis.uid}" href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?uid={ausweis.uid}"
>Bearbeiten</a >Stornieren</a>
>
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?uid={ausweis.uid}"
>Freigeben</a>
<a <a
class="p-2 rounded-lg hover:bg-gray-200" class="p-2 rounded-lg hover:bg-gray-200"
title="PDF Herunterladen" title="PDF Herunterladen"

View File

@@ -26,7 +26,7 @@
{#each objekt.aufnahmen as aufnahme} {#each objekt.aufnahmen as aufnahme}
<div class="border rounded-lg px-4 py-2"> <div class="border rounded-lg px-4 py-2">
<div class="flex flex-row justify-between items-center"> <div class="flex flex-row justify-between items-center">
<span>Sanierungsstand vom {moment(aufnahme.erstellungsdatum).format("DD.MM.YYYY")}</span> <span>Stand vom {moment(aufnahme.erstellungsdatum).format("DD.MM.YYYY")}</span>
<a href="/dashboard/aufnahme/{aufnahme.uid}" class="rounded-lg p-2 hover:bg-gray-100 transition-all"><OpenInNewWindow size={20}></OpenInNewWindow></a> <a href="/dashboard/aufnahme/{aufnahme.uid}" class="rounded-lg p-2 hover:bg-gray-100 transition-all"><OpenInNewWindow size={20}></OpenInNewWindow></a>
</div> </div>
<div class="flex flex-row gap-2"> <div class="flex flex-row gap-2">

View File

@@ -8,6 +8,7 @@
import ThemeController from "#components/ThemeController.svelte"; import ThemeController from "#components/ThemeController.svelte";
import { BenutzerClient } from "#components/Ausweis/types.js"; import { BenutzerClient } from "#components/Ausweis/types.js";
import Cross1 from "radix-svelte-icons/src/lib/icons/Cross1.svelte"; import Cross1 from "radix-svelte-icons/src/lib/icons/Cross1.svelte";
import { flex } from "#lib/pdf/elements/index.js";
export let lightTheme: boolean; export let lightTheme: boolean;
export let benutzer: BenutzerClient; export let benutzer: BenutzerClient;
@@ -20,37 +21,36 @@
let headerOpen = false; let headerOpen = false;
</script> </script>
<header class="fixed top-0 left-0 w-full h-16 flex items-center justify-between px-4 border-b z-10 bg-base-200">
<button on:click={() => headerOpen = !headerOpen}>
{#if headerOpen}
<Cross1 size={28}></Cross1>
{:else}
<HamburgerMenu size={28}></HamburgerMenu>
{/if}
</button>
<a href="/" class="block md:hidden"
><img
src="/images/header/logo-IBC-big.svg"
class="w-24"
alt="IBCornelsen - Logo"
/></a
>
</header>
<aside class:hidden={!headerOpen} class="fixed left-0 top-16 w-full h-[calc(100%-4rem)] flex z-30 md:relative md:h-auto md:w-auto md:top-0 md:flex bg-base-200 border-r border-r-base-300 flex-col py-4"> <aside class:hidden={!headerOpen} class="fixed left-0 top-16 w-full h-[calc(100%-4rem)] flex z-30 md:relative md:h-auto md:w-auto md:top-0 md:flex bg-base-200 border-r border-r-base-300 flex-col py-4">
<a href="/" class="px-8 hidden md:block"
><img
src="/images/header/logo-IBC-big.svg"
class="w-24"
alt="IBCornelsen - Logo"
/></a
>
<div class="flex flex-col gap-2 mt-0 md:mt-12 px-0"> <div class="flex flex-row items-center px-4">
<div class="flex flex-row mr-6">
<a href="/"><img src="/images/header/logo-IBC-big.svg" class="h-16" alt="IBCornelsen - Logo"/></a>
</div>
<div class="flex-col items-end">
<div class="text-base-content font-semibold text-left flex"
>{benutzer.vorname} {benutzer.name}</div>
<div class="text-base-content text-sm flex">{benutzer.email}</div>
</div>
</div>
<div class="flex flex-col gap-2 mt-0 md:mt-8 px-0">
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard"> <a use:ripple={rippleOptions} class="button-tab" href="/dashboard">
<Reader width={22} height={22} /> <Reader width={22} height={22} />
Objekte Gebäude
</a> </a>
<div class="flex ml-12">Katendeich 5AAA<br>44145 Dortmund</div>
<hr class="border-gray-600">
<div class="flex ml-12">Birkenalee<br>33175 Bad Lippspringe</div>
<hr class="border-gray-600">
<div class="flex ml-12">Birkenalee<br>33175 Bad Lippspringe</div>
<hr class="border-gray-600">
<div class="flex ml-12">Katendeich 5AAA<br>44145 Dortmund</div>
<hr class="border-gray-600">
<div class="flex ml-12">Katendeich 5AAA<br>44145 Dortmund</div>
<!-- <button use:ripple={rippleOptions} class="button-tab"> <!-- <button use:ripple={rippleOptions} class="button-tab">
<EnvelopeClosed width={22} height={22} /> <EnvelopeClosed width={22} height={22} />
Kontakt Kontakt
@@ -87,7 +87,7 @@
</details></li> </details></li>
{/if} {/if}
</div> </div>
<div class="mt-auto flex flex-col gap-4 px-8"> <div class="mt-10 flex flex-col gap-4 px-8">
<div class="flex flex-row justify-between items-center"> <div class="flex flex-row justify-between items-center">
<ThemeController bind:lightTheme></ThemeController> <ThemeController bind:lightTheme></ThemeController>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
@@ -117,19 +117,7 @@
use:ripple={rippleOptions} use:ripple={rippleOptions}
class="hover:bg-gray-200 no-animation focus:shadow-none justify-start py-4 h-auto px-8 rounded-none w-full flex flex-row gap-4" class="hover:bg-gray-200 no-animation focus:shadow-none justify-start py-4 h-auto px-8 rounded-none w-full flex flex-row gap-4"
> >
<div class="avatar">
<div class="w-12 rounded-full">
<img
src={benutzer.profilbild || "/images/profile-placeholder.png"}
/>
</div>
</div>
<div class="flex flex-col">
<span class="text-base-content font-semibold text-left"
>{benutzer.vorname} {benutzer.name}</span
>
<span class="text-base-content text-sm">{benutzer.email}</span>
</div>
</a> </a>
</aside> </aside>

View File

@@ -1,5 +1,5 @@
--- ---
import "svelte-ripple-action/ripple.css"; // import "svelte-ripple-action/ripple.css";
import "../style/global.css"; import "../style/global.css";
import "../../svelte-dialogs.config"; import "../../svelte-dialogs.config";
import DashboardSidebar from "../components/Dashboard/DashboardSidebar.svelte"; import DashboardSidebar from "../components/Dashboard/DashboardSidebar.svelte";
@@ -95,14 +95,27 @@ let lightTheme = Astro.cookies.get("theme")?.value === "light";
</title> </title>
</head> </head>
<body class="min-h-screen grid md:grid-cols-[300px_1fr]"> <body>
<main
class="p-0 grid max-w-[1920px]
xs:grid-cols-[minmax(1fr,1fr)] xs:gap-1 xs:p-0
sm:grid-cols-[minmax(1fr,1fr)] sm:gap-1 sm:p-0
md:grid-cols-[minmax(1fr,1fr)] md:gap-2 md:p-0
lg:grid-cols-[minmax(150px,250px)1fr] lg:gap-3 lg:p-4
xl:grid-cols-[minmax(150px,350px)1fr] xl:gap-4 xl:p-6
2xl:grid-cols-[minmax(150px,300px)1fr] 2xl:gap-5 2xl:p-6"
>
<DashboardSidebar lightTheme={lightTheme} benutzer={user} client:load> <DashboardSidebar lightTheme={lightTheme} benutzer={user} client:load>
</DashboardSidebar> </DashboardSidebar>
<main class="overflow-auto h-screen bg-base-100 pt-24 px-6 w-full">
<article class="box rounded-tl-none <article class="box rounded-tl-none
xl:px-10 py-8"> xl:px-10 py-8">
<slot /> <slot />
</article> </article>
</main> </main>
</body> </body>
</html> </html>

View File

@@ -3,35 +3,71 @@
import Carousel from "#components/Carousel.svelte"; import Carousel from "#components/Carousel.svelte";
import DashboardAusweis from "#components/Dashboard/DashboardAusweis.svelte"; import DashboardAusweis from "#components/Dashboard/DashboardAusweis.svelte";
import { Objekt } from "#lib/client/prisma"; import { Objekt } from "#lib/client/prisma";
import { ChevronLeft, ChevronRight, Plus } from "radix-svelte-icons"; import { ChevronLeft, ChevronRight } from "radix-svelte-icons";
export let user: BenutzerClient; export let user: BenutzerClient;
export let aufnahme: AufnahmeKomplettClient; export let aufnahme: AufnahmeKomplettClient;
export let objekt: Objekt; export let objekt: Objekt;
import { onMount } from "svelte";
let dropdownOpen = false;
function toggleDropdown() {
dropdownOpen = !dropdownOpen;
}
function closeDropdown() {
dropdownOpen = false;
}
</script> </script>
<h1>{objekt.adresse}, {objekt.plz} {objekt.ort}</h1> <h1>{objekt.adresse}, {objekt.plz} {objekt.ort}</h1>
<div class="bg-white rounded-lg"> <hr>
{#if aufnahme.bilder.length > 0}
<Carousel perPage={1}> <div class="relative mb-6">
{#each aufnahme.bilder as bild, i (i)} <button class="button flex flex-row rounded-lg gap-2 bg-secondary text-white text-center" on:click={toggleDropdown}>
<img src="/bilder/{bild.uid}.jpg" alt={bild.kategorie} class="max-h-[30vh] h-full w-full object-contain"> Ausweis erstellen +
{/each} </button>
<span slot="left-control" class="p-2.5 bg-opacity-50 bg-white block rounded-full"><ChevronLeft size={24}></ChevronLeft></span> {#if dropdownOpen}
<span slot="right-control" class="p-2.5 bg-opacity-50 bg-white block rounded-full"><ChevronRight size={24}></ChevronRight></span> <div class="absolut mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5" on:click|stopPropagation on:keydown|stopPropagation on:keyup|stopPropagation>
</Carousel> <div class="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
<button class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left" role="menuitem">Verbrauchsausweis Wohnen Erstellen</button>
<button class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left" role="menuitem">Verbrauchsausweis Gewerbe Erstellen</button>
<button class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left" role="menuitem">Bedarfsausweis Erstellen</button>
</div>
</div>
{/if} {/if}
</div> </div>
<div class="flex flex-row gap-4"> <div class="my-4 grid grid-cols-1 md:grid-cols-1 lg:grid-cols-1 gap-2">
<button class="button flex flex-row rounded-lg gap-2"><Plus size={20}></Plus> Verbrauchsausweis Wohnen Erstellen</button>
<button class="button flex flex-row rounded-lg gap-2"><Plus size={20}></Plus> Verbrauchsausweis Gewerbe Erstellen</button> <div class="relative bg-gray-100 rounded-md flex justify-center items-center">
<button class="button flex flex-row rounded-lg gap-2"><Plus size={20}></Plus> Bedarfsausweis Erstellen</button> {#if aufnahme.bilder.length > 0}
<Carousel perPage={3}>
{#each aufnahme.bilder as bild, i (i)}
<img src="/bilder/{bild.uid}.jpg" alt={bild.kategorie} class="max-h-[25vh] h-full w-full object-contain">
{/each}
<span slot="left-control" class="p-2.5 bg-opacity-50 bg-white block rounded-full"><ChevronLeft size={24}></ChevronLeft></span>
<span slot="right-control" class="p-2.5 bg-opacity-50 bg-white block rounded-full"><ChevronRight size={24}></ChevronRight></span>
</Carousel>
{/if}
</div>
</div> </div>
<div class="my-8 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3"> <style>
.button {
padding: 0.5rem 1rem;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
}
</style>
<div class="my-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
{#each aufnahme.verbrauchsausweise_wohnen as ausweis} {#each aufnahme.verbrauchsausweise_wohnen as ausweis}
<DashboardAusweis {ausweis} {aufnahme} {objekt} progress={0}></DashboardAusweis> <DashboardAusweis {ausweis} {aufnahme} {objekt} progress={0}></DashboardAusweis>
{/each} {/each}

View File

@@ -7,12 +7,16 @@
export let objekte: ObjektKomplettClient[]; export let objekte: ObjektKomplettClient[];
</script> </script>
<h1 class="text-4xl font-medium">Willkommen zurück, {user.vorname}!</h1> <h1>Gebäudeübersicht</h1>
<p class="text-lg">
Hier finden Sie eine Übersicht über all ihre Ausweise und Gebäude. <hr>
</p>
<div class="relative mb-6">
<button class="button flex flex-row rounded-lg gap-2 bg-secondary text-white text-center">
Gebäude anlegen +
</button>
</div>
<h1 class="text-4xl font-medium my-8">Gebäude</h1>
<div class="columns columns-1 md:columns-2 lg:columns-3 gap-4"> <div class="columns columns-1 md:columns-2 lg:columns-3 gap-4">
{#each objekte as objekt} {#each objekte as objekt}
<DashboardObjekt {objekt}></DashboardObjekt> <DashboardObjekt {objekt}></DashboardObjekt>