added editing; reversed list; fixed nap stat?; added repeater keys; styling;

This commit is contained in:
Spencer Flagg 2024-01-27 14:23:41 +01:00
parent d43322d16e
commit 6877c5ba97
8 changed files with 285 additions and 113 deletions

72
package-lock.json generated
View file

@ -10,8 +10,7 @@
"dependencies": { "dependencies": {
"@sveltejs/adapter-node": "^4.0.1", "@sveltejs/adapter-node": "^4.0.1",
"milligram": "^1.4.1", "milligram": "^1.4.1",
"pocketbase": "^0.20.3", "pocketbase": "^0.20.3"
"svelte-calendar": "^3.1.6"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.28.1", "@playwright/test": "^1.28.1",
@ -26,6 +25,7 @@
"eslint-plugin-svelte": "^2.35.1", "eslint-plugin-svelte": "^2.35.1",
"prettier": "^3.1.1", "prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2", "prettier-plugin-svelte": "^3.1.2",
"sass": "^1.70.0",
"svelte": "^4.2.7", "svelte": "^4.2.7",
"svelte-check": "^3.6.0", "svelte-check": "^3.6.0",
"tslib": "^2.4.1", "tslib": "^2.4.1",
@ -1442,7 +1442,7 @@
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"normalize-path": "^3.0.0", "normalize-path": "^3.0.0",
"picomatch": "^2.0.4" "picomatch": "^2.0.4"
@ -1500,7 +1500,7 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true, "devOptional": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@ -1517,7 +1517,7 @@
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"fill-range": "^7.0.1" "fill-range": "^7.0.1"
}, },
@ -1613,7 +1613,7 @@
"version": "3.5.3", "version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true, "devOptional": true,
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@ -1640,7 +1640,7 @@
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"is-glob": "^4.0.1" "is-glob": "^4.0.1"
}, },
@ -1735,11 +1735,6 @@
"node": ">=4" "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": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -2222,7 +2217,7 @@
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
}, },
@ -2462,6 +2457,12 @@
"node": ">= 4" "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": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -2514,7 +2515,7 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"binary-extensions": "^2.0.0" "binary-extensions": "^2.0.0"
}, },
@ -2551,7 +2552,7 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true, "devOptional": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -2560,7 +2561,7 @@
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"is-extglob": "^2.1.1" "is-extglob": "^2.1.1"
}, },
@ -2577,7 +2578,7 @@
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true, "devOptional": true,
"engines": { "engines": {
"node": ">=0.12.0" "node": ">=0.12.0"
} }
@ -2653,11 +2654,6 @@
"integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
"dev": true "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": { "node_modules/keyv": {
"version": "4.5.4", "version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@ -2935,7 +2931,7 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true, "devOptional": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -3392,7 +3388,7 @@
"version": "3.6.0", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"picomatch": "^2.2.1" "picomatch": "^2.2.1"
}, },
@ -3539,6 +3535,23 @@
"rimraf": "bin.js" "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": { "node_modules/semver": {
"version": "7.5.4", "version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@ -3762,15 +3775,6 @@
"node": ">=16" "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": { "node_modules/svelte-check": {
"version": "3.6.3", "version": "3.6.3",
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.3.tgz", "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.3.tgz",
@ -3937,7 +3941,7 @@
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"is-number": "^7.0.0" "is-number": "^7.0.0"
}, },

View file

@ -27,6 +27,7 @@
"eslint-plugin-svelte": "^2.35.1", "eslint-plugin-svelte": "^2.35.1",
"prettier": "^3.1.1", "prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2", "prettier-plugin-svelte": "^3.1.2",
"sass": "^1.70.0",
"svelte": "^4.2.7", "svelte": "^4.2.7",
"svelte-check": "^3.6.0", "svelte-check": "^3.6.0",
"tslib": "^2.4.1", "tslib": "^2.4.1",
@ -38,7 +39,6 @@
"dependencies": { "dependencies": {
"@sveltejs/adapter-node": "^4.0.1", "@sveltejs/adapter-node": "^4.0.1",
"milligram": "^1.4.1", "milligram": "^1.4.1",
"pocketbase": "^0.20.3", "pocketbase": "^0.20.3"
"svelte-calendar": "^3.1.6"
} }
} }

View 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>

View file

