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 { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
@@ -29,6 +29,7 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
const [calendarStartDate, setCalendarStartDate] = useState(startOfToday());
const [draggedTask, setDraggedTask] = useState<string | null>(null);
const [hoveredDate, setHoveredDate] = useState<Date | null>(null);
const [visibleDays, setVisibleDays] = useState(7);
const [completionModal, setCompletionModal] = useState<{ isOpen: boolean; task: Task | null }>({
isOpen: false,
task: null
@@ -41,8 +42,29 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
refetchOnWindowFocus: false,
});
// Get 7 days starting from today for calendar
const dates = Array.from({ length: 7 }, (_, i) => addDays(calendarStartDate, i));
// Calculate responsive visible days based on screen width
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) => {
if (!task.dueDate) return false;
@@ -159,9 +181,9 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
};
const navigateCalendar = (direction: 'prev' | 'next') => {
const newDate = addDays(calendarStartDate, direction === 'next' ? 7 : -7);
const newDate = addDays(calendarStartDate, direction === 'next' ? visibleDays : -visibleDays);
setCalendarStartDate(newDate);
console.log(`Navigating calendar to ${newDate.toLocaleDateString()}`);
console.log(`Navigating calendar to ${newDate.toLocaleDateString()}, showing ${visibleDays} days`);
};
const handleTaskComplete = (task: Task) => {
@@ -306,7 +328,7 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
<div className="flex items-center gap-2">
<Calendar className="w-4 h-4 text-primary" />
<h3 className="text-sm font-semibold" data-testid="text-calendar-title">
Next 7 Days
Next {visibleDays} Days
</h3>
</div>
@@ -331,8 +353,8 @@ export default function TasksWithCalendar({ tasks, onTaskUpdate, onTaskEdit, onS
</div>
</div>
{/* Full Width Calendar Grid - Responsive */}
<div className="grid grid-cols-4 sm:grid-cols-7 gap-2">
{/* Full Width Calendar Grid - Dynamic */}
<div className={`grid gap-2`} style={{ gridTemplateColumns: `repeat(${visibleDays}, minmax(0, 1fr))` }}>
{dates.map((date, index) => {
const dayTasks = getTasksForDate(date);
const isToday = isSameDay(date, new Date());