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/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../shared/constants/date_limits.dart';
|
||||
import '../../shared/models/menu.dart';
|
||||
import 'menu_provider.dart';
|
||||
|
||||
@@ -95,31 +96,48 @@ class _WeekNavBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
}
|
||||
|
||||
(int, int) _isoWeekOf(DateTime dt) {
|
||||
final thu = dt.add(Duration(days: 4 - (dt.weekday == 7 ? 0 : dt.weekday)));
|
||||
final jan1 = DateTime.utc(thu.year, 1, 1);
|
||||
final w = ((thu.difference(jan1).inDays) / 7).ceil();
|
||||
final int shift = dt.weekday == 7 ? -3 : 4 - dt.weekday;
|
||||
final thu = dt.add(Duration(days: shift));
|
||||
final jan1 = dt.isUtc
|
||||
? DateTime.utc(thu.year, 1, 1)
|
||||
: DateTime(thu.year, 1, 1);
|
||||
final w = (thu.difference(jan1).inDays ~/ 7) + 1;
|
||||
return (thu.year, w);
|
||||
}
|
||||
|
||||
String _currentWeekString(DateTime date) {
|
||||
final (y, w) = _isoWeekOf(date);
|
||||
return '$y-W${w.toString().padLeft(2, '0')}';
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final now = DateTime.now();
|
||||
final maxWeek = _currentWeekString(
|
||||
now.add(const Duration(days: kPlanningHorizonDays)));
|
||||
final minWeek = _currentWeekString(
|
||||
now.subtract(Duration(days: kMenuPastWeeks * 7)));
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.chevron_left),
|
||||
onPressed: () {
|
||||
ref.read(currentWeekProvider.notifier).state =
|
||||
_offsetWeek(week, -1);
|
||||
},
|
||||
onPressed: week.compareTo(minWeek) <= 0
|
||||
? null
|
||||
: () {
|
||||
ref.read(currentWeekProvider.notifier).state =
|
||||
_offsetWeek(week, -1);
|
||||
},
|
||||
),
|
||||
Text(_weekLabel(week), style: Theme.of(context).textTheme.bodyMedium),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.chevron_right),
|
||||
onPressed: () {
|
||||
ref.read(currentWeekProvider.notifier).state =
|
||||
_offsetWeek(week, 1);
|
||||
},
|
||||
onPressed: week.compareTo(maxWeek) >= 0
|
||||
? null
|
||||
: () {
|
||||
ref.read(currentWeekProvider.notifier).state =
|
||||
_offsetWeek(week, 1);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user