Co-authored-by: Azareth-Tr <Azareth-Tr@users.noreply.github.com> Co-authored-by: eddgranados12 <eddgranados12@users.noreply.github.com> vistas de mockup actualizaco
144 lines
4.5 KiB
Dart
144 lines
4.5 KiB
Dart
// lib/app.dart
|
|
// Root de la app: go_router + bottom navigation de 4 tabs (P3).
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'features/eta/eta_screen.dart';
|
|
import 'features/notifications/notifications_screen.dart';
|
|
import 'features/feedback/feedback_screen.dart';
|
|
import 'features/quiz/quiz_screen.dart';
|
|
|
|
// ──────────────────────────────────────────
|
|
// Router
|
|
// ──────────────────────────────────────────
|
|
final _router = GoRouter(
|
|
initialLocation: '/eta',
|
|
routes: [
|
|
ShellRoute(
|
|
builder: (context, state, child) => _ScaffoldWithNav(child: child),
|
|
routes: [
|
|
GoRoute(
|
|
path: '/eta',
|
|
pageBuilder: (context, state) => const NoTransitionPage(
|
|
child: EtaScreen(),
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/notifications',
|
|
pageBuilder: (context, state) => const NoTransitionPage(
|
|
child: NotificationsScreen(),
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/feedback',
|
|
pageBuilder: (context, state) => const NoTransitionPage(
|
|
child: FeedbackScreen(),
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/quiz',
|
|
pageBuilder: (context, state) => const NoTransitionPage(
|
|
child: QuizScreen(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
|
|
// ──────────────────────────────────────────
|
|
// App widget
|
|
// ──────────────────────────────────────────
|
|
class RecolectaApp extends StatelessWidget {
|
|
const RecolectaApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp.router(
|
|
title: 'Recolecta',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: _buildTheme(Brightness.light),
|
|
darkTheme: _buildTheme(Brightness.dark),
|
|
themeMode: ThemeMode.system,
|
|
routerConfig: _router,
|
|
);
|
|
}
|
|
|
|
ThemeData _buildTheme(Brightness brightness) {
|
|
final isDark = brightness == Brightness.dark;
|
|
return ThemeData(
|
|
colorScheme: ColorScheme.fromSeed(
|
|
seedColor: const Color(0xFF1D9E75), // teal-400
|
|
brightness: brightness,
|
|
),
|
|
useMaterial3: true,
|
|
appBarTheme: AppBarTheme(
|
|
backgroundColor:
|
|
isDark ? const Color(0xFF1A1A1A) : Colors.white,
|
|
foregroundColor: isDark ? Colors.white : Colors.black87,
|
|
elevation: 0,
|
|
scrolledUnderElevation: 1,
|
|
titleTextStyle: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.white : Colors.black87,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// ──────────────────────────────────────────
|
|
// Bottom navigation shell
|
|
// ──────────────────────────────────────────
|
|
class _ScaffoldWithNav extends StatelessWidget {
|
|
final Widget child;
|
|
const _ScaffoldWithNav({required this.child});
|
|
|
|
static const _tabs = [
|
|
_TabItem(path: '/eta', icon: Icons.schedule_rounded, label: 'ETA'),
|
|
_TabItem(
|
|
path: '/notifications',
|
|
icon: Icons.notifications_outlined,
|
|
label: 'Avisos'),
|
|
_TabItem(
|
|
path: '/feedback',
|
|
icon: Icons.feedback_outlined,
|
|
label: 'Buzón'),
|
|
_TabItem(
|
|
path: '/quiz', icon: Icons.quiz_outlined, label: 'Quiz'),
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final location = GoRouterState.of(context).uri.path;
|
|
final currentIndex =
|
|
_tabs.indexWhere((t) => location.startsWith(t.path));
|
|
|
|
return Scaffold(
|
|
body: child,
|
|
bottomNavigationBar: NavigationBar(
|
|
selectedIndex: currentIndex < 0 ? 0 : currentIndex,
|
|
onDestinationSelected: (i) => context.go(_tabs[i].path),
|
|
destinations: _tabs
|
|
.map(
|
|
(t) => NavigationDestination(
|
|
icon: Icon(t.icon),
|
|
label: t.label,
|
|
),
|
|
)
|
|
.toList(),
|
|
height: 64,
|
|
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TabItem {
|
|
final String path;
|
|
final IconData icon;
|
|
final String label;
|
|
const _TabItem(
|
|
{required this.path, required this.icon, required this.label});
|
|
} |