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:
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}