added recent activity cards to home page
This commit is contained in:
@@ -167,6 +167,52 @@
|
|||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
.recent-activity {
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.recent-activity h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #333;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
.activity-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.activity-card {
|
||||||
|
background: white;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.activity-card .icon {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.activity-card .type {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.activity-card .time {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.activity-card .details {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #888;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
.activity-card.empty {
|
||||||
|
opacity: 0.5;
|
||||||
|
font-style: italic;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -321,6 +367,7 @@
|
|||||||
let activeSleep = null;
|
let activeSleep = null;
|
||||||
let lastSleep = null;
|
let lastSleep = null;
|
||||||
let sleepUpdateTimerInterval = null;
|
let sleepUpdateTimerInterval = null;
|
||||||
|
let lastDiaperChange = null;
|
||||||
|
|
||||||
async function loadFeedingStatus(children) {
|
async function loadFeedingStatus(children) {
|
||||||
userChildren = children;
|
userChildren = children;
|
||||||
@@ -376,6 +423,20 @@
|
|||||||
lastSleep = sleeps[0];
|
lastSleep = sleeps[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch all diaper changes to get the last one
|
||||||
|
const diaperResponse = await fetch("/api/diaper-changes", {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (diaperResponse.ok) {
|
||||||
|
const diapers = await diaperResponse.json();
|
||||||
|
if (diapers.length > 0) {
|
||||||
|
lastDiaperChange = diapers[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading feeding status:", error);
|
console.error("Error loading feeding status:", error);
|
||||||
}
|
}
|
||||||
@@ -478,9 +539,98 @@
|
|||||||
</button>
|
</button>
|
||||||
${feedingButtonHtml}
|
${feedingButtonHtml}
|
||||||
${sleepButtonHtml}
|
${sleepButtonHtml}
|
||||||
|
${buildRecentActivitySection()}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildRecentActivitySection() {
|
||||||
|
// Build diaper card
|
||||||
|
const diaperCard = lastDiaperChange
|
||||||
|
? `
|
||||||
|
<div class="activity-card">
|
||||||
|
<div class="icon">🧷</div>
|
||||||
|
<div class="type">Last Diaper</div>
|
||||||
|
<div class="time">${formatTime(lastDiaperChange.change_time)}</div>
|
||||||
|
<div class="details">
|
||||||
|
${lastDiaperChange.poop_amount ? `💩 ${lastDiaperChange.poop_amount}` : ""}
|
||||||
|
${lastDiaperChange.poop_amount && lastDiaperChange.pee_amount ? " • " : ""}
|
||||||
|
${lastDiaperChange.pee_amount ? `💧 ${lastDiaperChange.pee_amount}` : ""}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: `
|
||||||
|
<div class="activity-card empty">
|
||||||
|
<div class="icon">🧷</div>
|
||||||
|
<div class="type">No diaper changes yet</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Build feeding card
|
||||||
|
const feedingCard = lastFeeding
|
||||||
|
? `
|
||||||
|
<div class="activity-card">
|
||||||
|
<div class="icon">🍼</div>
|
||||||
|
<div class="type">Last Feeding</div>
|
||||||
|
<div class="time">${formatTime(lastFeeding.start_time)}</div>
|
||||||
|
<div class="details">
|
||||||
|
${formatFeedingType(lastFeeding.feeding_type)}
|
||||||
|
${lastFeeding.end_time ? ` • ${calculateDuration(lastFeeding.start_time, lastFeeding.end_time)}` : " (ongoing)"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: `
|
||||||
|
<div class="activity-card empty">
|
||||||
|
<div class="icon">🍼</div>
|
||||||
|
<div class="type">No feedings yet</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Build sleep card
|
||||||
|
const sleepCard = lastSleep
|
||||||
|
? `
|
||||||
|
<div class="activity-card">
|
||||||
|
<div class="icon">😴</div>
|
||||||
|
<div class="type">Last Sleep</div>
|
||||||
|
<div class="time">${formatTime(lastSleep.start_time)}</div>
|
||||||
|
<div class="details">
|
||||||
|
${lastSleep.end_time ? calculateDuration(lastSleep.start_time, lastSleep.end_time) : "ongoing"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: `
|
||||||
|
<div class="activity-card empty">
|
||||||
|
<div class="icon">😴</div>
|
||||||
|
<div class="type">No sleep sessions yet</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="recent-activity">
|
||||||
|
<h3>📊 Recent Activity</h3>
|
||||||
|
<div class="activity-grid">
|
||||||
|
${diaperCard}
|
||||||
|
${feedingCard}
|
||||||
|
${sleepCard}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateDuration(startTime, endTime) {
|
||||||
|
const start = new Date(startTime);
|
||||||
|
const end = new Date(endTime);
|
||||||
|
const diffMs = end - start;
|
||||||
|
const diffMins = Math.floor(diffMs / 60000);
|
||||||
|
|
||||||
|
if (diffMins < 60) {
|
||||||
|
return `${diffMins} min`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hours = Math.floor(diffMins / 60);
|
||||||
|
const mins = diffMins % 60;
|
||||||
|
return `${hours}h ${mins}m`;
|
||||||
|
}
|
||||||
|
|
||||||
function formatFeedingType(type) {
|
function formatFeedingType(type) {
|
||||||
const types = {
|
const types = {
|
||||||
left_breast: "Left Breast",
|
left_breast: "Left Breast",
|
||||||
|
|||||||
Reference in New Issue
Block a user