formatting fixes
Build and Push Docker Image / build-and-push (pull_request) Successful in 58s
Python Code Quality / python-code-quality (pull_request) Successful in 10s
Python Test / python-test (pull_request) Successful in 18s

This commit is contained in:
Brian Bjarke Jensen
2025-11-10 21:19:13 +01:00
parent cd3db4fb86
commit 6c3d301027
6 changed files with 268 additions and 169 deletions
+76 -56
View File
@@ -470,7 +470,8 @@
}
function onChildChange(event) {
selectedChildId = event.target.value === "all" ? null : parseInt(event.target.value);
selectedChildId =
event.target.value === "all" ? null : parseInt(event.target.value);
displayFeedings(allFeedings);
}
@@ -492,31 +493,34 @@
const durationChartData = prepareDurationChartData(feedings);
// Build child dropdown options
const childOptions = allChildren.map(child =>
`<option value="${child.id}" ${selectedChildId === child.id ? 'selected' : ''}>${child.name}</option>`
).join('');
const childOptions = allChildren
.map(
(child) =>
`<option value="${child.id}" ${selectedChildId === child.id ? "selected" : ""}>${child.name}</option>`,
)
.join("");
content.innerHTML = `
<div class="controls">
<label for="childFilter">Child:</label>
<select id="childFilter" onchange="onChildChange(event)">
<option value="all" ${selectedChildId === null ? 'selected' : ''}>All Children</option>
<option value="all" ${selectedChildId === null ? "selected" : ""}>All Children</option>
${childOptions}
</select>
<label for="daysRange">Time Range:</label>
<select id="daysRange" onchange="onDaysRangeChange(event)">
<option value="1" ${currentDaysRange === 1 ? 'selected' : ''}>Last 24 Hours</option>
<option value="3" ${currentDaysRange === 3 ? 'selected' : ''}>Last 3 Days</option>
<option value="7" ${currentDaysRange === 7 ? 'selected' : ''}>Last 7 Days</option>
<option value="14" ${currentDaysRange === 14 ? 'selected' : ''}>Last 14 Days</option>
<option value="30" ${currentDaysRange === 30 ? 'selected' : ''}>Last 30 Days</option>
<option value="90" ${currentDaysRange === 90 ? 'selected' : ''}>Last 90 Days</option>
<option value="1" ${currentDaysRange === 1 ? "selected" : ""}>Last 24 Hours</option>
<option value="3" ${currentDaysRange === 3 ? "selected" : ""}>Last 3 Days</option>
<option value="7" ${currentDaysRange === 7 ? "selected" : ""}>Last 7 Days</option>
<option value="14" ${currentDaysRange === 14 ? "selected" : ""}>Last 14 Days</option>
<option value="30" ${currentDaysRange === 30 ? "selected" : ""}>Last 30 Days</option>
<option value="90" ${currentDaysRange === 90 ? "selected" : ""}>Last 90 Days</option>
</select>
</div>
<div class="chart-container">
<h2>Feedings Per Day (Last ${currentDaysRange} Day${currentDaysRange !== 1 ? 's' : ''})</h2>
<h2>Feedings Per Day (Last ${currentDaysRange} Day${currentDaysRange !== 1 ? "s" : ""})</h2>
<div class="chart-wrapper">
<canvas id="feedingsChart"></canvas>
</div>
@@ -543,7 +547,7 @@
renderBarChart(barChartData);
renderPieChart(pieChartData);
renderDurationChart(durationChartData);
// Render feeding list
renderFeedingList(feedings);
}
@@ -563,7 +567,9 @@
// Filter by selected child if applicable
if (selectedChildId !== null) {
filteredFeedings = filteredFeedings.filter((f) => f.child_id === selectedChildId);
filteredFeedings = filteredFeedings.filter(
(f) => f.child_id === selectedChildId,
);
}
// Sort by most recent first
@@ -571,45 +577,49 @@
return new Date(b.start_time) - new Date(a.start_time);
});
const listHtml = filteredFeedings.map((feeding) => {
const startTime = new Date(feeding.start_time);
const endTime = feeding.end_time ? new Date(feeding.end_time) : null;
const dateStr = startTime.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
});
const timeStr = startTime.toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
});
const listHtml = filteredFeedings
.map((feeding) => {
const startTime = new Date(feeding.start_time);
const endTime = feeding.end_time
? new Date(feeding.end_time)
: null;
const duration = endTime
? Math.round((endTime - startTime) / 60000)
: null;
const dateStr = startTime.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
});
const typeClass = feeding.feeding_type.replace("_", "-");
const typeLabel = formatFeedingType(feeding.feeding_type);
const timeStr = startTime.toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
});
// Get child name
const child = allChildren.find(c => c.id === feeding.child_id);
const childName = child ? child.name : "Unknown";
const duration = endTime
? Math.round((endTime - startTime) / 60000)
: null;
return `
const typeClass = feeding.feeding_type.replace("_", "-");
const typeLabel = formatFeedingType(feeding.feeding_type);
// Get child name
const child = allChildren.find((c) => c.id === feeding.child_id);
const childName = child ? child.name : "Unknown";
return `
<div class="feeding-item">
<div class="feeding-info-left">
<div class="feeding-time">${dateStr} at ${timeStr}${selectedChildId === null ? ` - ${childName}` : ''}</div>
<div class="feeding-time">${dateStr} at ${timeStr}${selectedChildId === null ? ` - ${childName}` : ""}</div>
<div class="feeding-details">
<span class="feeding-type-badge ${typeClass}">${typeLabel}</span>
${duration !== null ? `${duration} minutes` : 'Ongoing'}
${duration !== null ? `${duration} minutes` : "Ongoing"}
</div>
</div>
<button class="edit-button" onclick="editFeeding(${feeding.id})">Edit</button>
</div>
`;
}).join("");
})
.join("");
const listContainer = `
<div class="feedings-list">
@@ -624,7 +634,7 @@
`;
const content = document.getElementById("content");
content.insertAdjacentHTML('beforeend', listContainer);
content.insertAdjacentHTML("beforeend", listContainer);
}
function formatFeedingType(type) {
@@ -660,7 +670,9 @@
// Filter by selected child if applicable
if (selectedChildId !== null) {
recentFeedings = recentFeedings.filter((f) => f.child_id === selectedChildId);
recentFeedings = recentFeedings.filter(
(f) => f.child_id === selectedChildId,
);
}
const typeCounts = {
@@ -708,7 +720,9 @@
// Filter by selected child if applicable
if (selectedChildId !== null) {
completedFeedings = completedFeedings.filter((f) => f.child_id === selectedChildId);
completedFeedings = completedFeedings.filter(
(f) => f.child_id === selectedChildId,
);
}
// Calculate durations in minutes
@@ -721,14 +735,14 @@
// Find max duration to determine how many bins we need
const maxDuration = Math.max(...durations, 0);
const maxBin = Math.ceil(maxDuration / 5) * 5; // Round up to nearest 5
// Create 5-minute duration buckets dynamically
const buckets = {};
for (let i = 0; i < maxBin; i += 5) {
const label = `${i}-${i + 5}`;
buckets[label] = 0;
}
// Add a final bucket for anything over the max
if (maxBin > 0) {
buckets[`${maxBin}+`] = 0;
@@ -738,7 +752,7 @@
durations.forEach((duration) => {
const binIndex = Math.floor(duration / 5) * 5;
const label = `${binIndex}-${binIndex + 5}`;
if (buckets[label] !== undefined) {
buckets[label]++;
} else {
@@ -760,7 +774,9 @@
// Filter by selected child if applicable
let filteredFeedings = feedings;
if (selectedChildId !== null) {
filteredFeedings = feedings.filter((f) => f.child_id === selectedChildId);
filteredFeedings = feedings.filter(
(f) => f.child_id === selectedChildId,
);
}
// Create days based on currentDaysRange (including today)
@@ -792,7 +808,7 @@
function renderBarChart(chartData) {
const ctx = document.getElementById("feedingsChart").getContext("2d");
new Chart(ctx, {
type: "bar",
data: {
@@ -870,7 +886,7 @@
function renderPieChart(chartData) {
const ctx = document.getElementById("pieChart").getContext("2d");
// Color mapping for each type
const colorMap = {
"Left Breast": {
@@ -881,7 +897,7 @@
background: "rgba(118, 75, 162, 0.8)",
border: "rgba(118, 75, 162, 1)",
},
"Bottle": {
Bottle: {
background: "rgba(255, 159, 64, 0.8)",
border: "rgba(255, 159, 64, 1)",
},
@@ -889,12 +905,12 @@
// Generate colors based on labels present
const backgroundColors = chartData.labels.map(
(label) => colorMap[label]?.background || "rgba(200, 200, 200, 0.8)"
(label) => colorMap[label]?.background || "rgba(200, 200, 200, 0.8)",
);
const borderColors = chartData.labels.map(
(label) => colorMap[label]?.border || "rgba(200, 200, 200, 1)"
(label) => colorMap[label]?.border || "rgba(200, 200, 200, 1)",
);
new Chart(ctx, {
type: "pie",
data: {
@@ -933,8 +949,12 @@
callbacks: {
label: function (context) {
const count = context.parsed;
const total = context.dataset.data.reduce((a, b) => a + b, 0);
const percentage = total > 0 ? ((count / total) * 100).toFixed(1) : 0;
const total = context.dataset.data.reduce(
(a, b) => a + b,
0,
);
const percentage =
total > 0 ? ((count / total) * 100).toFixed(1) : 0;
return `${context.label}: ${count} (${percentage}%)`;
},
},
@@ -946,7 +966,7 @@
function renderDurationChart(chartData) {
const ctx = document.getElementById("durationChart").getContext("2d");
new Chart(ctx, {
type: "bar",
data: {