import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../services/database.dart'; import '../providers/app_state.dart'; import 'route_page.dart'; import 'settings_page.dart'; class RoutesPage extends StatefulWidget { const RoutesPage({super.key}); @override State createState() => _RoutesPageState(); } class _RoutesPageState extends State { final _db = DatabaseService(); List> _routes = []; bool _loading = true; String? _error; @override void initState() { super.initState(); _initDb(); } Future _initDb() async { try { await _db.database; await _loadRoutes(); } catch (e) { setState(() { _error = 'Failed to initialize database: $e'; _loading = false; }); } } Future _loadRoutes() async { try { final r = await _db.getRoutes(); setState(() { _routes = r; _loading = false; _error = null; }); } catch (e) { setState(() { _error = 'Failed to load routes: $e'; _loading = false; }); } } void _addRoute() { final ctrl = TextEditingController(); showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('New Route'), content: TextField( controller: ctrl, decoration: const InputDecoration(labelText: 'Route name', hintText: 'e.g., Morning Route'), autofocus: true, ), actions: [ TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Cancel')), ElevatedButton( onPressed: () async { if (ctrl.text.trim().isNotEmpty) { await _db.insertRoute(ctrl.text.trim()); await _loadRoutes(); } if (ctx.mounted) Navigator.pop(ctx); }, child: const Text('Create'), ), ], ), ); } Future _deleteRoute(int routeId, String routeName) async { final confirmed = await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Delete Route'), content: Text('Delete "$routeName" and all its stops?'), actions: [ TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')), TextButton( onPressed: () => Navigator.pop(ctx, true), style: TextButton.styleFrom(foregroundColor: Colors.red), child: const Text('Delete'), ), ], ), ); if (confirmed == true) { await _db.deleteRoute(routeId); await _loadRoutes(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('My Routes'), actions: [ IconButton( icon: const Icon(Icons.settings), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (_) => SettingsPage(appState: context.read()), ), ); }, ), ], ), body: _buildBody(), floatingActionButton: FloatingActionButton(onPressed: _addRoute, child: const Icon(Icons.add)), ); } Widget _buildBody() { if (_loading) { return const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Initializing database...'), ], ), ); } if (_error != null) { return Center( child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.error_outline, size: 48, color: Colors.red), const SizedBox(height: 16), Text(_error!, textAlign: TextAlign.center), const SizedBox(height: 16), ElevatedButton.icon( onPressed: () { setState(() => _loading = true); _initDb(); }, icon: const Icon(Icons.refresh), label: const Text('Retry'), ), ], ), ), ); } if (_routes.isEmpty) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.route, size: 64, color: Colors.grey), const SizedBox(height: 16), const Text('No routes yet', style: TextStyle(fontSize: 18, color: Colors.grey)), const SizedBox(height: 16), ElevatedButton.icon( onPressed: _addRoute, icon: const Icon(Icons.add), label: const Text('Create Route'), ), ], ), ); } return RefreshIndicator( onRefresh: _loadRoutes, child: ListView.builder( itemCount: _routes.length, itemBuilder: (ctx, i) { final route = _routes[i]; return Card( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), child: ListTile( leading: const CircleAvatar(child: Icon(Icons.route)), title: Text(route['name'] as String, style: const TextStyle(fontWeight: FontWeight.w600)), subtitle: Text( route['created_at'] != null ? _formatDate(route['created_at'] as String) : '', ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.delete_outline, color: Colors.red), onPressed: () => _deleteRoute(route['id'] as int, route['name'] as String), ), const Icon(Icons.chevron_right), ], ), onTap: () => Navigator.push( context, MaterialPageRoute( builder: (_) => RoutePage(routeId: route['id'] as int, name: route['name'] as String), ), ).then((_) => _loadRoutes()), ), ); }, ), ); } String _formatDate(String iso) { try { final dt = DateTime.parse(iso); return '${dt.day}/${dt.month}/${dt.year} ${dt.hour}:${dt.minute.toString().padLeft(2, '0')}'; } catch (_) { return iso; } } }