187 lines
5.8 KiB
Svelte
187 lines
5.8 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte';
|
|
import { pb } from '$lib/pocketbase';
|
|
|
|
type Action = {
|
|
type: string;
|
|
created: string;
|
|
};
|
|
|
|
let stats = {
|
|
avgSleepPerNap: 0,
|
|
avgNapsPerDay: 0,
|
|
avgSleepPerDay: 0,
|
|
avgDiaperChanges: 0,
|
|
avgPoops: 0,
|
|
avgEatingTimes: 0
|
|
};
|
|
|
|
onMount(async () => {
|
|
const actions = await fetchAllActions();
|
|
calculateStats(actions);
|
|
});
|
|
|
|
async function fetchAllActions() {
|
|
// Fetch all actions. Adjust as needed for date range or pagination
|
|
const result = await pb.collection('actions').getList(1, 1000);
|
|
return result.items;
|
|
}
|
|
|
|
function calculateStats(actions: Action[]) {
|
|
// Implement the logic to calculate each statistic
|
|
// This is a placeholder and should be replaced with actual calculation logic
|
|
stats.avgSleepPerNap = calculateAvgSleepPerNap(actions);
|
|
stats.avgNapsPerDay = calculateAvgNapsPerDay(actions);
|
|
stats.avgSleepPerDay = calculateAvgSleepPerDay(actions);
|
|
stats.avgDiaperChanges = calculateAvgDiaperChanges(actions);
|
|
stats.avgPoops = calculateAvgDaysBetweenPoops(actions);
|
|
stats.avgEatingTimes = calculateAvgMealsPerDay(actions);
|
|
}
|
|
|
|
function calculateAvgSleepPerNap(actions: Action[]): number {
|
|
const sleepActions = actions.filter((a) => a.type === 'asleep' || a.type === 'awake');
|
|
sleepActions.sort((a, b) => new Date(a.created).getTime() - new Date(b.created).getTime());
|
|
|
|
let totalSleepTime = 0;
|
|
let napCount = 0;
|
|
|
|
for (let i = 0; i < sleepActions.length - 1; i++) {
|
|
if (sleepActions[i].type === 'asleep' && sleepActions[i + 1].type === 'awake') {
|
|
totalSleepTime +=
|
|
new Date(sleepActions[i + 1].created).getTime() -
|
|
new Date(sleepActions[i].created).getTime();
|
|
napCount++;
|
|
}
|
|
}
|
|
|
|
console.log('Total Sleep Time:', totalSleepTime);
|
|
console.log('Nap Count:', napCount);
|
|
|
|
return Math.round(napCount > 0 ? totalSleepTime / napCount / 1000 / 60 : 0); // returns average time in minutes
|
|
}
|
|
|
|
function calculateAvgNapsPerDay(actions: Action[]): number {
|
|
const sortedActions = actions.sort(
|
|
(a, b) => new Date(a.created).getTime() - new Date(b.created).getTime()
|
|
);
|
|
const daysMap = new Map<string, number>();
|
|
|
|
for (let i = 0; i < sortedActions.length - 1; i++) {
|
|
if (sortedActions[i].type === 'asleep' && sortedActions[i + 1].type === 'awake') {
|
|
const asleepDate = new Date(sortedActions[i].created);
|
|
const awakeDate = new Date(sortedActions[i + 1].created);
|
|
|
|
if (asleepDate.toDateString() === awakeDate.toDateString()) {
|
|
const dayKey = asleepDate.toDateString();
|
|
daysMap.set(dayKey, (daysMap.get(dayKey) || 0) + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
const totalNaps = Array.from(daysMap.values()).reduce((acc, naps) => acc + naps, 0);
|
|
return daysMap.size > 0 ? totalNaps / daysMap.size : 0;
|
|
}
|
|
|
|
function calculateAvgSleepPerDay(actions: Action[]): number {
|
|
const sortedActions = actions.sort(
|
|
(a, b) => new Date(a.created).getTime() - new Date(b.created).getTime()
|
|
);
|
|
const sleepDurations: number[] = [];
|
|
|
|
for (let i = 0; i < sortedActions.length - 1; i++) {
|
|
if (sortedActions[i].type === 'asleep' && sortedActions[i + 1].type === 'awake') {
|
|
const asleepDate = new Date(sortedActions[i].created);
|
|
const awakeDate = new Date(sortedActions[i + 1].created);
|
|
|
|
if (asleepDate.toDateString() === awakeDate.toDateString()) {
|
|
const sleepDuration = (awakeDate.getTime() - asleepDate.getTime()) / 1000 / 60; // Sleep duration in minutes
|
|
sleepDurations.push(sleepDuration);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sleepDurations.length === 0) return 0;
|
|
|
|
const totalSleepDuration = sleepDurations.reduce((a, b) => a + b, 0);
|
|
return Math.round(totalSleepDuration / sleepDurations.length);
|
|
}
|
|
|
|
function calculateAvgDiaperChanges(actions: Action[]): number {
|
|
let diaperChangesPerDay = new Map<string, number>();
|
|
|
|
for (const action of actions) {
|
|
if (action.type === 'diaper') {
|
|
const actionDate = action.created.split('T')[0]; // Extract the date part
|
|
diaperChangesPerDay.set(actionDate, (diaperChangesPerDay.get(actionDate) || 0) + 1);
|
|
}
|
|
}
|
|
|
|
if (diaperChangesPerDay.size === 0) {
|
|
return 0;
|
|
}
|
|
|
|
const totalDiaperChanges = Array.from(diaperChangesPerDay.values()).reduce(
|
|
(total, count) => total + count,
|
|
0
|
|
);
|
|
return totalDiaperChanges / diaperChangesPerDay.size;
|
|
}
|
|
|
|
function calculateAvgDaysBetweenPoops(actions: Action[]): number {
|
|
let poopDates = [];
|
|
|
|
// Extract dates of 'poop' actions
|
|
for (const action of actions) {
|
|
if (action.type === 'poop') {
|
|
const actionDate = new Date(action.created.split('T')[0]); // Extract the date part
|
|
poopDates.push(actionDate);
|
|
}
|
|
}
|
|
|
|
// Sort dates
|
|
poopDates.sort((a, b) => a.getTime() - b.getTime());
|
|
|
|
if (poopDates.length < 2) {
|
|
return 0; // Not enough data to calculate intervals
|
|
}
|
|
|
|
let totalDays = 0;
|
|
for (let i = 1; i < poopDates.length; i++) {
|
|
const interval =
|
|
(poopDates[i].getTime() - poopDates[i - 1].getTime()) / (1000 * 60 * 60 * 24); // Convert to days
|
|
totalDays += interval;
|
|
}
|
|
|
|
return parseFloat((totalDays / (poopDates.length - 1)).toFixed(2));
|
|
}
|
|
|
|
function calculateAvgMealsPerDay(actions: Action[]): number {
|
|
let mealsPerDay = new Map<string, number>();
|
|
|
|
for (const action of actions) {
|
|
if (action.type === 'food') {
|
|
const actionDate = action.created.split('T')[0]; // Extract the date part
|
|
mealsPerDay.set(actionDate, (mealsPerDay.get(actionDate) || 0) + 1);
|
|
}
|
|
}
|
|
|
|
if (mealsPerDay.size === 0) {
|
|
return 0;
|
|
}
|
|
|
|
const totalMeals = Array.from(mealsPerDay.values()).reduce((total, count) => total + count, 0);
|
|
return totalMeals / mealsPerDay.size;
|
|
}
|
|
</script>
|
|
|
|
<section>
|
|
<h2>Stats</h2>
|
|
<ul>
|
|
<li>{stats.avgSleepPerNap} min / nap</li>
|
|
<li>{stats.avgNapsPerDay} naps / day</li>
|
|
<li>{stats.avgSleepPerDay} min of sleep / day</li>
|
|
<li>{stats.avgDiaperChanges} diapers / day</li>
|
|
<li>{stats.avgPoops} days between poops</li>
|
|
<li>{stats.avgEatingTimes} meals / day</li>
|
|
</ul>
|
|
</section>
|