Improved UX for the creation flow
This commit is contained in:
@@ -11,9 +11,9 @@
|
|||||||
let participants = $state([]);
|
let participants = $state([]);
|
||||||
let subject = $state('');
|
let subject = $state('');
|
||||||
let body = $state('');
|
let body = $state('');
|
||||||
|
let authorized = $state(false);
|
||||||
|
|
||||||
// Update events and participants from the form data
|
$effect(() => {
|
||||||
$effect( () => {
|
|
||||||
if (form && form.new_event) {
|
if (form && form.new_event) {
|
||||||
new_event = form.new_event;
|
new_event = form.new_event;
|
||||||
}
|
}
|
||||||
@@ -31,10 +31,15 @@
|
|||||||
StepOverview
|
StepOverview
|
||||||
];
|
];
|
||||||
|
|
||||||
// State variable for current step
|
let step: number = $state(0);
|
||||||
let step = $state(0);
|
|
||||||
|
let stepConditions = $derived([
|
||||||
|
authorized,
|
||||||
|
!!new_event?.name,
|
||||||
|
!!participants?.length,
|
||||||
|
!!subject && !!body
|
||||||
|
]);
|
||||||
|
|
||||||
// Helper to go to next/previous step (optional)
|
|
||||||
function nextStep() {
|
function nextStep() {
|
||||||
if (step < steps.length - 1) step += 1;
|
if (step < steps.length - 1) step += 1;
|
||||||
}
|
}
|
||||||
@@ -56,16 +61,15 @@
|
|||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
onclick={nextStep}
|
onclick={nextStep}
|
||||||
disabled={step === steps.length - 1}
|
disabled={step === steps.length - 1 || !stepConditions[step]}
|
||||||
class="min-w-[100px] py-2 px-4 bg-white border border-gray-300 text-gray-700 rounded hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition"
|
class="min-w-[100px] py-2 px-4 bg-white border border-gray-300 text-gray-700 rounded hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition"
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Render the current step component -->
|
|
||||||
{#if step == 0}
|
{#if step == 0}
|
||||||
<StepConnectGoogle />
|
<StepConnectGoogle bind:authorized />
|
||||||
{:else if step == 1}
|
{:else if step == 1}
|
||||||
<StepCreateEvent events={data.events} {new_event} />
|
<StepCreateEvent events={data.events} {new_event} />
|
||||||
{:else if step == 2}
|
{:else if step == 2}
|
||||||
@@ -73,5 +77,11 @@
|
|||||||
{:else if step == 3}
|
{:else if step == 3}
|
||||||
<StepCraftEmail bind:subject bind:body />
|
<StepCraftEmail bind:subject bind:body />
|
||||||
{:else if step == 4}
|
{:else if step == 4}
|
||||||
<StepOverview {new_event} {participants} {subject} {body} />
|
<StepOverview
|
||||||
|
{new_event}
|
||||||
|
{participants}
|
||||||
|
{subject}
|
||||||
|
{body}
|
||||||
|
{stepConditions}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
|
export let authorized = false;
|
||||||
|
|
||||||
let refreshToken = '';
|
let refreshToken = '';
|
||||||
let authorized = false;
|
|
||||||
let loading = true;
|
let loading = true;
|
||||||
|
|
||||||
let to = '';
|
let to = '';
|
||||||
@@ -32,22 +33,6 @@
|
|||||||
/* ⇢ redirects straight to Google via server 302 */
|
/* ⇢ redirects straight to Google via server 302 */
|
||||||
const connect = () => goto('/private/api/gmail?action=auth');
|
const connect = () => goto('/private/api/gmail?action=auth');
|
||||||
|
|
||||||
async function sendEmail() {
|
|
||||||
const r = await fetch('/private/api/gmail', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
action: 'send',
|
|
||||||
to,
|
|
||||||
subject,
|
|
||||||
text: body,
|
|
||||||
refreshToken
|
|
||||||
})
|
|
||||||
});
|
|
||||||
r.ok ? alert('Sent!') : alert(await r.text());
|
|
||||||
to = subject = body = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
async function disconnect() {
|
async function disconnect() {
|
||||||
if (!confirm('Disconnect Google account?')) return;
|
if (!confirm('Disconnect Google account?')) return;
|
||||||
await fetch('/private/api/gmail', {
|
await fetch('/private/api/gmail', {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let { new_event, participants, subject, body } = $props();
|
let { new_event, participants, subject, body, stepConditions } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- New Event Overview -->
|
<!-- New Event Overview -->
|
||||||
@@ -41,22 +41,22 @@
|
|||||||
class="mt-4 w-full rounded bg-blue-600 px-4 py-3 font-bold text-white
|
class="mt-4 w-full rounded bg-blue-600 px-4 py-3 font-bold text-white
|
||||||
transition-colors duration-200 hover:bg-blue-700
|
transition-colors duration-200 hover:bg-blue-700
|
||||||
disabled:cursor-not-allowed disabled:bg-gray-300 disabled:text-gray-500"
|
disabled:cursor-not-allowed disabled:bg-gray-300 disabled:text-gray-500"
|
||||||
disabled={!new_event?.name || !participants?.length || !subject || !body}
|
disabled={!stepConditions.every(Boolean)}
|
||||||
>
|
>
|
||||||
Generate QR codes and send
|
Generate QR codes and send
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="mt-2 space-y-1">
|
<div class="mt-2 space-y-1">
|
||||||
{#if !new_event?.name}
|
{#if !stepConditions[0]}
|
||||||
<p class="text-sm text-red-500">Please provide an event name before proceeding.</p>
|
<p class="text-sm text-red-500">Please provide an event name before proceeding.</p>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !participants?.length}
|
{#if !stepConditions[1]}
|
||||||
<p class="text-sm text-red-500">Please add at least one participant before proceeding.</p>
|
<p class="text-sm text-red-500">Please add at least one participant before proceeding.</p>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !subject}
|
{#if !stepConditions[2]}
|
||||||
<p class="text-sm text-red-500">Please provide an email subject before proceeding.</p>
|
<p class="text-sm text-red-500">Please provide an email subject before proceeding.</p>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !body}
|
{#if !stepConditions[3]}
|
||||||
<p class="text-sm text-red-500">Please provide an email body before proceeding.</p>
|
<p class="text-sm text-red-500">Please provide an email body before proceeding.</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user