koro

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

commit 6f6cd060ecd375754ff089f4331e9399bf78ad74
parent 13d9502db2d068f5d4f24c1179e6807fa8e54a99
Author: mokou <mokou@posteo.de>
Date:   Thu, 21 May 2020 15:33:20 +0200

feat(event): Add a response grid

Diffstat:
Asrc/components/ResponseGrid.svelte | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/pages/Event.svelte | 37++++++++++++++++++++++++++++++++++++-
2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/src/components/ResponseGrid.svelte b/src/components/ResponseGrid.svelte @@ -0,0 +1,55 @@ +<script> + export let times + export let responses + import day from 'dayjs' + import utc from 'dayjs/plugin/utc' + day.extend(utc) + + let view = [0, 9] + + function reduceStatus (status, time) { + return Object.values(responses).reduce((acc, r) => { + if (r[day.utc(time).format()] === status) + return acc + 1 + return acc + }, 0) + } +</script> + +<div class="max-w-3xl grid grid-cols-12"> + <div class="col-span-3"></div> + {#each times.slice(view[0], view[1]) as t} + <div class="text-center">{day.utc(t).local().format('DD/MM hh:mm')}</div> + {/each} + {#if times.slice(view[0], view[1]).length < 9} + {#each new Array(9 - times.slice(view[0], view[1]).length) as a} + <div></div> + {/each} + {/if} + {#each Object.keys(responses) as name} + <div class="col-span-3">{name}</div> + {#each times.slice(view[0], view[1]) as t} + <div + class:bg-green-200={responses[name][day.utc(t).format()] === 'yes'} + class:bg-yellow-200={responses[name][day.utc(t).format()] === 'maybe'} + class:bg-red-200={responses[name][day.utc(t).format()] === 'no'} + ></div> + {/each} + {#if times.slice(view[0], view[1]).length < 9} + {#each new Array(9 - times.slice(view[0], view[1]).length) as a} + <div></div> + {/each} + {/if} + {/each} + <div class="col-span-3"></div> + {#each times.slice(view[0], view[1]) as t} + <div + class="text-center" + class:bg-yellow-300={reduceStatus('yes', t) >= (Object.values(responses).length / 2)} + class:bg-green-500={reduceStatus('yes', t) === Object.values(responses).length} + class:text-white={reduceStatus('yes', t) === Object.values(responses).length} + > + {reduceStatus('yes', t)}/{Object.values(responses).length} + </div> + {/each} +</div> diff --git a/src/pages/Event.svelte b/src/pages/Event.svelte @@ -6,17 +6,42 @@ import utc from 'dayjs/plugin/utc' import relativeTime from 'dayjs/plugin/relativeTime' import { onMount } from 'svelte' + import ResponseGrid from '../components/ResponseGrid.svelte' day.extend(utc) day.extend(relativeTime) let loading = true + let errorFlash = '' let error = '' let event = {} let name = '' let responses = {} async function onSubmit () { + if (!name) { + errorFlash = 'Please enter a name!' + return + } + if (Object.keys(responses).length === 0) { + errorFlash = 'Please select at least one time!' + return + } + + // TODO: Sync the document so we can make sure we have the + // most recent available version, which would reduce conflicts. + + const db = new PouchDB('koro') + let responsesToPut = event.responses || new Object() + responsesToPut[name] = responses + try { + await db.put({ + responses: responsesToPut, + ...event + }) + } catch (e) { + console.error(e) + } } function toggleYes (date) { @@ -64,13 +89,21 @@ {error} {:else} <h1 class="text-5xl font-serif font-extrabold">{event.name}</h1> - + <div class="max-w-xl">{#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}</div> {#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> + {:else} + <ResponseGrid times={event.times} responses={event.responses} /> {/if} <form class="mt-5 max-w-xl" on:submit|preventDefault={onSubmit}> @@ -97,5 +130,7 @@ <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> + + <button class="btn mt-5" on:click|preventDefault={onSubmit}>Submit</button> </form> {/if}