Files
online-energieausweis/src/components/FileGrid.svelte
Moritz Utcke 5997037328 Mime
2025-04-01 14:55:32 -03:00

142 lines
4.4 KiB
Svelte

<script lang="ts">
import { BedarfsausweisWohnenClient, GEGNachweisWohnenClient, ObjektClient, UnterlageClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js";
import { Trash, Upload } from "radix-svelte-icons";
import HelpLabel from "#components/labels/HelpLabel.svelte";
export let kategorie: string = "";
export let files: Unterlage[] = [];
export let max: number = Infinity;
export let min: number = 1;
export let name: string = "";
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient | BedarfsausweisGewerbe | GEGNachweisWohnen | GEGNachweisGewerbe;
export let objekt: ObjektClient;
import mime from "mime"
import { api } from "astro-typesafe-api/client";
import { BedarfsausweisGewerbe, GEGNachweisGewerbe, GEGNachweisWohnen, Unterlage } from "#lib/client/prisma.js";
function getAllFiles(this: HTMLInputElement) {
const fileArray = this.files || [];
if (fileArray.length == max) {
this.value = "";
return;
}
for (let i = 0; i < fileArray.length; i++) {
const file = fileArray[i];
if (i == max) {
break;
}
const reader = new FileReader();
reader.onload = async () => {
if (reader.readyState != reader.DONE) {
return;
}
if (!reader.result) {
return;
}
const mimeType = mime.getType(file.name.split(".").pop() as string)
const { id } = await api.unterlage.PUT.fetch({
data: reader.result as string,
kategorie,
mime: mimeType,
name: file.name
})
files.push({ id, kategorie, name: file.name, mime: mimeType, aufnahme_id: null });
files = files;
if (i == (Math.min(fileArray.length, max) - 1)) {
this.value = "";
}
}
reader.readAsDataURL(file);
}
}
let fileUpload: HTMLInputElement;
export const upload = () => {
fileUpload.click()
}
</script>
<div class="flex flex-col gap-4">
<!-- Falls die maximale Anzahl Dokumente erreicht wurde grauen wir den input aus und zeigen einen Hilfstext -->
{#if files.filter((file) => file.kategorie === kategorie).length === max}
<span class="bg-base-200 border px-4 py-2">Maximale Anzahl Dokumente wurde erreicht.</span>
{:else if max > 1}
<div class="input-standard">
<input type="file" class="file-input file-input-ghost h-[38px]" bind:this={fileUpload} {name} multiple on:change={getAllFiles} />
<div class="help-label">
<HelpLabel>
<slot />
</HelpLabel>
</div>
</div>
{:else}
<div class="input-standard">
<input type="file" class="file-input file-input-ghost h-[38px]" bind:this={fileUpload} {name} on:change={getAllFiles} />
<div class="help-label">
<HelpLabel>
<slot />
</HelpLabel>
</div>
</div>
{/if}
<div class="grid grid-cols-2 gap-2">
{#each files as file, i}
{#if file.kategorie == kategorie}
<div class="relative group">
<div
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all text-center items-center flex p-4 text-opacity-75 text-black"
>{file.name}</div>
<div class="invisible group-hover:visible absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-row gap-2">
<button
type="button"
class="rounded-full w-[30px] h-[30px] flex items-center justify-center p-0 bg-[rgba(0,0,0,0.4)]"
on:click={() => {
delete files[i];
files = files.filter((x) => x);
}}
>
<Trash size={20} color="#fff"></Trash>
</button>
</div>
</div>
{/if}
{/each}
<!-- Wir zeigen Platzhalter an, damit der Nutzer sieht wie viele Bilder er hochladen soll -->
{#each { length: Math.max(0, Math.min(max, 4) - files.filter(image => image.kategorie === kategorie).length) } as _, i}
<div class="relative group">
<img
src="/placeholder.png"
alt={kategorie}
class="h-full max-h-32 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all"
class:opacity-35={i >= min}
/>
<div class="invisible group-hover:visible absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-row gap-2">
<button
type="button"
class="rounded-full w-[30px] h-[30px] flex items-center justify-center p-0 bg-[rgba(0,0,0,0.4)]"
on:click={upload}
>
<Upload size={20} color="#fff"></Upload>
</button>
</div>
</div>
{/each}
</div>
</div>