added editing; reversed list; fixed nap stat?; added repeater keys; styling;
This commit is contained in:
parent
d43322d16e
commit
6877c5ba97
8 changed files with 285 additions and 113 deletions
72
package-lock.json
generated
72
package-lock.json
generated
|
|
@ -10,8 +10,7 @@
|
|||
"dependencies": {
|
||||
"@sveltejs/adapter-node": "^4.0.1",
|
||||
"milligram": "^1.4.1",
|
||||
"pocketbase": "^0.20.3",
|
||||
"svelte-calendar": "^3.1.6"
|
||||
"pocketbase": "^0.20.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.28.1",
|
||||
|
|
@ -26,6 +25,7 @@
|
|||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"sass": "^1.70.0",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tslib": "^2.4.1",
|
||||
|
|
@ -1442,7 +1442,7 @@
|
|||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
|
|
@ -1500,7 +1500,7 @@
|
|||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -1517,7 +1517,7 @@
|
|||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
|
|
@ -1613,7 +1613,7 @@
|
|||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
|
@ -1640,7 +1640,7 @@
|
|||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
|
|
@ -1735,11 +1735,6 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.10",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
|
||||
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
|
|
@ -2222,7 +2217,7 @@
|
|||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
|
|
@ -2462,6 +2457,12 @@
|
|||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
|
||||
"integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
|
|
@ -2514,7 +2515,7 @@
|
|||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
|
|
@ -2551,7 +2552,7 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -2560,7 +2561,7 @@
|
|||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
|
|
@ -2577,7 +2578,7 @@
|
|||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
|
|
@ -2653,11 +2654,6 @@
|
|||
"integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/just-throttle": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/just-throttle/-/just-throttle-2.3.1.tgz",
|
||||
"integrity": "sha512-0H4miIAWZYpnpg7oD/Y/PBb77ISSHAETif5xK9EnwIgYCO6oC8ErkJxDumMUTR44shSOwptRIArRuvNuvN/hOw=="
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
|
|
@ -2935,7 +2931,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -3392,7 +3388,7 @@
|
|||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
|
|
@ -3539,6 +3535,23 @@
|
|||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.70.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
|
||||
"integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
|
|
@ -3762,15 +3775,6 @@
|
|||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-calendar": {
|
||||
"version": "3.1.6",
|
||||
"resolved": "https://registry.npmjs.org/svelte-calendar/-/svelte-calendar-3.1.6.tgz",
|
||||
"integrity": "sha512-jOHiPlxBAa1LGVFQZoczdAGnCSI2RKcuQQHj32TjLbXO/P2Povx4JphPEcP7XjKj/s/jimBC6xQyFhyjD0vxbg==",
|
||||
"dependencies": {
|
||||
"dayjs": "^1.10.6",
|
||||
"just-throttle": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-check": {
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.3.tgz",
|
||||
|
|
@ -3937,7 +3941,7 @@
|
|||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"sass": "^1.70.0",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tslib": "^2.4.1",
|
||||
|
|
@ -38,7 +39,6 @@
|
|||
"dependencies": {
|
||||
"@sveltejs/adapter-node": "^4.0.1",
|
||||
"milligram": "^1.4.1",
|
||||
"pocketbase": "^0.20.3",
|
||||
"svelte-calendar": "^3.1.6"
|
||||
"pocketbase": "^0.20.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
105
src/lib/components/Action.svelte
Normal file
105
src/lib/components/Action.svelte
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let action;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let dialog: HTMLDialogElement;
|
||||
|
||||
const adjustTime = (minutes: number) => {
|
||||
const timestamp = new Date(action.timestamp);
|
||||
timestamp.setMinutes(timestamp.getMinutes() + minutes);
|
||||
action.timestamp = timestamp.toISOString();
|
||||
console.log(action);
|
||||
dispatch('update', action);
|
||||
};
|
||||
|
||||
const deleteAction = () => {
|
||||
dispatch('delete', action);
|
||||
dialog.close();
|
||||
};
|
||||
|
||||
const openDialog = () => {
|
||||
dialog.showModal();
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
dialog.close();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.button--action {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.button--edit-time {
|
||||
padding: 0 1em;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.button--close {
|
||||
padding: 0 1em;
|
||||
border-radius: 999px;
|
||||
background-color: #c6c6c6;
|
||||
border-color: #c6c6c6;
|
||||
}
|
||||
|
||||
dialog {
|
||||
width: 50vw;
|
||||
height: 50vh;
|
||||
border-radius: 3rem;
|
||||
border: none;
|
||||
z-index: 1;
|
||||
&::backdrop {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.dialog__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
.dialog__middle {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<button class="button--action" on:click={openDialog}></button>
|
||||
|
||||
<span class="badge badge--{action.type}">{action.type}</span> at {new Date(
|
||||
action.timestamp
|
||||
).toLocaleTimeString('en-NL', { hour: '2-digit', minute: '2-digit' })}
|
||||
|
||||
<dialog bind:this={dialog}>
|
||||
<div class="dialog__content">
|
||||
<div class="">
|
||||
<h3>
|
||||
{action.type} @{new Date(action.timestamp).toLocaleString('en-NL', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="dialog__middle">
|
||||
<button class="button--edit-time" on:click={() => adjustTime(-5)}>-5</button>
|
||||
<button class="button--edit-time" on:click={() => adjustTime(-1)}>-1</button>
|
||||
<button class="button--edit-time" on:click={() => adjustTime(1)}>+1</button>
|
||||
<button class="button--edit-time" on:click={() => adjustTime(5)}>+5</button>
|
||||
<button class="button--edit-time" on:click={deleteAction}>Delete</button>
|
||||
</div>
|
||||
<div class=""><button class="button--close" on:click={closeDialog}>Done Editing</button></div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
}
|
||||
|
||||
onMount(() => {
|
||||
const interval = setInterval(updateTimes, 1000); // Update every minute
|
||||
const interval = setInterval(updateTimes, 2000); // Update every 2 minutes
|
||||
|
||||
return () => {
|
||||
clearInterval(interval); // Cleanup on component destruction
|
||||
|
|
|
|||
|
|
@ -1,75 +1,124 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { pb, currentUser } from '$lib/pocketbase';
|
||||
import Counters from '$lib/components/counters.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { pb, currentUser } from '$lib/pocketbase';
|
||||
import Counters from '$lib/components/counters.svelte';
|
||||
import Action from '$lib/components/Action.svelte';
|
||||
|
||||
type Action = {
|
||||
type: string;
|
||||
timestamp: string;
|
||||
};
|
||||
type Action = {
|
||||
type: string;
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
let actions: Action[] = [];
|
||||
let actions: Action[] = [];
|
||||
|
||||
onMount(async () => {
|
||||
await fetchActions();
|
||||
onMount(async () => {
|
||||
await fetchActions();
|
||||
});
|
||||
|
||||
async function recordAction(actionType: string) {
|
||||
const action = {
|
||||
// No longer specifying a timestamp here
|
||||
type: actionType,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
|
||||
// Send action to PocketBase
|
||||
await pb.collection('actions').create(action);
|
||||
|
||||
// Refresh actions list
|
||||
await fetchActions();
|
||||
}
|
||||
|
||||
async function fetchActions() {
|
||||
// Fetch actions for the current day from PocketBase
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const result = await pb.collection('actions').getList<Action>(1, 50, {
|
||||
filter: `timestamp >= '${today}'`,
|
||||
sort: 'timestamp'
|
||||
});
|
||||
|
||||
// Assuming the items are in the 'items' property of the result
|
||||
actions = result.items;
|
||||
}
|
||||
|
||||
const updateAction = async (event) => {
|
||||
const updatedAction = event.detail;
|
||||
// Update the action in your PocketBase database
|
||||
await pb.collection('actions').update(updatedAction.id, updatedAction);
|
||||
// Re-fetch or update the actions array locally
|
||||
fetchActions();
|
||||
};
|
||||
|
||||
const deleteAction = async (event) => {
|
||||
const actionToDelete = event.detail;
|
||||
// Delete the action from your PocketBase database
|
||||
await pb.collection('actions').delete(actionToDelete.id);
|
||||
// Re-fetch or update the actions array locally
|
||||
fetchActions();
|
||||
};
|
||||
|
||||
$: isLastActionAsleep = actions.length > 0 && actions[actions.length - 1].type === 'asleep';
|
||||
$: isLastActionAwake = actions.length > 0 && actions[actions.length - 1].type === 'awake';
|
||||
$: isLastActionDiaper = actions.length > 0 && actions[actions.length - 1].type === 'diaper';
|
||||
|
||||
$: sortedActions = [...actions].sort((a, b) => {
|
||||
return new Date(b.timestamp) - new Date(a.timestamp);
|
||||
});
|
||||
|
||||
async function recordAction(actionType: string) {
|
||||
const action = { // No longer specifying a timestamp here
|
||||
type: actionType,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
|
||||
// Send action to PocketBase
|
||||
await pb.collection('actions').create(action);
|
||||
|
||||
// Refresh actions list
|
||||
await fetchActions();
|
||||
}
|
||||
|
||||
async function fetchActions() {
|
||||
// Fetch actions for the current day from PocketBase
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const result = await pb.collection('actions').getList<Action>(1, 50, {
|
||||
filter: `timestamp >= '${today}'`,
|
||||
sort: 'timestamp'
|
||||
});
|
||||
|
||||
// Assuming the items are in the 'items' property of the result
|
||||
actions = result.items;
|
||||
}
|
||||
|
||||
$: isLastActionAsleep = actions.length > 0 && actions[actions.length - 1].type === 'asleep';
|
||||
$: isLastActionAwake = actions.length > 0 && actions[actions.length - 1].type === 'awake';
|
||||
$: isLastActionDiaper = actions.length > 0 && actions[actions.length - 1].type === 'diaper';
|
||||
</script>
|
||||
|
||||
{#if $currentUser}
|
||||
<aside>
|
||||
{#if isLastActionAsleep}
|
||||
<button class="button--awake" on:click={() => recordAction('awake')}>Awake</button>
|
||||
{:else}
|
||||
{#if !isLastActionAwake}
|
||||
<button class="button--awake" on:click={() => recordAction('awake')}>Awake</button>
|
||||
{/if}
|
||||
<button class="button--asleep" on:click={() => recordAction('asleep')}>Asleep</button>
|
||||
<button class="button--food" on:click={() => recordAction('food')}>Food</button>
|
||||
<button class="button--diaper" on:click={() => recordAction('diaper')}>Diaper</button>
|
||||
{#if isLastActionDiaper}
|
||||
<button class="button--poop" on:click={() => recordAction('poop')}>Poop</button>
|
||||
{/if}
|
||||
{/if}
|
||||
</aside>
|
||||
<style lang="scss">
|
||||
.today__list {
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
//gap: 1rem;
|
||||
list-style: none;
|
||||
}
|
||||
.today__item {
|
||||
position: relative;
|
||||
padding: 1.5rem 2rem;
|
||||
border-radius: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
|
||||
<section>
|
||||
<h2>Today</h2>
|
||||
<div class="today__list">
|
||||
<ul>
|
||||
{#each actions as action}
|
||||
<li><span class="badge badge--{action.type}">{action.type}</span> at {new Date(action.timestamp).toLocaleTimeString('en-NL', { hour: '2-digit', minute: '2-digit' })}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<Counters {actions} />
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
width: 15ch;
|
||||
font-size: 2.5rem;
|
||||
&:nth-child(odd) {
|
||||
background: var(--c-zebra);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{#if $currentUser}
|
||||
<aside>
|
||||
{#if isLastActionAsleep}
|
||||
<button class="button--awake" on:click={() => recordAction('awake')}>Awake</button>
|
||||
{:else}
|
||||
{#if !isLastActionAwake}
|
||||
<button class="button--awake" on:click={() => recordAction('awake')}>Awake</button>
|
||||
{/if}
|
||||
<button class="button--asleep" on:click={() => recordAction('asleep')}>Asleep</button>
|
||||
<button class="button--food" on:click={() => recordAction('food')}>Food</button>
|
||||
<button class="button--diaper" on:click={() => recordAction('diaper')}>Diaper</button>
|
||||
{#if isLastActionDiaper}
|
||||
<button class="button--poop" on:click={() => recordAction('poop')}>Poop</button>
|
||||
{/if}
|
||||
{/if}
|
||||
</aside>
|
||||
|
||||
<section>
|
||||
<h2>Today</h2>
|
||||
<div class="today__list">
|
||||
<ul>
|
||||
{#each sortedActions as action (action.id)}
|
||||
<li class="today__item">
|
||||
<Action {action} on:update={updateAction} on:delete={deleteAction} />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<Counters {actions} />
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -122,16 +122,16 @@ import { onMount } from 'svelte';
|
|||
<div></div>
|
||||
|
||||
<!-- Day Headers -->
|
||||
{#each daysOfWeek as day}
|
||||
{#each daysOfWeek as day (day)}
|
||||
<div class="day-header">{day}</div>
|
||||
{/each}
|
||||
|
||||
<!-- Hour Labels and Calendar Grid -->
|
||||
{#each hours as hour}
|
||||
{#each hours as hour (hour)}
|
||||
<div class="hour-label">{formatHour(hour)}</div> <!-- Hour label -->
|
||||
{#each daysOfWeek as _, dayIndex}
|
||||
<div class="hour">
|
||||
{#each actions as action}
|
||||
{#each actions as action (action.id)}
|
||||
{#if getDayOfWeek(action.timestamp) === dayIndex && getHourOfDay(action.timestamp) === hour}
|
||||
<div class="event event--{action.type}"><span class="event__title">{action.type}</span><span class="event__time">{formatTime(action.timestamp)}</span></div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -175,10 +175,12 @@
|
|||
|
||||
<section>
|
||||
<h2>Stats</h2>
|
||||
<p>(let me know how broken these are)</p>
|
||||
<ul>
|
||||
<li>{stats.avgSleepPerNap} min / nap</li>
|
||||
<li>{stats.avgNapsPerDay} naps / day</li>
|
||||
<li>{stats.avgSleepPerDay} min of sleep / day</li>
|
||||
<!-- <li>{stats.avgSleepPerDay} min of sleep / day</li> -->
|
||||
<li>{stats.avgSleepPerNap * stats.avgNapsPerDay} min of sleep / day</li>
|
||||
<li>{stats.avgDiaperChanges} diapers / day</li>
|
||||
<li>{stats.avgPoops} days between poops</li>
|
||||
<li>{stats.avgEatingTimes} meals / day</li>
|
||||
|
|
|
|||
|
|
@ -25,12 +25,14 @@ html[data-theme='light'] body {
|
|||
background-color: #f2f0ef;
|
||||
--c-border: #e9e9e9;
|
||||
--c-toggle: #00464b;
|
||||
--c-zebra: #ececec;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] body {
|
||||
background-color: #181818;
|
||||
--c-border: #2b2b2b;
|
||||
--c-toggle: #ffe600;
|
||||
--c-zebra: #ececec11;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -43,6 +45,11 @@ textarea:focus {
|
|||
color: var(--c-primary);
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='submit'] {
|
||||
--color: var(--c-primary);
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='submit'] {
|
||||
background-color: var(--color);
|
||||
|
|
@ -72,10 +79,6 @@ nav ul li {
|
|||
list-style: none;
|
||||
}
|
||||
|
||||
.today__list ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
header {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
|
@ -140,5 +143,14 @@ section {
|
|||
margin-right: -2rem;
|
||||
border-radius: 2rem 0 0 2rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
.counters {
|
||||
margin-right: -2rem;
|
||||
border-radius: 2rem 0 0 2rem;
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
top:auto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue