Make calendar display dynamically adjust to screen size for better mobile usability

Update the calendar component to use a `useEffect` hook for calculating and setting the number of visible days based on window width. This ensures the calendar grid adapts responsively, addressing issues with day card size and text readability on mobile devices. The navigation and title display are also updated to reflect the dynamic number of visible days.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/7CG7dga
This commit is contained in:
paul-nothaft
2025-09-12 12:49:43 +00:00
parent e98ffb4479
commit f687dc5a33
+30 -8
View File
@@ -1,4 +1,4 @@
import { useState } from 'react'; import { useState, useEffect } from 'react';
import { Card } from '@/components/ui/card'; import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
@@ -29,6 +29,7 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
const [calendarStartDate, setCalendarStartDate] = useState(startOfToday()); const [calendarStartDate, setCalendarStartDate] = useState(startOfToday());
const [draggedTask, setDraggedTask] = useState<string | null>(null); const [draggedTask, setDraggedTask] = useState<string | null>(null);
const [hoveredDate, setHoveredDate] = useState<Date | null>(null); const [hoveredDate, setHoveredDate] = useState<Date | null>(null);
const [visibleDays, setVisibleDays] = useState(7);
const [completionModal, setCompletionModal] = useState<{ isOpen: boolean; task: Task | null }>({ const [completionModal, setCompletionModal] = useState<{ isOpen: boolean; task: Task | null }>({
isOpen: false, isOpen: false,
task: null task: null
@@ -41,8 +42,29 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
}); });
// Get 7 days starting from today for calendar // Calculate responsive visible days based on screen width
const dates = Array.from({ length: 7 }, (_, i) => addDays(calendarStartDate, i)); useEffect(() => {
const calculateVisibleDays = () => {
const screenWidth = window.innerWidth;
// Subtract margins and padding (approximately 32px total)
const availableWidth = screenWidth - 32;
// Minimum width per day card (including gaps): ~120px
const minDayWidth = 120;
const maxDays = Math.floor(availableWidth / minDayWidth);
// Clamp between 2 and 7 days
const calculated = Math.max(2, Math.min(7, maxDays));
setVisibleDays(calculated);
};
calculateVisibleDays();
window.addEventListener('resize', calculateVisibleDays);
return () => window.removeEventListener('resize', calculateVisibleDays);
}, []);
// Get dynamic number of days starting from calendar start date
const dates = Array.from({ length: visibleDays }, (_, i) => addDays(calendarStartDate, i));
const isOverdue = (task: Task) => { const isOverdue = (task: Task) => {
if (!task.dueDate) return false; if (!task.dueDate) return false;
@@ -159,9 +181,9 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
}; };
const navigateCalendar = (direction: 'prev' | 'next') => { const navigateCalendar = (direction: 'prev' | 'next') => {
const newDate = addDays(calendarStartDate, direction === 'next' ? 7 : -7); const newDate = addDays(calendarStartDate, direction === 'next' ? visibleDays : -visibleDays);
setCalendarStartDate(newDate); setCalendarStartDate(newDate);
console.log(`Navigating calendar to ${newDate.toLocaleDateString()}`); console.log(`Navigating calendar to ${newDate.toLocaleDateString()}, showing ${visibleDays} days`);
}; };
const handleTaskComplete = (task: Task) => { const handleTaskComplete = (task: Task) => {
@@ -306,7 +328,7 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Calendar className="w-4 h-4 text-primary" /> <Calendar className="w-4 h-4 text-primary" />
<h3 className="text-sm font-semibold" data-testid="text-calendar-title"> <h3 className="text-sm font-semibold" data-testid="text-calendar-title">
Next 7 Days Next {visibleDays} Days
</h3> </h3>
</div> </div>
@@ -331,8 +353,8 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
</div> </div>
</div> </div>
{/* Full Width Calendar Grid - Responsive */} {/* Full Width Calendar Grid - Dynamic */}
<div className="grid grid-cols-4 sm:grid-cols-7 gap-2"> <div className={`grid gap-2`} style={{ gridTemplateColumns: `repeat(${visibleDays}, minmax(0, 1fr))` }}>
{dates.map((date, index) => { {dates.map((date, index) => {
const dayTasks = getTasksForDate(date); const dayTasks = getTasksForDate(date);
const isToday = isSameDay(date, new Date()); const isToday = isSameDay(date, new Date());