svelte 5 mit npm
This commit is contained in:
244
src/routes/(angemeldet)/upload/+page.svelte
Normal file
244
src/routes/(angemeldet)/upload/+page.svelte
Normal file
@@ -0,0 +1,244 @@
|
||||
<script>
|
||||
import { deserialize, enhance } from '$app/forms';
|
||||
import Alert from '$lib/components/ui/Alert.svelte';
|
||||
import Button from '$lib/components/ui/Button.svelte';
|
||||
import Modal from '$lib/components/ui/Modal/Modal.svelte';
|
||||
import ModalTitle from '$lib/components/ui/Modal/ModalTitle.svelte';
|
||||
import ModalContent from '$lib/components/ui/Modal/ModalContent.svelte';
|
||||
import ModalFooter from '$lib/components/ui/Modal/ModalFooter.svelte';
|
||||
import shortenFileSize from '$lib/helper/shortenFileSize.js';
|
||||
import Exclamation from '$lib/icons/Exclamation.svelte';
|
||||
|
||||
export let form;
|
||||
|
||||
let open = false;
|
||||
let inProgress = false;
|
||||
let vorgang = '';
|
||||
let name = '';
|
||||
/** @type {?string}*/
|
||||
let etag = null;
|
||||
/** @type {?FileList} */
|
||||
let files = null;
|
||||
|
||||
$: inProgress = form === null;
|
||||
|
||||
/** @type {?Record<string,any>}*/
|
||||
let formErrors;
|
||||
|
||||
async function validateForm() {
|
||||
let data = new FormData();
|
||||
data.append('vorgang', vorgang);
|
||||
data.append('name', name);
|
||||
const response = await fetch('?/validate', { method: 'POST', body: data });
|
||||
/** @type {import('@sveltejs/kit').ActionResult} */
|
||||
const result = deserialize(await response.text());
|
||||
|
||||
let success = true;
|
||||
if (result.type === 'success') {
|
||||
formErrors = null;
|
||||
} else {
|
||||
if (result.type === 'failure' && result.data) formErrors = result.data;
|
||||
success = false;
|
||||
}
|
||||
|
||||
console.log('File', files);
|
||||
if (!files?.length) {
|
||||
formErrors = { file: 'Sie haben keine Datei ausgewählt.', ...formErrors };
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
async function getUrl() {
|
||||
let data = new FormData();
|
||||
data.append('vorgang', vorgang);
|
||||
data.append('name', name);
|
||||
if (files?.length === 1) {
|
||||
data.append('type', files[0].type);
|
||||
data.append('fileName', files[0].name);
|
||||
}
|
||||
const response = await fetch('?/url', { method: 'POST', body: data });
|
||||
/** @type {import('@sveltejs/kit').ActionResult} */
|
||||
const result = deserialize(await response.text());
|
||||
if (result.type === 'success') return result.data?.url;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @param {MouseEvent} event*/
|
||||
async function buttonClick(event) {
|
||||
if (!(await validateForm())) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
const url = await getUrl();
|
||||
console.log('URL', url);
|
||||
open = true;
|
||||
inProgress = true;
|
||||
|
||||
fetch(url, { method: 'PUT', body: files[0] })
|
||||
.then((response) => {
|
||||
inProgress = false;
|
||||
etag = '123';
|
||||
console.log('SUCCESS', response);
|
||||
})
|
||||
.catch((err) => {
|
||||
inProgress = false;
|
||||
etag = null;
|
||||
console.log('ERROR', err);
|
||||
});
|
||||
}
|
||||
|
||||
function uploadSuccessful() {
|
||||
console.log('reset');
|
||||
open = false;
|
||||
vorgang = '';
|
||||
name = '';
|
||||
files = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="flex flex-col items-center justify-center w-full">
|
||||
<h1 class="text-xl">Datei zu Vorgang hinzufügen</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="space-y-12">
|
||||
<div class="border-b border-gray-900/10 pb-12">
|
||||
<p class="mt-8 text-sm leading-6 text-gray-600">
|
||||
This information will be displayed publicly so be careful what you share.
|
||||
</p>
|
||||
|
||||
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8">
|
||||
<div>
|
||||
<label for="vorgang" class="block text-sm font-medium leading-6 text-gray-900"
|
||||
><span class="flex"
|
||||
>{#if formErrors?.vorgang}
|
||||
<span class="inline-block mr-1"><Exclamation /></span>
|
||||
{/if} Vorgang</span
|
||||
></label
|
||||
>
|
||||
<div class="mt-2">
|
||||
<div
|
||||
class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600"
|
||||
>
|
||||
<input
|
||||
bind:value={vorgang}
|
||||
type="text"
|
||||
name="vorgang"
|
||||
id="vorgang"
|
||||
autocomplete={vorgang}
|
||||
class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{#if formErrors?.vorgang}
|
||||
<p class="block text-sm leading-6 text-red-900 mt-2">{formErrors.vorgang}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium leading-6 text-gray-900"
|
||||
><span class="flex"
|
||||
>{#if formErrors?.name}
|
||||
<span class="inline-block mr-1"><Exclamation /></span>
|
||||
{/if} Name</span
|
||||
></label
|
||||
>
|
||||
<div class="mt-2">
|
||||
<div
|
||||
class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600"
|
||||
>
|
||||
<input
|
||||
bind:value={name}
|
||||
type="text"
|
||||
name="name"
|
||||
id="name"
|
||||
autocomplete={name}
|
||||
class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{#if formErrors?.name}
|
||||
<p class="block text-sm leading-6 text-red-900 mt-2">{formErrors.name}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="col-span-full">
|
||||
<label for="file" class="block text-sm font-medium leading-6 text-gray-900"
|
||||
><span class="flex"
|
||||
>{#if formErrors?.file}
|
||||
<span class="inline-block mr-1"><Exclamation /></span>
|
||||
{/if} Datei</span
|
||||
></label
|
||||
>
|
||||
<div
|
||||
class="mt-2 flex justify-center rounded-lg border border-dashed border-gray-900/25 px-6 py-10"
|
||||
>
|
||||
<div class="text-center">
|
||||
<svg
|
||||
class="mx-auto h-12 w-12 text-gray-300"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M1.5 6a2.25 2.25 0 012.25-2.25h16.5A2.25 2.25 0 0122.5 6v12a2.25 2.25 0 01-2.25 2.25H3.75A2.25 2.25 0 011.5 18V6zM3 16.06V18c0 .414.336.75.75.75h16.5A.75.75 0 0021 18v-1.94l-2.69-2.689a1.5 1.5 0 00-2.12 0l-.88.879.97.97a.75.75 0 11-1.06 1.06l-5.16-5.159a1.5 1.5 0 00-2.12 0L3 16.061zm10.125-7.81a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<div class="mt-4 flex text-sm leading-6 text-gray-600">
|
||||
<label
|
||||
for="file"
|
||||
class="relative cursor-pointer rounded-md bg-white font-semibold text-indigo-600 focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2 hover:text-indigo-500"
|
||||
>
|
||||
<span>Wähle eine Datei aus</span>
|
||||
<input id="file" bind:files name="file" type="file" class="sr-only" />
|
||||
</label>
|
||||
<p class="pl-1">oder ziehe sie ins Feld</p>
|
||||
</div>
|
||||
<p class="text-xs leading-5 text-gray-600">GLB Dateien bis zu 1GB</p>
|
||||
{#if files?.length}
|
||||
<div class="flex justify-center text-xs">
|
||||
<p class="mx-2">Datei: <span class="font-bold">{files[0].name}</span></p>
|
||||
<p class="mx-2">
|
||||
Größe: <span class="font-bold">{shortenFileSize(files[0].size)}</span>
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if formErrors?.file}
|
||||
<p class="block text-sm leading-6 text-red-900 mt-2">{formErrors.file}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
|
||||
<Button
|
||||
on:click={buttonClick}
|
||||
class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
>Save</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal {open}
|
||||
><ModalTitle>Upload</ModalTitle><ModalContent>
|
||||
{#if inProgress}
|
||||
<p class="py-2 mb-1">Upload läuft...</p>
|
||||
{:else if etag}
|
||||
<Alert class="w-full">Upload erfolgreich</Alert>
|
||||
{:else}
|
||||
<Alert class="w-full" type="error">Fehler beim Upload</Alert>
|
||||
{/if}
|
||||
</ModalContent>
|
||||
<ModalFooter><Button disabled={inProgress} on:click={uploadSuccessful}>Ok</Button></ModalFooter>
|
||||
</Modal>
|
||||
</div>
|
||||
Reference in New Issue
Block a user