feat: migrate prosappco from Firebase to NestJS REST API (Fase 2)
- Replace all Firebase* repositories with Api* repositories using HTTP + SharedPreferences JWT - Remove Firebase.initializeApp() and firebase_messaging background handler from main.dart - Update DI (app_di.dart) to inject Api* repositories instead of Firebase* ones - Replace all Timestamp/cloud_firestore usage with ISO 8601 String dates - Stub PhoneVerificationService (Firebase phone OTP → backend OTP when implemented) - Add ApiService singleton with JWT management in lib/services/ - Legacy firebase_*_repository.dart files preserved for Fase 4 cleanup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
726cf12fd2
commit
733384091c
@@ -0,0 +1,76 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:city_repository/city_repository.dart';
|
||||
import 'city_repo.dart';
|
||||
|
||||
const _base = 'https://backend.prosapp.co/api/v1';
|
||||
|
||||
class ApiCityRepository implements CityRepository {
|
||||
List<CityUi>? _cities;
|
||||
|
||||
Future<String?> _getToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString('token');
|
||||
}
|
||||
|
||||
Future<Map<String, String>> _headers() async {
|
||||
final t = await _getToken();
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
if (t != null) 'Authorization': 'Bearer $t',
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<CityUi>> getCities() async {
|
||||
if (_cities != null) return _cities!;
|
||||
|
||||
final List<CityUi> cities = [];
|
||||
|
||||
try {
|
||||
final countriesRes = await http.get(
|
||||
Uri.parse('$_base/locations/countries'),
|
||||
headers: await _headers(),
|
||||
);
|
||||
final countries = jsonDecode(countriesRes.body) as List;
|
||||
|
||||
for (final country in countries) {
|
||||
final countryId = country['id']?.toString() ?? '';
|
||||
final countryName = country['name']?.toString() ?? '';
|
||||
|
||||
final regionsRes = await http.get(
|
||||
Uri.parse('$_base/locations/countries/$countryId/regions'),
|
||||
headers: await _headers(),
|
||||
);
|
||||
final regions = jsonDecode(regionsRes.body) as List;
|
||||
|
||||
for (final region in regions) {
|
||||
final regionId = region['id']?.toString() ?? '';
|
||||
final regionName = region['name']?.toString() ?? '';
|
||||
|
||||
final citiesRes = await http.get(
|
||||
Uri.parse('$_base/locations/regions/$regionId/cities'),
|
||||
headers: await _headers(),
|
||||
);
|
||||
final citiesList = jsonDecode(citiesRes.body) as List;
|
||||
|
||||
for (final city in citiesList) {
|
||||
cities.add(CityUi(
|
||||
cityName: city['name']?.toString() ?? '',
|
||||
coordsOfCity: city['coords']?.toString() ?? '',
|
||||
stateOfCity: regionName,
|
||||
countryOfCity: countryName,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
|
||||
_cities = cities;
|
||||
return cities;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user