forked from eatvio/eatvio_app
feat(insights): first isights impemetation
This commit is contained in:
130
lib/features/insights/presentation/widgets/intra_date_nav.dart
Normal file
130
lib/features/insights/presentation/widgets/intra_date_nav.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
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),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user