MotorSignal-App/lib/features/activity/activity_screen.dart

134 lines
4.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/theme/app_typography.dart';
import '../../core/theme/theme_extensions.dart';
import '../history/history_screen.dart';
import '../records/records_screen.dart';
enum ActivityTab { rides, records }
/// Canonical unified Activity screen for MotorSignal.
///
/// Houses chronological ride history and personal performance records
/// under a single top-level destination with segmented navigation,
/// preserving information architecture and full responsiveness.
class ActivityScreen extends ConsumerStatefulWidget {
final ActivityTab initialTab;
const ActivityScreen({
super.key,
this.initialTab = ActivityTab.rides,
});
@override
ConsumerState<ActivityScreen> createState() => _ActivityScreenState();
}
class _ActivityScreenState extends ConsumerState<ActivityScreen> {
late ActivityTab _currentTab;
@override
void initState() {
super.initState();
_currentTab = widget.initialTab;
}
@override
void didUpdateWidget(covariant ActivityScreen oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.initialTab != widget.initialTab) {
_currentTab = widget.initialTab;
}
}
@override
Widget build(BuildContext context) {
final colors = context.motorColors;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
appBar: AppBar(
title: Text(
_currentTab == ActivityTab.rides ? 'Ride History' : 'Personal Records',
style: const TextStyle(fontWeight: FontWeight.w700),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(48),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
child: SizedBox(
width: double.infinity,
height: 36,
child: SegmentedButton<ActivityTab>(
segments: const [
ButtonSegment<ActivityTab>(
value: ActivityTab.rides,
icon: Icon(Icons.history, size: 16),
label: Text(
'Rides',
style: TextStyle(
fontFamily: AppTypography.fontHeadline,
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
ButtonSegment<ActivityTab>(
value: ActivityTab.records,
icon: Icon(Icons.emoji_events_outlined, size: 16),
label: Text(
'Records',
style: TextStyle(
fontFamily: AppTypography.fontHeadline,
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
],
selected: {_currentTab},
onSelectionChanged: (selection) {
if (selection.isNotEmpty) {
setState(() {
_currentTab = selection.first;
});
}
},
style: ButtonStyle(
visualDensity: VisualDensity.compact,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
side: WidgetStateProperty.all(
BorderSide(
color: colors.outlineVariant,
width: 0.8,
),
),
backgroundColor: WidgetStateProperty.resolveWith<Color?>((states) {
if (states.contains(WidgetState.selected)) {
return colors.cyberCyan.withValues(alpha: isDark ? 0.16 : 0.12);
}
return isDark ? colors.surfaceContainer : Colors.transparent;
}),
foregroundColor: WidgetStateProperty.resolveWith<Color?>((states) {
if (states.contains(WidgetState.selected)) {
return colors.cyberCyan;
}
return isDark ? Colors.white70 : Colors.black87;
}),
),
),
),
),
),
),
body: IndexedStack(
index: _currentTab == ActivityTab.rides ? 0 : 1,
children: const [
HistoryScreen(isEmbedded: true),
RecordsScreen(isEmbedded: true),
],
),
);
}
}