{habits.map((habit) => {
// Use lift() - just call with reactive args in an object
const isCompletedToday = checkCompleted({
logs,
name: habit.name,
date: todayDate,
});
const streak = calcStreak({ logs, name: habit.name });
return (
{habit.icon}
{habit.name || "(unnamed)"}
Streak: {streak} days
{
const habitName = habit.name;
const currentLogs = logs.get();
const existingIdx = currentLogs.findIndex(
(log) =>
log.habitName === habitName &&
log.date === todayDate,
);
if (existingIdx >= 0) {
// Toggle existing
const updated = currentLogs.map((log, i) =>
i === existingIdx
? { ...log, completed: !log.completed }
: log
);
logs.set(updated);
} else {
// Create new
logs.push({
habitName,
date: todayDate,
completed: true,
});
}
}}
>
{ifElse(isCompletedToday, "✓", "○")}
{
const current = habits.get();
const idx = current.findIndex((h) =>
Cell.equals(habit, h)
);
if (idx >= 0) {
habits.set(current.toSpliced(idx, 1));
}
}}
>
×
{/* Last 7 days indicator */}
{[6, 5, 4, 3, 2, 1, 0].map((daysAgo) => {
const dateStr = getDateDaysAgo(daysAgo);
const wasCompleted = checkCompleted({
logs,
name: habit.name,
date: dateStr,
});
return (
{dateStr.slice(-2)}
);
})}
);
})}
{ifElse(
computed(() => habits.get().length === 0),
No habits yet. Add one below!
,
null,
)}