175 lines
6.0 KiB
Svelte
175 lines
6.0 KiB
Svelte
<script lang="ts">
|
|
import { toast } from '$lib/stores/toast.js';
|
|
|
|
interface Participant {
|
|
id: string;
|
|
name: string;
|
|
surname: string;
|
|
email: string;
|
|
scanned: boolean;
|
|
email_sent: boolean;
|
|
}
|
|
|
|
interface Event {
|
|
id: string;
|
|
sheet_id: string;
|
|
}
|
|
|
|
let {
|
|
event,
|
|
participants,
|
|
loading,
|
|
participantsLoading,
|
|
syncingParticipants,
|
|
onSyncParticipants
|
|
} = $props<{
|
|
event: Event | null;
|
|
participants: Participant[];
|
|
loading: boolean;
|
|
participantsLoading: boolean;
|
|
syncingParticipants: boolean;
|
|
onSyncParticipants: () => void;
|
|
}>();
|
|
|
|
// Handle sync participants with toast notifications
|
|
function handleSyncParticipants() {
|
|
|
|
// Show initial notification about sync starting
|
|
toast.info('Starting participant synchronization...', 2000);
|
|
|
|
// Call the parent component's sync function
|
|
onSyncParticipants();
|
|
}
|
|
</script>
|
|
|
|
<div class="mb-4 rounded-lg border border-gray-300 bg-white p-6">
|
|
<div class="mb-4 flex items-center justify-between">
|
|
<h2 class="text-xl font-semibold text-gray-900">Participants</h2>
|
|
<button
|
|
onclick={onSyncParticipants}
|
|
disabled={syncingParticipants || !event || loading}
|
|
class="rounded bg-blue-600 px-4 py-2 text-white transition hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
>
|
|
{#if syncingParticipants}
|
|
Syncing...
|
|
{:else}
|
|
Sync Participants
|
|
{/if}
|
|
</button>
|
|
</div>
|
|
|
|
{#if participantsLoading || loading}
|
|
<!-- Loading placeholder for participants -->
|
|
<div class="space-y-3">
|
|
{#each Array(5) as _}
|
|
<div class="grid grid-cols-5 gap-4 border-b border-gray-200 py-3">
|
|
<div class="h-4 animate-pulse rounded bg-gray-200"></div>
|
|
<div class="h-4 animate-pulse rounded bg-gray-200"></div>
|
|
<div class="h-4 animate-pulse rounded bg-gray-200"></div>
|
|
<div class="h-4 animate-pulse rounded bg-gray-200"></div>
|
|
<div class="h-4 animate-pulse rounded bg-gray-200"></div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
{:else if participants.length > 0}
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Name</th>
|
|
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Surname</th>
|
|
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Email</th>
|
|
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Scanned</th>
|
|
<th class="px-4 py-3 text-left text-sm font-medium text-gray-700">Email Sent</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{#each participants as participant}
|
|
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
|
<td class="px-4 py-3 text-sm text-gray-900">{participant.name}</td>
|
|
<td class="px-4 py-3 text-sm text-gray-900">{participant.surname}</td>
|
|
<td class="px-4 py-3 text-sm text-gray-900">{participant.email}</td>
|
|
<td class="px-4 py-3 text-sm">
|
|
{#if participant.scanned}
|
|
<div class="flex items-center text-green-600">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
>
|
|
<path
|
|
fill-rule="evenodd"
|
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
|
clip-rule="evenodd"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
{:else}
|
|
<div class="flex items-center text-gray-400">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M6 18L18 6M6 6l12 12"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
{/if}
|
|
</td>
|
|
<td class="px-4 py-3 text-sm">
|
|
{#if participant.email_sent}
|
|
<div class="flex items-center text-blue-600">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
>
|
|
<path
|
|
fill-rule="evenodd"
|
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
|
clip-rule="evenodd"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
{:else}
|
|
<div class="flex items-center text-gray-400">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M6 18L18 6M6 6l12 12"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
{/if}
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{:else}
|
|
<div class="py-8 text-center">
|
|
<p class="text-gray-500">
|
|
No participants found. Click "Sync Participants" to load from Google Sheets.
|
|
</p>
|
|
</div>
|
|
{/if}
|
|
</div>
|