Files
scan-wave/src/routes/private/events/creator/steps/StepUploadParticipants.svelte
2025-06-28 00:35:47 +02:00

97 lines
2.4 KiB
Svelte

<script lang="ts">
import Papa from 'papaparse';
let { participants = $bindable() } = $props();
let loading = $state(false);
let showForm = $derived(participants.length === 0);
async function handleSubmit(e: Event) {
e.preventDefault();
loading = true;
const form = e.target as HTMLFormElement;
const fileInput = form.elements.namedItem('participants') as HTMLInputElement;
const file = fileInput?.files?.[0];
if (!file) {
loading = false;
return;
}
const csvText = await file.text();
const { data: parsedRows } = Papa.parse<string[]>(csvText, {
skipEmptyLines: true,
header: false
});
// Remove the first row (header)
if (parsedRows.length > 0) {
parsedRows.shift();
}
participants = parsedRows.map((row: string[]) => ({
name: row[0],
surname: row[1],
email: row[2]
}));
showForm = false;
loading = false;
}
function showEditForm() {
showForm = true;
}
</script>
{#if showForm}
<form
onsubmit={handleSubmit}
autocomplete="off"
enctype="multipart/form-data"
class="flex w-full flex-col space-y-4 rounded border border-gray-300 bg-white p-8 shadow-none"
>
<h2 class="mb-4 text-center text-2xl font-semibold">Upload Participants</h2>
<label class="flex flex-col text-gray-700">
CSV File
<input
type="file"
name="participants"
id="participants"
accept=".csv"
class="mt-1 rounded border border-gray-300 px-3 py-2 focus:ring-2 focus:ring-blue-200 focus:outline-none"
required
/>
</label>
<button
type="submit"
class="w-full rounded bg-blue-600 py-2 text-white transition hover:bg-blue-700"
>
Submit
</button>
</form>
{:else}
<button
class="w-full rounded bg-blue-600 py-2 text-white transition hover:bg-blue-700"
onclick={showEditForm}
aria-label="Edit participants"
>
Edit participants
</button>
{/if}
{#if !showForm}
<div class="mt-4 rounded border-l-4 border-green-500 bg-green-50 p-4 text-green-700">
{#if loading}
<strong class="text-gray-700">Loading...</strong>
{:else if participants.length === 0}
<strong class="text-gray-700">No participants yet...</strong>
{:else}
<ul class="space-y-2">
{#each participants as p, i}
<li class="flex items-center justify-between border-b pb-1">
<div>
<div class="font-semibold">{p.name} {p.surname}</div>
<div class="font-mono text-xs text-gray-600">{p.email}</div>
</div>
</li>
{/each}
</ul>
{/if}
</div>
{/if}