This commit is contained in:
Felipe
2024-03-13 13:59:33 -05:00
parent 312cc3d863
commit a25bc6a987
26 changed files with 684 additions and 60 deletions
@@ -0,0 +1,6 @@
library city_repository;
export 'src/models/models.dart';
export 'src/entities/entities.dart';
export 'src/repositories/city_repo.dart';
export 'src/repositories/firebase_city_repository.dart';
@@ -0,0 +1,36 @@
import 'package:equatable/equatable.dart';
class CityEntity extends Equatable {
final String name;
final String coords;
const CityEntity({
required this.name,
required this.coords,
});
Map<String, Object?> toDocument() {
return {
'name': name,
'coords': coords,
};
}
static CityEntity fromDocument(Map<String, dynamic> doc) {
return CityEntity(
name: doc['name'] as String,
coords: doc['coords'] as String,
);
}
@override
List<Object?> get props => [name, coords];
@override
String toString() {
return '''CityEntity {
name: $name
coords: $coords
}''';
}
}
@@ -0,0 +1,39 @@
import 'package:equatable/equatable.dart';
import 'package:city_repository/city_repository.dart';
class CountryEntity extends Equatable {
final String name;
final List<RegionEntity> regions;
const CountryEntity({
required this.name,
required this.regions,
});
Map<String, Object?> toDocument() {
return {
'name': name,
'states': regions,
};
}
static CountryEntity fromDocument(Map<String, dynamic> doc) {
return CountryEntity(
name: doc['name'] as String,
regions: (doc['states'] as List)
.map((region) => RegionEntity.fromDocument(region))
.toList(),
);
}
@override
List<Object?> get props => [name, regions];
@override
String toString() {
return '''CountryEntity {
name: $name
regions: $regions
}''';
}
}
@@ -0,0 +1,3 @@
export '/src/entities/country_entity.dart';
export '/src/entities/region_entity.dart';
export '/src/entities/city_entity.dart';
@@ -0,0 +1,39 @@
import 'package:equatable/equatable.dart';
import 'package:city_repository/city_repository.dart';
class RegionEntity extends Equatable {
final String name;
final List<CityEntity> cities;
const RegionEntity({
required this.name,
required this.cities,
});
Map<String, Object?> toDocument() {
return {
'name': name,
'cities': cities,
};
}
static RegionEntity fromDocument(Map<String, dynamic> doc) {
return RegionEntity(
name: doc['name'] as String,
cities: (doc['cities'] as List)
.map((city) => CityEntity.fromDocument(city))
.toList(),
);
}
@override
List<Object?> get props => [name, cities];
@override
String toString() {
return '''RegionEntity {
name: $name
cities: $cities
}''';
}
}
@@ -0,0 +1,45 @@
import 'package:equatable/equatable.dart';
import 'package:city_repository/city_repository.dart';
class City extends Equatable {
final String name;
final String coords;
const City({
required this.name,
required this.coords,
});
static const empty = City(name: '', coords: '');
City copyWith({
String? name,
String? coords,
}) {
return City(
name: name ?? this.name,
coords: coords ?? this.coords,
);
}
bool get isEmpty => this == City.empty;
bool get isNotEmpty => this != City.empty;
City toEntity() {
return City(
name: name,
coords: coords,
);
}
static City fromEntity(CityEntity entity) {
return City(
name: entity.name,
coords: entity.coords,
);
}
@override
List<Object?> get props => [name, coords];
}
@@ -0,0 +1,19 @@
import 'package:equatable/equatable.dart';
class CityUi extends Equatable {
final String cityName;
final String coordsOfCity;
final String stateOfCity;
final String countryOfCity;
const CityUi({
required this.cityName,
required this.coordsOfCity,
required this.stateOfCity,
required this.countryOfCity,
});
@override
List<Object?> get props =>
[cityName, coordsOfCity, stateOfCity, countryOfCity];
}
@@ -0,0 +1,42 @@
import 'package:equatable/equatable.dart';
import 'package:city_repository/city_repository.dart';
class Country extends Equatable {
final String name;
final List<Region> regions;
const Country({
required this.name,
required this.regions,
});
static const empty = Country(name: '', regions: []);
Country copyWith({
String? name,
List<Region>? regions,
}) {
return Country(
name: name ?? this.name,
regions: regions ?? this.regions,
);
}
bool get isEmpty => this == Country.empty;
bool get isNotEmpty => this != Country.empty;
Country toEntity() {
return Country(name: name, regions: regions);
}
static Country fromEntity(CountryEntity entity) {
return Country(
name: entity.name,
regions:
entity.regions.map((region) => Region.fromEntity(region)).toList(),
);
}
@override
List<Object?> get props => [name, regions];
}
@@ -0,0 +1,4 @@
export 'country.dart';
export 'region.dart';
export 'city.dart';
export 'city_ui.dart';
@@ -0,0 +1,41 @@
import 'package:equatable/equatable.dart';
import 'package:city_repository/city_repository.dart';
class Region extends Equatable {
final String name;
final List<City> cities;
const Region({
required this.name,
required this.cities,
});
static const empty = Region(name: '', cities: []);
Region copyWith({
String? name,
List<City>? cities,
}) {
return Region(
name: name ?? this.name,
cities: cities ?? this.cities,
);
}
bool get isEmpty => this == Region.empty;
bool get isNotEmpty => this != Region.empty;
Region toEntity() {
return Region(name: name, cities: cities);
}
static Region fromEntity(RegionEntity entity) {
return Region(
name: entity.name,
cities: entity.cities.map((city) => City.fromEntity(city)).toList(),
);
}
@override
List<Object?> get props => [name, cities];
}
@@ -0,0 +1,6 @@
import 'package:city_repository/city_repository.dart';
import 'package:city_repository/src/models/city_ui.dart';
abstract class CityRepository {
Future<List<CityUi>> getCities();
}
@@ -0,0 +1,44 @@
import 'dart:developer';
import 'package:city_repository/city_repository.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class FirebaseCityRepository implements CityRepository {
final citiesCollection =
FirebaseFirestore.instance.collection('countries v2');
List<CityUi>? _cities;
@override
Future<List<CityUi>> getCities() async {
if (_cities != null) {
return _cities!;
}
final List<CityUi> cities = [];
try {
final doc = await citiesCollection.doc("Colombia").get();
final data = doc.data();
final country = CountryEntity.fromDocument(data as Map<String, dynamic>);
for (var region in country.regions) {
for (var city in region.cities) {
cities.add(CityUi(
cityName: city.name,
coordsOfCity: city.coords,
stateOfCity: region.name,
countryOfCity: country.name));
}
}
} catch (e) {
log(e.toString());
rethrow;
}
_cities = cities;
return cities;
}
}