This repository has been archived on 2024-10-26. You can view files and clone it, but cannot push or open issues or pull requests.
fotochallenge/src/routes/+page.svelte

106 lines
2.6 KiB
Svelte
Raw Normal View History

2024-07-17 00:26:05 +02:00
<script lang="ts">
import { enhance } from '$app/forms';
import type { ActionData } from './$types';
2024-07-30 17:48:44 +02:00
// @ts-expect-error: package does not contain type definitions
2024-07-30 17:34:56 +02:00
import AutoComplete from 'simple-svelte-autocomplete';
2024-07-17 00:26:05 +02:00
export let form: ActionData;
2024-07-30 17:39:41 +02:00
2024-07-30 17:40:35 +02:00
let selectedName: string;
2024-07-17 00:26:05 +02:00
let files: FileList;
let sending = false;
const siPrefixes = new Map([
[1_000_000, 'M'],
[1_000, 'k']
]);
const fileSize = (files: FileList) => {
const size = Array.from(files)
.map((f) => f.size)
.reduce((a, b) => a + b, 0);
return (
Array.from(siPrefixes)
.filter(([k]) => size >= k)
.map(([k, v]) => `${(size / k).toFixed(1)} ${v}B`)[0] ?? `${size} bytes`
);
};
2024-07-30 17:39:41 +02:00
2024-07-30 17:40:35 +02:00
async function loadNames() {
2024-07-30 17:39:41 +02:00
const url = './names';
2024-07-30 17:34:56 +02:00
const response = await fetch(url);
return await response.json();
}
2024-07-17 00:26:05 +02:00
</script>
<form
enctype="multipart/form-data"
class="box"
method="POST"
use:enhance={() => {
sending = true;
return ({ update }) => {
update({ invalidateAll: true }).finally(async () => {
sending = false;
});
};
}}
>
{#if sending}
<div class="notification is-info">Wird hochgeladen...</div>
{:else if form?.success}
<div class="notification is-success">Erfolgreich hochgeladen</div>
{/if}
<div class="field">
<label for="name" class="label">Name</label>
<div class="control">
2024-07-30 17:39:41 +02:00
<AutoComplete
id="name"
name="name"
2024-07-30 19:10:47 +02:00
placeholder="Name"
2024-07-30 17:39:41 +02:00
create={true}
bind:selectedItem={selectedName}
bind:text={selectedName}
createText=""
searchFunction={loadNames}
2024-07-17 00:26:05 +02:00
/>
</div>
{#if form?.field === 'name'}
{#if form?.missing}
<p class="help is-danger">Bitte einen Namen angeben</p>
{:else if form?.incorrect}
<p class="help is-danger">Ungültiger Name</p>
{/if}
{/if}
</div>
<div class="file is-centered has-name is-boxed">
<label class="file-label">
<input class="file-input" type="file" name="files" bind:files multiple required />
<span class="file-cta">
<span class="file-label">Fotos auswählen...</span>
</span>
2024-07-30 17:34:56 +02:00
{#if files && files?.length !== 0}
<span class="file-name">
{files.length} Bild{#if files.length > 1}er{/if} ausgewählt ({fileSize(files)})
</span>
2024-07-17 00:26:05 +02:00
{:else}
<span class="file-name">Keine Bilder ausgewählt</span>
{/if}
{#if form?.field === 'files'}
{#if form?.missing || form?.empty}
<p class="help is-danger">Bitte mindestens eine Datei auswählen</p>
{:else if form?.incorrect}
<p class="help is-danger">Ungültige Dateien</p>
{/if}
{/if}
</label>
</div>
<div class="field is-grouped is-grouped-centered">
<div class="control">
<button class="button is-link">Hochladen</button>
</div>
</div>
</form>