import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../core/theme.dart'; /// Seven-day selector. A dot under a day marks something booked or set. class WeekStrip extends StatelessWidget { const WeekStrip({ super.key, required this.days, required this.selected, required this.onSelect, this.marked = const {}, }); final List days; final DateTime selected; final ValueChanged onSelect; /// Day indices (0..6) that carry a marker dot. final Set marked; @override Widget build(BuildContext context) { final dow = DateFormat('EEE'); return Row( children: [ for (var i = 0; i < days.length; i++) ...[ if (i > 0) const SizedBox(width: 7), Expanded( child: _DayCell( day: days[i], label: dow.format(days[i]), selected: days[i].day == selected.day && days[i].month == selected.month, marked: marked.contains(i), onTap: () => onSelect(days[i]), ), ), ], ], ); } } class _DayCell extends StatelessWidget { const _DayCell({ required this.day, required this.label, required this.selected, required this.marked, required this.onTap, }); final DateTime day; final String label; final bool selected; final bool marked; final VoidCallback onTap; static const _duration = Duration(milliseconds: 260); static const _curve = Curves.easeOutCubic; @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, // Colour is animated rather than swapped so moving along the week reads // as one continuous selection rather than a series of flashes. child: AnimatedContainer( duration: _duration, curve: _curve, height: 64, decoration: BoxDecoration( color: selected ? KrowPalette.blue : Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: selected ? KrowPalette.blue : KrowPalette.line, ), boxShadow: selected ? [ BoxShadow( color: KrowPalette.blue.withValues(alpha: 0.26), blurRadius: 12, offset: const Offset(0, 4), ), ] : null, ), child: Stack( alignment: Alignment.center, children: [ Column( mainAxisAlignment: MainAxisAlignment.center, children: [ AnimatedDefaultTextStyle( duration: _duration, curve: _curve, style: TextStyle( fontSize: 9, fontWeight: FontWeight.w600, letterSpacing: 0.8, color: selected ? Colors.white70 : const Color(0xFF949FA5), ), child: Text(label.toUpperCase()), ), const SizedBox(height: 2), AnimatedDefaultTextStyle( duration: _duration, curve: _curve, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w700, color: selected ? Colors.white : KrowPalette.ink, ), child: Text('${day.day}'), ), ], ), Positioned( bottom: 8, child: AnimatedScale( scale: marked ? 1 : 0, duration: _duration, curve: Curves.easeOutBack, child: AnimatedContainer( duration: _duration, width: 5, height: 5, decoration: BoxDecoration( shape: BoxShape.circle, color: selected ? KrowPalette.yellow : KrowPalette.blue, ), ), ), ), ], ), ), ); } }