@ -48,7 +48,7 @@
} }
onMount(() => { onMount(() => {
const interval = setInterval(updateTimes, 1000); // Update every minute const interval = setInterval(updateTimes, 2000); // Update every 2 minutes
return () => { return () => {
clearInterval(interval); // Cleanup on component destruction clearInterval(interval); // Cleanup on component destruction

View file

@ -1,75 +1,124 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { pb, currentUser } from '$lib/pocketbase'; import { pb, currentUser } from '$lib/pocketbase';
import Counters from '$lib/components/counters.svelte'; import Counters from '$lib/components/counters.svelte';
import Action from '$lib/components/Action.svelte';
type Action = { type Action = {
type: string; type: string;
timestamp: string; timestamp: string;
}; };
let actions: Action[] = []; let actions: Action[] = [];
onMount(async () => { onMount(async () => {
await fetchActions(); 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> </script>
{#if $currentUser} <style lang="scss">
<aside> .today__list {
{#if isLastActionAsleep} ul {
<button class="button--awake" on:click={() => recordAction('awake')}>Awake</button> display: flex;
{:else} flex-direction: column;
{#if !isLastActionAwake} //gap: 1rem;
<button class="button--awake" on:click={() => recordAction('awake')}>Awake</button> list-style: none;
{/if} }
<button class="button--asleep" on:click={() => recordAction('asleep')}>Asleep</button> .today__item {
<button class="button--food" on:click={() => recordAction('food')}>Food</button> position: relative;
<button class="button--diaper" on:click={() => recordAction('diaper')}>Diaper</button> padding: 1.5rem 2rem;
{#if isLastActionDiaper} border-radius: 1.5rem;
<button class="button--poop" on:click={() => recordAction('poop')}>Poop</button> display: flex;
{/if} align-items: center;
{/if} gap: 1rem;
</aside>
<section> width: 15ch;
<h2>Today</h2> font-size: 2.5rem;
<div class="today__list"> &:nth-child(odd) {
<ul> background: var(--c-zebra);
{#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> </style>
<Counters {actions} />
</div> {#if $currentUser}
</section> <aside>
{/if} {#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}

View file

@ -122,16 +122,16 @@ import { onMount } from 'svelte';
<div></div> <div></div>
<!-- Day Headers --> <!-- Day Headers -->
{#each daysOfWeek as day} {#each daysOfWeek as day (day)}
<div class="day-header">{day}</div> <div class="day-header">{day}</div>
{/each} {/each}
<!-- Hour Labels and Calendar Grid --> <!-- Hour Labels and Calendar Grid -->
{#each hours as hour} {#each hours as hour (hour)}
<div class="hour-label">{formatHour(hour)}</div> <!-- Hour label --> <div class="hour-label">{formatHour(hour)}</div> <!-- Hour label -->
{#each daysOfWeek as _, dayIndex} {#each daysOfWeek as _, dayIndex}
<div class="hour"> <div class="hour">
{#each actions as action} {#each actions as action (action.id)}
{#if getDayOfWeek(action.timestamp) === dayIndex && getHourOfDay(action.timestamp) === hour} {#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> <div class="event event--{action.type}"><span class="event__title">{action.type}</span><span class="event__time">{formatTime(action.timestamp)}</span></div>
{/if} {/if}

View file

@ -175,10 +175,12 @@
<section> <section>
<h2>Stats</h2> <h2>Stats</h2>
<p>(let me know how broken these are)</p>
<ul> <ul>
<li>{stats.avgSleepPerNap} min / nap</li> <li>{stats.avgSleepPerNap} min / nap</li>
<li>{stats.avgNapsPerDay} naps / day</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.avgDiaperChanges} diapers / day</li>
<li>{stats.avgPoops} days between poops</li> <li>{stats.avgPoops} days between poops</li>
<li>{stats.avgEatingTimes} meals / day</li> <li>{stats.avgEatingTimes} meals / day</li>

View file

@ -25,12 +25,14 @@ html[data-theme='light'] body {
background-color: #f2f0ef; background-color: #f2f0ef;
--c-border: #e9e9e9; --c-border: #e9e9e9;
--c-toggle: #00464b; --c-toggle: #00464b;
--c-zebra: #ececec;
} }
html[data-theme='dark'] body { html[data-theme='dark'] body {
background-color: #181818; background-color: #181818;
--c-border: #2b2b2b; --c-border: #2b2b2b;
--c-toggle: #ffe600; --c-toggle: #ffe600;
--c-zebra: #ececec11;
} }
@ -43,6 +45,11 @@ textarea:focus {
color: var(--c-primary); color: var(--c-primary);
} }
button,
input[type='submit'] {
--color: var(--c-primary);
}
button, button,
input[type='submit'] { input[type='submit'] {
background-color: var(--color); background-color: var(--color);
@ -72,10 +79,6 @@ nav ul li {
list-style: none; list-style: none;
} }
.today__list ul {
list-style: none;
}
header { header {
padding-top: 2rem; padding-top: 2rem;
} }
@ -140,5 +143,14 @@ section {
margin-right: -2rem; margin-right: -2rem;
border-radius: 2rem 0 0 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;
}
} }