koro

an event time scheduler
git clone https://tilde.team/~marisa/repo/koro.git
Log | Files | Refs | README | LICENSE

commit 13d9502db2d068f5d4f24c1179e6807fa8e54a99
parent e7ac63ba4c86baaab18770df74b12f12ea905072
Author: mokou <mokou@posteo.de>
Date:   Thu, 21 May 2020 04:12:04 +0200

feat: Fundamental event page

Diffstat:
Msrc/main.css | 4++++
Msrc/pages/Event.svelte | 98++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/pages/Index.svelte | 84+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
3 files changed, 153 insertions(+), 33 deletions(-)

diff --git a/src/main.css b/src/main.css @@ -69,6 +69,10 @@ input:focus { border-color: #a4cafe; } +.grid-cols-3-1 { + grid-template-columns: 10% 10% 10% auto; +} + @media sm { input { @apply text-sm leading-tight; diff --git a/src/pages/Event.svelte b/src/pages/Event.svelte @@ -1,5 +1,101 @@ <script> export let params + + import PouchDB from 'pouchdb-browser' + import day from 'dayjs' + import utc from 'dayjs/plugin/utc' + import relativeTime from 'dayjs/plugin/relativeTime' + import { onMount } from 'svelte' + day.extend(utc) + day.extend(relativeTime) + + let loading = true + let error = '' + let event = {} + let name = '' + let responses = {} + + async function onSubmit () { + + } + + function toggleYes (date) { + const d = day.utc(date).format() + if (responses[d] === 'yes') { + responses[d] = '' + return + } + responses[d] = 'yes' + } + + function toggleMaybe (date) { + const d = day.utc(date).format() + if (responses[d] === 'maybe') { + responses[d] = '' + return + } + responses[d] = 'maybe' + } + + function toggleNo (date) { + const d = day.utc(date).format() + if (responses[d] === 'no') { + responses[d] = '' + return + } + responses[d] = 'no' + } + + onMount(async () => { + const db = new PouchDB('koro') + try { + event = await db.get(params.id) + loading = false + } catch (e) { + error = 'Couldn\'t fetch the event you\'re looking for. Do you have the right link? Or maybe you\'re offline?' + loading = false + } + }) </script> -<h1>E!</h1> +{#if loading} + Loading event information... +{:else if !loading && error} + {error} +{:else} + <h1 class="text-5xl font-serif font-extrabold">{event.name}</h1> + + {#if !event.responses || event.responses.length === 0} + <p class="text-xl mb-5 max-w-xl"> + Someone has shared this event and wants you to indicate your availability + at the specified times! Fill out the form to tell them when you're free. + </p> + <p class="text-xl">No responses yet. You can be the first!</p> + {/if} + + <form class="mt-5 max-w-xl" on:submit|preventDefault={onSubmit}> + <label for="name" class="font-bold text-gray-600">Your name</label> + <input type="text" bind:value={name} /> + <div class="grid mt-4 grid-cols-3-1"> + <div class="text-center">Yes</div> + <div class="text-center">Maybe</div> + <div class="text-center">No</div> + <div></div> + {#each event.times.sort((a, b) => day.utc(a).isAfter(day.utc(b))) as t} + <div + class:bg-green-400={responses[day.utc(t).format()] === 'yes'} + class="border border-gray-200" + on:click={() => toggleYes(t)}></div> + <div + class:bg-yellow-400={responses[day.utc(t).format()] === 'maybe'} + class="border border-gray-200" + on:click={() => toggleMaybe(t)}></div> + <div + class:bg-red-400={responses[day.utc(t).format()] === 'no'} + class="border border-gray-200" + on:click={() => toggleNo(t)}></div> + <div class="ml-3"><span class="font-bold">{day.utc(t).local().format('DD/MM/YYYY hh:mm')}</span> ({day.utc(t).local().fromNow()})</div> + {/each} + </div> + </form> +{/if} diff --git a/src/pages/Index.svelte b/src/pages/Index.svelte @@ -2,11 +2,15 @@ import PouchDB from 'pouchdb-browser' import autocomplete from 'accessible-autocomplete' import search from 'fuzzysearch' + import day from 'dayjs' + import utc from 'dayjs/plugin/utc' import { nanoid } from 'nanoid' import { onMount } from 'svelte' import DateTimeGrid from '../components/DateTimeGrid.svelte' + day.extend(utc) let submitting = false + let success = false let errorFlash = '' let durationInput = null let durationsList = [ @@ -25,6 +29,7 @@ duration: '', times: [], } + let eventLink = '' async function submitForm() { errorFlash = '' @@ -56,8 +61,12 @@ const db = new PouchDB('koro') try { - const res = await db.put(event) - console.log(res) + const res = await db.put({ + times: event.times.map(e => day(e).utc().format()), + ...event + }) + success = true + eventLink = `https://koro.com/${res.id}` } catch (e) { console.error(e) } @@ -77,40 +86,51 @@ confirmOnBlur: false, onConfirm: (opt) => { event.duration = opt - console.log(event) }, }) }) </script> <h1 class="text-5xl font-serif font-extrabold">koro</h1> -<p class="text-2xl font-medium max-w-xl leading-normal"> - An event time planning site for the rest of us. Use this to find a timeslot - for your next meeting, party, raid, whatever you want. It automatically - supports the user's timezone and works locally, too. -</p> +{#if success} + <p class="text-2xl font-medium max-w-xl leading-normal"> + Your event has successfully been created! You can share the link below with + anyone you want to invite, and they can set their available times from the ones + you picked out. Don't forget to fill it out yourself! + </p> -<form class="max-w-xl mt-7" on:submit|preventDefault={submitForm}> - {#if errorFlash} - <div - class="w-full bg-red-100 px-3 py-2 border rounded border-red-400 - text-red-600 my-5"> - {errorFlash} - </div> - {/if} - <label for="name" class="font-bold text-gray-600">Your event's name</label> - <input - id="name" - type="text" - bind:value={event.name} - placeholder="Raid with the boys" /> - <label for="duration" class="font-bold text-gray-600 mt-3"> - Duration of the event - </label> - <div id="duration-mount" class="mb-5" /> - <label class="font-bold text-gray-600">Event start times</label> - <DateTimeGrid startDate={new Date()} bind:selected={event.times} /> - <button class="btn mt-5" type="submit" disabled={submitting}> - Create event - </button> -</form> + <div class="text-2xl font-mono bg-black text-white max-w-xl w-full px-3 py-2 mt-5 text-center"> + {eventLink} + </div> +{:else} + <p class="text-2xl font-medium max-w-xl leading-normal"> + An event time planning site for the rest of us. Use this to find a timeslot + for your next meeting, party, raid, whatever you want. It automatically + supports the user's timezone and works locally, too. + </p> + + <form class="max-w-xl mt-6" on:submit|preventDefault={submitForm}> + {#if errorFlash} + <div + class="w-full bg-red-100 px-3 py-2 border rounded border-red-400 + text-red-600 my-5"> + {errorFlash} + </div> + {/if} + <label for="name" class="font-bold text-gray-600">Your event's name</label> + <input + id="name" + type="text" + bind:value={event.name} + placeholder="Raid with the boys" /> + <label for="duration" class="font-bold text-gray-600 inline-block mt-4"> + Duration of the event + </label> + <div id="duration-mount" class="mb-5" /> + <label class="font-bold text-gray-600">Event start times</label> + <DateTimeGrid startDate={new Date()} bind:selected={event.times} /> + <button class="btn mt-5" type="submit" disabled={submitting}> + Create event + </button> + </form> +{/if}