Initial commit: SIBU 2.0 MISSION
This commit is contained in:
265
old/lib/presentation/taxi_screen/taxi_screen.dart
Normal file
265
old/lib/presentation/taxi_screen/taxi_screen.dart
Normal file
@ -0,0 +1,265 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../models/taxi_model.dart';
|
||||
import '../../services/taxi_service.dart';
|
||||
import '../../widgets/custom_app_bar.dart';
|
||||
import '../../widgets/custom_bottom_bar.dart';
|
||||
import './widgets/taxi_card_widget.dart';
|
||||
import './widgets/taxi_empty_state_widget.dart';
|
||||
import './widgets/taxi_filters_widget.dart';
|
||||
|
||||
/// Main taxi screen with filtering, search, and favorites functionality
|
||||
class TaxiScreen extends StatefulWidget {
|
||||
const TaxiScreen({super.key});
|
||||
|
||||
@override
|
||||
State<TaxiScreen> createState() => _TaxiScreenState();
|
||||
}
|
||||
|
||||
class _TaxiScreenState extends State<TaxiScreen> {
|
||||
final TaxiService _taxiService = TaxiService.instance;
|
||||
Timer? _searchDebouncer;
|
||||
|
||||
// State variables
|
||||
List<String> _corregimientos = [];
|
||||
List<String> _shifts = [];
|
||||
List<TaxiModel> _taxis = [];
|
||||
Set<String> _favoriteTaxiIds = {};
|
||||
String? _selectedCorregimiento;
|
||||
String? _selectedShift;
|
||||
String _searchText = '';
|
||||
bool _isLoading = true;
|
||||
String? _error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadInitialData();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_searchDebouncer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// Load corregimientos, shifts and initial taxi data
|
||||
Future<void> _loadInitialData() async {
|
||||
try {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
});
|
||||
|
||||
// Load corregimientos, shifts and favorites
|
||||
final results = await Future.wait([
|
||||
_taxiService.getCorregimientos(),
|
||||
_taxiService.getFavoriteTaxiIds(),
|
||||
]);
|
||||
|
||||
final corregimientos = results[0];
|
||||
final favoriteIds = results[1];
|
||||
|
||||
setState(() {
|
||||
_corregimientos = corregimientos;
|
||||
_shifts = _taxiService.getShifts();
|
||||
_favoriteTaxiIds = favoriteIds.toSet();
|
||||
_isLoading = false;
|
||||
});
|
||||
|
||||
// Load taxis for all corregimientos initially
|
||||
await _searchTaxis();
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
_error = e.toString();
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Search taxis with current filters
|
||||
Future<void> _searchTaxis() async {
|
||||
try {
|
||||
final taxis = await _taxiService.searchTaxis(
|
||||
selectedCorregimiento: _selectedCorregimiento,
|
||||
selectedShift: _selectedShift,
|
||||
searchText: _searchText.isEmpty ? null : _searchText,
|
||||
);
|
||||
|
||||
setState(() {
|
||||
_taxis = taxis;
|
||||
_error = null;
|
||||
});
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
_error = e.toString();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle corregimiento selection change
|
||||
void _onCorregimientoChanged(String? corregimiento) {
|
||||
setState(() {
|
||||
_selectedCorregimiento = corregimiento;
|
||||
});
|
||||
_searchTaxis();
|
||||
}
|
||||
|
||||
/// Handle shift selection change
|
||||
void _onShiftChanged(String? shift) {
|
||||
setState(() {
|
||||
_selectedShift = shift;
|
||||
});
|
||||
_searchTaxis();
|
||||
}
|
||||
|
||||
/// Handle search text change with debouncing
|
||||
void _onSearchChanged(String text) {
|
||||
setState(() {
|
||||
_searchText = text;
|
||||
});
|
||||
|
||||
// Cancel previous timer
|
||||
_searchDebouncer?.cancel();
|
||||
|
||||
// Start new timer for debounced search
|
||||
_searchDebouncer = Timer(const Duration(milliseconds: 300), () {
|
||||
_searchTaxis();
|
||||
});
|
||||
}
|
||||
|
||||
/// Clear all filters
|
||||
void _onClearFilters() {
|
||||
setState(() {
|
||||
_selectedCorregimiento = null;
|
||||
_selectedShift = null;
|
||||
_searchText = '';
|
||||
});
|
||||
_searchTaxis();
|
||||
}
|
||||
|
||||
/// Toggle favorite status for a taxi
|
||||
Future<void> _onFavoriteToggle(String taxiId) async {
|
||||
try {
|
||||
final isFavorite = await _taxiService.toggleFavorite(taxiId);
|
||||
|
||||
setState(() {
|
||||
if (isFavorite) {
|
||||
_favoriteTaxiIds.add(taxiId);
|
||||
} else {
|
||||
_favoriteTaxiIds.remove(taxiId);
|
||||
}
|
||||
});
|
||||
|
||||
// Show feedback
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
isFavorite
|
||||
? 'Taxi agregado a favoritos'
|
||||
: 'Taxi removido de favoritos',
|
||||
),
|
||||
duration: const Duration(seconds: 2),
|
||||
backgroundColor: isFavorite ? Colors.green : Colors.orange,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Error al actualizar favoritos: $e'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle pull to refresh
|
||||
Future<void> _onRefresh() async {
|
||||
await _loadInitialData();
|
||||
}
|
||||
|
||||
/// Get current empty state widget based on context
|
||||
Widget _getEmptyStateWidget() {
|
||||
if (_error != null) {
|
||||
return TaxiEmptyStateWidget.error(
|
||||
error: _error!,
|
||||
onRetry: _loadInitialData,
|
||||
);
|
||||
}
|
||||
|
||||
if (_selectedCorregimiento == null &&
|
||||
_selectedShift == null &&
|
||||
_searchText.isEmpty) {
|
||||
return TaxiEmptyStateWidget.noFiltersSelected();
|
||||
}
|
||||
|
||||
return TaxiEmptyStateWidget.noResultsFound(onClearFilters: _onClearFilters);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
appBar: const CustomAppBar(
|
||||
title: 'Taxi Directory',
|
||||
backgroundColor: Color(0xFF101820),
|
||||
foregroundColor: Color(0xFFFEE715),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
// Filters Section
|
||||
TaxiFiltersWidget(
|
||||
corregimientos: _corregimientos,
|
||||
shifts: _shifts,
|
||||
selectedCorregimiento: _selectedCorregimiento,
|
||||
selectedShift: _selectedShift,
|
||||
searchText: _searchText,
|
||||
onCorregimientoChanged: _onCorregimientoChanged,
|
||||
onShiftChanged: _onShiftChanged,
|
||||
onSearchChanged: _onSearchChanged,
|
||||
onClearFilters: _onClearFilters,
|
||||
),
|
||||
// Results Section
|
||||
Expanded(
|
||||
child:
|
||||
_isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: _taxis.isEmpty
|
||||
? _getEmptyStateWidget()
|
||||
: RefreshIndicator(
|
||||
onRefresh: _onRefresh,
|
||||
child: ListView.builder(
|
||||
itemCount: _taxis.length,
|
||||
itemBuilder: (context, index) {
|
||||
final taxi = _taxis[index];
|
||||
return TaxiCardWidget(
|
||||
taxi: taxi,
|
||||
isFavorite: _favoriteTaxiIds.contains(taxi.id),
|
||||
onFavoriteToggle: _onFavoriteToggle,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: CustomBottomBar(
|
||||
currentIndex: 3, // Taxi tab index
|
||||
onTap: _onBottomNavTap,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Handle bottom navigation tap
|
||||
void _onBottomNavTap(int index) {
|
||||
// Navigation is handled by CustomBottomBar
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user