fix: unify date limits, fix ISO week calculation, refactor home screen plan button
- Fix _isoWeek: correct Sunday shift (-3 instead of +4), use floor+1 formula, match jan1 timezone to input — planned meals now appear correctly for UTC+ users - Add kPlanningHorizonDays=28 / kMenuPastWeeks=8 constants; apply to home date strip, plan picker (strip + calendar), and menu screen prev/next navigation - Menu screen week nav: disable arrows at min/max limits using compareTo - Home screen: replace _GenerateActionCard/_WeekPlannedChip conditional with always-visible _FutureDayPlanButton(dateString); show _DayPlannedChip only when the specific day has planned meals; remove standalone _PlanMenuButton - _FutureDayPlanButton uses selected date as defaultStart instead of lastPlanned+1 - Rename weekPlannedLabel -> dayPlannedLabel across all 12 locales Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:food_ai/l10n/app_localizations.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../shared/constants/date_limits.dart';
|
||||
import '../../shared/models/meal_type.dart';
|
||||
import '../profile/profile_provider.dart';
|
||||
import 'menu_provider.dart';
|
||||
@@ -279,8 +280,8 @@ class _DateStripSelector extends StatefulWidget {
|
||||
|
||||
class _DateStripSelectorState extends State<_DateStripSelector> {
|
||||
late final ScrollController _scrollController;
|
||||
// Show 30 upcoming days (today excluded, starts tomorrow).
|
||||
static const _futureDays = 30;
|
||||
// Show upcoming days up to the planning horizon (today excluded, starts tomorrow).
|
||||
static const _futureDays = kPlanningHorizonDays;
|
||||
static const _itemWidth = 64.0;
|
||||
|
||||
DateTime get _tomorrow =>
|
||||
@@ -407,12 +408,22 @@ class _CalendarRangePickerState extends State<_CalendarRangePicker> {
|
||||
}
|
||||
|
||||
void _nextMonth() {
|
||||
final horizon = DateTime.now().add(const Duration(days: kPlanningHorizonDays));
|
||||
final limitMonth = DateTime(horizon.year, horizon.month);
|
||||
if (!DateTime(_displayMonth.year, _displayMonth.month).isBefore(limitMonth)) return;
|
||||
setState(() {
|
||||
_displayMonth =
|
||||
DateTime(_displayMonth.year, _displayMonth.month + 1);
|
||||
});
|
||||
}
|
||||
|
||||
bool _isBeyondHorizon(DateTime date) {
|
||||
final today = DateTime.now();
|
||||
final horizon = DateTime(today.year, today.month, today.day)
|
||||
.add(const Duration(days: kPlanningHorizonDays));
|
||||
return date.isAfter(horizon);
|
||||
}
|
||||
|
||||
bool _isInRange(DateTime date) {
|
||||
final dayOnly = DateTime(date.year, date.month, date.day);
|
||||
final start =
|
||||
@@ -510,11 +521,13 @@ class _CalendarRangePickerState extends State<_CalendarRangePicker> {
|
||||
final isStart = _isRangeStart(date);
|
||||
final isEnd = _isRangeEnd(date);
|
||||
final isPast = _isPast(date);
|
||||
final isBeyond = _isBeyondHorizon(date);
|
||||
final isDisabled = isPast || isBeyond;
|
||||
|
||||
Color bgColor = Colors.transparent;
|
||||
Color textColor = theme.colorScheme.onSurface;
|
||||
|
||||
if (isPast) {
|
||||
if (isDisabled) {
|
||||
// ignore: deprecated_member_use
|
||||
textColor = theme.colorScheme.onSurface.withOpacity(0.3);
|
||||
} else if (isStart || isEnd) {
|
||||
@@ -526,7 +539,7 @@ class _CalendarRangePickerState extends State<_CalendarRangePicker> {
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: isPast ? null : () => widget.onDayTapped(date),
|
||||
onTap: isDisabled ? null : () => widget.onDayTapped(date),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
|
||||
Reference in New Issue
Block a user