koro

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

commit 8df1db8e5affa50b5b3b4a64b31584c2aa960141
parent 1497b02d8de93f73a0006a1eb0c8e9f1d062b614
Author: mokou <mokou@posteo.de>
Date:   Sun, 31 May 2020 14:18:19 +0200

feat: Add responsive design and layouts

Closes #2.

Diffstat:
Msrc/components/DateTimeGrid.svelte | 39++++++++++++++++++++++-----------------
Msrc/components/ResponseGrid.svelte | 91+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/main.css | 8+++++++-
Msrc/pages/Event.svelte | 5+++--
4 files changed, 91 insertions(+), 52 deletions(-)

diff --git a/src/components/DateTimeGrid.svelte b/src/components/DateTimeGrid.svelte @@ -62,34 +62,39 @@ } </script> -<div class="grid grid-cols-11 w-full max-w-5xl datetimegrid"> - <div class="text-center hover:cursor-pointer" on:click={previousDay}> +<div class="grid grid-cols-4 lg:grid-cols-11 w-full max-w-5xl datetimegrid"> + <div + class="block lg:hidden text-xs bg-black text-white" + on:click={() => (view = view[1] < datesDay1.length ? [view[0] + 1, view[1] + 1] : view)} + >+30 mins</div> + <div + class="block lg:hidden text-xs bg-black text-white" + on:click={() => (view = view[0] !== 0 ? [view[0] - 1, view[1] - 1] : view)} + >-30 mins</div> + <div class="block lg:hidden text-xs bg-black text-white" on:click={nextDay}>+1 day</div> + <div class="block lg:hidden text-xs bg-black text-white" on:click={previousDay}>-1 day</div> + <div class="text-center hidden lg:block hover:cursor-pointer" on:click={previousDay}> {day1.date() === day(startDate).date() ? '' : '▲'} </div> <div - class="text-center hover:cursor-pointer" + class="text-center hidden lg:block hover:cursor-pointer" on:click={() => (view = view[0] !== 0 ? [view[0] - 1, view[1] - 1] : view)}> {view[0] !== 0 ? '‹' : ''} </div> - <div class="col-span-8" /> + <div class="col-span-8 hidden lg:block" /> <div - class="text-center hover:cursor-pointer" + class="text-center hidden lg:block hover:cursor-pointer" on:click={() => (view = view[1] < datesDay1.length ? [view[0] + 1, view[1] + 1] : view)}> {view[1] < datesDay1.length ? '›' : ''} </div> - <div class="font-bold"> + <div class="font-bold col-span-4 lg:col-span-1"> {day1.date() === day(startDate).date() ? 'today' : day1 .endOf('day') .fromNow()} </div> - {#if datesDay1.slice(view[0], view[1]).length < 5} - {#each new Array(5 - datesDay1.slice(view[0], view[1]).length) as a} - <div /> - {/each} - {/if} {#each datesDay1.slice(view[0], view[1]) as t} <div - class="text-center time hover:cursor-pointer" + class="text-center time col-span-4 lg:col-span-1 hover:cursor-pointer" class:text-gray-600={day().isAfter(t)} class:time-unselectable={day().isAfter(t)} class:bg-purple-600={!day().isAfter(t) && selected.includes(t.toISOString())} @@ -99,14 +104,14 @@ </div> {/each} - <div> + <div class="col-span-4 lg:col-span-1"> {day2.date() === day(startDate).date() ? 'today' : day2 .endOf('day') .fromNow()} </div> {#each datesDay2.slice(view[0], view[1]) as t} <div - class="text-center time hover:cursor-pointer" + class="text-center time col-span-4 lg:col-span-1 hover:cursor-pointer" class:bg-purple-600={selected.includes(t.toISOString())} class:text-white={selected.includes(t.toISOString())} on:click={() => addOrRemove(t)}> @@ -114,21 +119,21 @@ </div> {/each} - <div> + <div class="col-span-4 lg:col-span-1"> {day3.date() === day(startDate).date() ? 'today' : day3 .endOf('day') .fromNow()} </div> {#each datesDay3.slice(view[0], view[1]) as t} <div - class="text-center time hover:cursor-pointer" + class="text-center time col-span-4 lg:col-span-1 hover:cursor-pointer" class:bg-purple-600={selected.includes(t.toISOString())} class:text-white={selected.includes(t.toISOString())} on:click={() => addOrRemove(t)}> {t.format($is24Hrs ? 'HH:mm' : 'hh:mma')} </div> {/each} - <div class="text-center hover:cursor-pointer" on:click={nextDay}>▼</div> + <div class="text-center hidden lg:block hover:cursor-pointer" on:click={nextDay}>▼</div> </div> <div class="mt-2"> diff --git a/src/components/ResponseGrid.svelte b/src/components/ResponseGrid.svelte @@ -3,10 +3,14 @@ export let responses import day from 'dayjs' import utc from 'dayjs/plugin/utc' + import { onDestroy } from 'svelte' import { is24Hrs } from '../stores' day.extend(utc) - let view = [0, 9] + $: hasManyTimes = times.length > 10 + let windowWidth = window.innerWidth + + window.addEventListener('resize', updateWindowSize) function reduceStatus(status, time) { return Object.values(responses).reduce((acc, r) => { @@ -14,40 +18,63 @@ return acc }, 0) } + + function updateWindowSize () { + windowWidth = window.innerWidth + } + + onDestroy(() => { + window.removeEventListener('resize', updateWindowSize) + }) </script> -<div class="max-w-3xl grid grid-cols-12"> - <div class="col-span-3" /> - {#each times.slice(view[0], view[1]) as t} - <div class="text-center">{day.utc(t).local().format(`DD/MM ${$is24Hrs ? 'HH:mm' : 'hh:mma'}`)}</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 /> - {/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'} /> +{#if !hasManyTimes && windowWidth > 1024} + <div class="grid grid-cols-12"> + <div class="col-span-2" /> + {#each times as t} + <div class="text-center">{day.utc(t).local().format(`DD/MM ${$is24Hrs ? 'HH:mm' : 'hh:mma'}`)}</div> {/each} - {#if times.slice(view[0], view[1]).length < 9} - {#each new Array(9 - times.slice(view[0], view[1]).length) as a} + {#if times.length < 10} + {#each new Array(10 - times.length) as a} <div /> {/each} {/if} - {/each} - <div class="col-span-3" /> - {#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> + {#each Object.keys(responses) as name} + <div class="col-span-2">{name}</div> + {#each times 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'} /> + {/each} + {#if times.length < 10} + {#each new Array(10 - times.length) as a} + <div /> + {/each} + {/if} + {/each} + <div class="col-span-2" /> + {#each times 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> +{:else} + <div class="grid grid-cols-2 max-w-lg"> + {#each times as t} + <div class="text-center font-bold py-2">{day.utc(t).local().format(`DD/MM ${$is24Hrs ? 'HH:mm' : 'hh:mma'}`)}</div> + <div + class="py-2 text-center rounded-sm" + class:bg-green-500={reduceStatus('yes', t) === Object.values(responses).length} + class:bg-yellow-300={reduceStatus('yes', t) >= Object.values(responses).length / 2} + class:text-white={reduceStatus('yes', t) === Object.values(responses).length}> + {reduceStatus('yes', t)}/{Object.values(responses).length} + </div> + {/each} + </div> +{/if} diff --git a/src/main.css b/src/main.css @@ -82,7 +82,13 @@ input:focus { } .grid-cols-3-1 { - grid-template-columns: 10% 10% 10% auto; + grid-template-columns: 20% 20% 20% auto; +} + +@media lg { + .grid-cols-3-1 { + grid-template-columns: 10% 10% 10% auto; + } } @media sm { diff --git a/src/pages/Event.svelte b/src/pages/Event.svelte @@ -183,9 +183,10 @@ on:click={() => toggleNo(t)} /> <div class="ml-3"> <span class="font-bold"> - {day.utc(t).local().format(`DD/MM/YYYY ${$is24Hrs ? 'HH:mm' : 'hh:mma'}`)} + <span class="text-center block lg:inline">{day.utc(t).local().format('DD/MM/YYYY')}</span> + <span class="text-center block lg:inline">{day.utc(t).local().format($is24Hrs ? 'HH:mm' : 'hh:mma')}</span> </span> - ({day.utc(t).local().fromNow()}) + <span class="hidden lg:block">({day.utc(t).local().fromNow()})</span> </div> {/each} </div>