Initial commit: SIBU 2.0 MISSION
This commit is contained in:
243
old/lib/services/taxi_service.dart
Normal file
243
old/lib/services/taxi_service.dart
Normal file
@ -0,0 +1,243 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
import '../models/taxi_model.dart';
|
||||
import './supabase_service.dart';
|
||||
|
||||
/// Service for managing taxi data and favorites functionality
|
||||
class TaxiService {
|
||||
static TaxiService? _instance;
|
||||
static TaxiService get instance => _instance ??= TaxiService._();
|
||||
TaxiService._();
|
||||
|
||||
final SupabaseClient _client = SupabaseService.client;
|
||||
static const String _favoritesKey = 'favorite_taxi_ids';
|
||||
|
||||
/// Get distinct corregimientos from active taxis
|
||||
Future<List<String>> getCorregimientos() async {
|
||||
try {
|
||||
final response = await _client
|
||||
.from('taxis')
|
||||
.select('corregimiento')
|
||||
.eq('is_active', true)
|
||||
.order('corregimiento');
|
||||
|
||||
if (response.isEmpty) return [];
|
||||
|
||||
// Extract unique corregimientos
|
||||
final Set<String> uniqueCorregimientos = {};
|
||||
for (final item in response) {
|
||||
final corregimiento = item['corregimiento'] as String?;
|
||||
if (corregimiento != null && corregimiento.isNotEmpty) {
|
||||
uniqueCorregimientos.add(corregimiento);
|
||||
}
|
||||
}
|
||||
|
||||
return uniqueCorregimientos.toList()..sort();
|
||||
} catch (e) {
|
||||
throw Exception('Failed to fetch corregimientos: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get available shifts
|
||||
List<String> getShifts() {
|
||||
return ['Day', 'Evening', 'Night'];
|
||||
}
|
||||
|
||||
/// Search taxis with optional corregimiento, shift, and text filters
|
||||
Future<List<TaxiModel>> searchTaxis({
|
||||
String? selectedCorregimiento,
|
||||
String? selectedShift,
|
||||
String? searchText,
|
||||
}) async {
|
||||
try {
|
||||
var query = _client.from('taxis').select('*').eq('is_active', true);
|
||||
|
||||
// Apply corregimiento filter
|
||||
if (selectedCorregimiento != null && selectedCorregimiento.isNotEmpty) {
|
||||
query = query.eq('corregimiento', selectedCorregimiento);
|
||||
}
|
||||
|
||||
// Apply shift filter
|
||||
if (selectedShift != null && selectedShift.isNotEmpty) {
|
||||
// Convert display name to database value
|
||||
String dbShift = selectedShift.toLowerCase();
|
||||
query = query.eq('shift', dbShift);
|
||||
}
|
||||
|
||||
// Apply text search filter
|
||||
if (searchText != null && searchText.isNotEmpty) {
|
||||
query = query.or('name.ilike.%$searchText%,phone.ilike.%$searchText%');
|
||||
}
|
||||
|
||||
final response = await query.order('name');
|
||||
|
||||
return response
|
||||
.map<TaxiModel>((json) => TaxiModel.fromJson(json))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
throw Exception('Failed to search taxis: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get user's favorite taxi IDs (from Supabase or local storage)
|
||||
Future<List<String>> getFavoriteTaxiIds() async {
|
||||
try {
|
||||
// Check if user is authenticated
|
||||
final user = _client.auth.currentUser;
|
||||
if (user != null) {
|
||||
// Get favorites from Supabase
|
||||
final response = await _client
|
||||
.from('favorite_taxis')
|
||||
.select('taxi_id')
|
||||
.eq('user_id', user.id);
|
||||
|
||||
return response
|
||||
.map<String>((item) => item['taxi_id'] as String)
|
||||
.toList();
|
||||
} else {
|
||||
// Get favorites from local storage
|
||||
return await _getLocalFavorites();
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback to local storage if Supabase fails
|
||||
return await _getLocalFavorites();
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggle favorite status for a taxi
|
||||
Future<bool> toggleFavorite(String taxiId) async {
|
||||
try {
|
||||
final user = _client.auth.currentUser;
|
||||
|
||||
if (user != null) {
|
||||
// Handle Supabase favorites
|
||||
return await _toggleSupabaseFavorite(user.id, taxiId);
|
||||
} else {
|
||||
// Handle local storage favorites
|
||||
return await _toggleLocalFavorite(taxiId);
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback to local storage
|
||||
return await _toggleLocalFavorite(taxiId);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if taxi is favorited
|
||||
Future<bool> isFavorite(String taxiId) async {
|
||||
final favorites = await getFavoriteTaxiIds();
|
||||
return favorites.contains(taxiId);
|
||||
}
|
||||
|
||||
/// Handle Supabase favorite toggle
|
||||
Future<bool> _toggleSupabaseFavorite(String userId, String taxiId) async {
|
||||
try {
|
||||
// Check if favorite exists
|
||||
final existing =
|
||||
await _client
|
||||
.from('favorite_taxis')
|
||||
.select('id')
|
||||
.eq('user_id', userId)
|
||||
.eq('taxi_id', taxiId)
|
||||
.maybeSingle();
|
||||
|
||||
if (existing != null) {
|
||||
// Remove favorite
|
||||
await _client
|
||||
.from('favorite_taxis')
|
||||
.delete()
|
||||
.eq('user_id', userId)
|
||||
.eq('taxi_id', taxiId);
|
||||
return false;
|
||||
} else {
|
||||
// Add favorite
|
||||
await _client.from('favorite_taxis').insert({
|
||||
'user_id': userId,
|
||||
'taxi_id': taxiId,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Failed to toggle Supabase favorite: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle local storage favorite toggle
|
||||
Future<bool> _toggleLocalFavorite(String taxiId) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final favorites = prefs.getStringList(_favoritesKey) ?? [];
|
||||
|
||||
if (favorites.contains(taxiId)) {
|
||||
favorites.remove(taxiId);
|
||||
await prefs.setStringList(_favoritesKey, favorites);
|
||||
return false;
|
||||
} else {
|
||||
favorites.add(taxiId);
|
||||
await prefs.setStringList(_favoritesKey, favorites);
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Failed to toggle local favorite: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get favorites from local storage
|
||||
Future<List<String>> _getLocalFavorites() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getStringList(_favoritesKey) ?? [];
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all local favorites (for testing/reset)
|
||||
Future<void> clearLocalFavorites() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_favoritesKey);
|
||||
} catch (e) {
|
||||
// Silent fail for clearing favorites
|
||||
}
|
||||
}
|
||||
|
||||
/// Sync local favorites to Supabase when user authenticates
|
||||
Future<void> syncLocalFavoritesToSupabase() async {
|
||||
try {
|
||||
final user = _client.auth.currentUser;
|
||||
if (user == null) return;
|
||||
|
||||
final localFavorites = await _getLocalFavorites();
|
||||
if (localFavorites.isEmpty) return;
|
||||
|
||||
// Get existing Supabase favorites
|
||||
final supabaseFavorites = await _client
|
||||
.from('favorite_taxis')
|
||||
.select('taxi_id')
|
||||
.eq('user_id', user.id);
|
||||
|
||||
final existingIds =
|
||||
supabaseFavorites
|
||||
.map<String>((item) => item['taxi_id'] as String)
|
||||
.toSet();
|
||||
|
||||
// Add local favorites that don't exist in Supabase
|
||||
final toAdd = localFavorites.where((id) => !existingIds.contains(id));
|
||||
|
||||
if (toAdd.isNotEmpty) {
|
||||
final insertData =
|
||||
toAdd
|
||||
.map((taxiId) => {'user_id': user.id, 'taxi_id': taxiId})
|
||||
.toList();
|
||||
|
||||
await _client.from('favorite_taxis').insert(insertData);
|
||||
}
|
||||
|
||||
// Clear local favorites after successful sync
|
||||
await clearLocalFavorites();
|
||||
} catch (e) {
|
||||
// Silent fail for sync operation
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user