forked from eatvio/eatvio_app
131 lines
4.1 KiB
Dart
131 lines
4.1 KiB
Dart
import 'package:eatvio_app/features/insights/models/insights_payload_model.dart';
|
||
import 'package:eatvio_app/features/insights/presentation/widgets/insights_colors.dart';
|
||
import 'package:eatvio_app/generated/l10n.dart';
|
||
import 'package:flutter/material.dart';
|
||
|
||
/// Навигация по дням для вкладки «В течение дня»: `‹ дата ›` и выбор даты.
|
||
///
|
||
/// Колбэки `null` — навигация неактивна (данные других дней ещё не подключены).
|
||
class IntraDateNav extends StatelessWidget {
|
||
const IntraDateNav({
|
||
super.key,
|
||
required this.model,
|
||
this.onPreviousDay,
|
||
this.onNextDay,
|
||
this.onDatePicked,
|
||
});
|
||
|
||
final IntraChartModel model;
|
||
final VoidCallback? onPreviousDay;
|
||
final VoidCallback? onNextDay;
|
||
final ValueChanged<DateTime>? onDatePicked;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final s = S.of(context);
|
||
final canGoNext = !model.isToday && onNextDay != null;
|
||
|
||
return Container(
|
||
padding: const EdgeInsets.all(4),
|
||
decoration: BoxDecoration(
|
||
color: InsightsColors.accentBackground,
|
||
borderRadius: BorderRadius.circular(999),
|
||
),
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
_NavButton(
|
||
key: const Key('insights_intra_prev'),
|
||
icon: Icons.chevron_left_rounded,
|
||
tooltip: s.insights_prev_day,
|
||
onPressed: onPreviousDay,
|
||
),
|
||
InkWell(
|
||
key: const Key('insights_intra_pick'),
|
||
borderRadius: BorderRadius.circular(999),
|
||
onTap: onDatePicked == null ? null : () => _pickDate(context),
|
||
child: Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||
child: ConstrainedBox(
|
||
constraints: const BoxConstraints(minWidth: 72),
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
const Icon(
|
||
Icons.calendar_today_rounded,
|
||
size: 14,
|
||
color: InsightsColors.blue,
|
||
),
|
||
const SizedBox(width: 6),
|
||
Text(
|
||
model.dateLabel,
|
||
key: const Key('insights_intra_date_label'),
|
||
style: const TextStyle(
|
||
fontSize: 13.5,
|
||
fontWeight: FontWeight.w700,
|
||
color: InsightsColors.title,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
_NavButton(
|
||
key: const Key('insights_intra_next'),
|
||
icon: Icons.chevron_right_rounded,
|
||
tooltip: s.insights_next_day,
|
||
onPressed: canGoNext ? onNextDay : null,
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Future<void> _pickDate(BuildContext context) async {
|
||
final lastDate = DateTime.tryParse(model.maxDate) ?? DateTime.now();
|
||
final current = DateTime.tryParse(model.date) ?? lastDate;
|
||
final picked = await showDatePicker(
|
||
context: context,
|
||
initialDate: current.isAfter(lastDate) ? lastDate : current,
|
||
firstDate: DateTime(2000),
|
||
lastDate: lastDate,
|
||
helpText: S.of(context).insights_pick_date,
|
||
);
|
||
if (picked != null) {
|
||
onDatePicked?.call(picked);
|
||
}
|
||
}
|
||
}
|
||
|
||
class _NavButton extends StatelessWidget {
|
||
const _NavButton({
|
||
super.key,
|
||
required this.icon,
|
||
required this.tooltip,
|
||
required this.onPressed,
|
||
});
|
||
|
||
final IconData icon;
|
||
final String tooltip;
|
||
final VoidCallback? onPressed;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Opacity(
|
||
opacity: onPressed == null ? 0.35 : 1,
|
||
child: SizedBox(
|
||
width: 36,
|
||
height: 36,
|
||
child: IconButton(
|
||
padding: EdgeInsets.zero,
|
||
tooltip: tooltip,
|
||
onPressed: onPressed,
|
||
icon: Icon(icon, color: InsightsColors.blue),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|