2 Commits

Author SHA1 Message Date
bb64bacd1e Update the minigrid responsiveness and visibility 2025-10-13 18:54:06 +02:00
7b513bca28 bug fixes 2025-10-13 18:44:46 +02:00
2 changed files with 45 additions and 27 deletions

View File

@@ -1,4 +1,4 @@
import React, { useMemo } from 'react'; import React, { useMemo, useEffect } from 'react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { getColorIntensity, isToday, formatDate, getWeekdayLabel } from '../lib/utils-habit'; import { getColorIntensity, isToday, formatDate, getWeekdayLabel } from '../lib/utils-habit';
import { toggleCompletion } from '../lib/storage'; import { toggleCompletion } from '../lib/storage';
@@ -29,29 +29,37 @@ const HabitGrid = ({ habit, onUpdate, fullView = false }) => {
return weeksArray; return weeksArray;
}, [fullView]); }, [fullView]);
useEffect(() => {
// Scroll to the rightmost (most recent) week on mount
const gridScroll = document.querySelector('.grid-scroll');
if (gridScroll) {
gridScroll.scrollLeft = gridScroll.scrollWidth;
}
}, []);
const handleCellClick = (date) => { const handleCellClick = (date) => {
toggleCompletion(habit.id, formatDate(date)); toggleCompletion(habit.id, formatDate(date));
onUpdate(); onUpdate();
}; };
return ( return (
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-sm border border-slate-200 dark:border-slate-700"> <div className="bg-white dark:bg-slate-800 rounded-2xl p-4 pt-0 shadow-sm border border-slate-200 dark:border-slate-700">
<div className="mb-4"> <div className="mb-2">
<h2 className="text-lg font-semibold mb-1">Activity Calendar</h2> <h2 className="text-lg font-semibold mb-1">Activity Calendar</h2>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
Tap any day to mark it as complete Tap any day to mark it as complete
</p> </p>
</div> </div>
<div className="overflow-x-auto grid-scroll"> <div className="overflow-x-auto grid-scroll mt-2">
<div className="inline-flex gap-1"> <div className="inline-flex gap-1 mb-4">
{/* Weekday labels: Monday (top) to Sunday (bottom) */} {/* Weekday labels: Monday (top) to Sunday (bottom) */}
<div className="flex flex-col gap-1 mr-2"> <div className="flex flex-col gap-1 mr-2">
<div className="h-3" /> <div className="h-1" />
{[1, 2, 3, 4, 5, 6, 0].map((day) => ( {[1, 2, 3, 4, 5, 6, 0].map((day) => (
<div <div
key={day} key={day}
className="h-3 flex items-center justify-end text-xs text-muted-foreground pr-1" className="h-3 flex items-center justify-end text-xs text-muted-foreground pr-0"
> >
{getWeekdayLabel(day)} {getWeekdayLabel(day)}
</div> </div>

View File

@@ -7,8 +7,15 @@ const MiniGrid = ({ habit, onUpdate }) => {
const today = new Date(); const today = new Date();
// Show fewer days on mobile for better aspect ratio // Show fewer days on mobile for better aspect ratio
const isMobile = window.innerWidth < 640; // Tailwind 'sm' breakpoint const isMobile = window.innerWidth < 640; // Tailwind 'sm' breakpoint
const numDays = isMobile ? 14 : 28; const numDays = isMobile ? 11 : 28;
const days = []; const days = [];
const scrollRef = React.useRef(null);
React.useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollLeft = scrollRef.current.scrollWidth;
}
}, [numDays, habit.completions]);
for (let i = numDays - 1; i >= 0; i--) { for (let i = numDays - 1; i >= 0; i--) {
const date = new Date(today); const date = new Date(today);
@@ -23,31 +30,34 @@ const MiniGrid = ({ habit, onUpdate }) => {
}; };
return ( return (
<div className="flex gap-1 overflow-x-auto grid-scroll pb-2"> <div ref={scrollRef} className="flex gap-1 overflow-x-auto grid-scroll pb-2">
{days.map((date, index) => { {days.map((date, index) => {
const dateStr = formatDate(date); const dateStr = formatDate(date);
const isCompleted = habit.completions.includes(dateStr); const isCompleted = habit.completions.includes(dateStr);
const intensity = isCompleted ? getColorIntensity(habit.completions, dateStr) : 0; const intensity = isCompleted ? getColorIntensity(habit.completions, dateStr) : 0;
const isTodayCell = isToday(date); const isTodayCell = isToday(date);
const dayLetter = date.toLocaleDateString('en-US', { weekday: 'short' })[0];
return ( return (
<motion.button <div key={index} className="flex flex-col items-center">
key={index} <motion.button
whileHover={{ scale: 0.9 }} whileHover={{ scale: 0.9 }}
whileTap={{ scale: 0.5 }} whileTap={{ scale: 0.5 }}
onClick={(e) => handleCellClick(e, date)} onClick={(e) => handleCellClick(e, date)}
className="habit-cell flex w-8 h-8 rounded-2xl transition-all" className={`habit-cell flex w-8 h-8 transition-all ${isTodayCell ? 'rounded-md' : 'rounded-2xl'}`}
style={{ style={{
backgroundColor: isCompleted backgroundColor: isCompleted
? habit.color ? habit.color
: 'transparent', : 'transparent',
opacity: isCompleted ? 0.3 + (intensity * 0.7) : 1, opacity: isCompleted ? 0.3 + (intensity * 0.7) : 1,
border: isTodayCell border: isTodayCell
? `2px solid ${habit.color}` ? `2px solid ${habit.color}`
: `1px solid ${habit.color}20`, : `1px solid ${habit.color}20`,
}} }}
title={dateStr} title={dateStr}
/> />
<span className="text-[10px] text-muted-foreground mt-1">{dayLetter}</span>
</div>
); );
})} })}
</div> </div>