diff --git a/hakim_hub_mobile/lib/features/hospital/data/datasources/example_local_datasource.dart b/hakim_hub_mobile/lib/features/hospital/data/datasources/example_local_datasource.dart deleted file mode 100644 index e69de29..0000000 diff --git a/hakim_hub_mobile/lib/features/hospital/data/datasources/example_remote_datasource.dart b/hakim_hub_mobile/lib/features/hospital/data/datasources/example_remote_datasource.dart deleted file mode 100644 index e69de29..0000000 diff --git a/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_detail_remote_datasource.dart b/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_detail_remote_datasource.dart index 1d64233..7b0f97a 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_detail_remote_datasource.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_detail_remote_datasource.dart @@ -9,16 +9,42 @@ import 'package:hakim_hub_mobile/features/hospital/data/models/hospital_doctor_m import 'package:hakim_hub_mobile/features/hospital/domain/usecases/get_doctor_by_filter.dart'; import 'package:http/http.dart' as http; +/// Hospital detail remote data source. +/// +/// Contains methods for retrieving hospital and doctor data from a remote API. abstract class HospitalDetailRemoteDataSource { - Future getHospitalDetail(String hospitalID); + /// Gets the detail information for a hospital. + /// + /// Fetches the hospital data from the `/InsitutionProfile/{id}` endpoint. + /// Throws a [ServerException] for all error codes. + /// + /// Parameters: + /// hospitalId: The ID of the hospital to get details for. + /// Returns: The [InstitutionDetailModel] for the hospital. + Future getHospitalDetail(String hospitalId); + + /// Gets doctors filtered by the provided criteria. + /// + /// Calls the `/DoctorProfiles/filter` endpoint to find doctors. + /// Throws a [ServerException] for any errors. + /// + /// Parameters: + /// doctorFilterModel: The filter criteria to find doctors by. + /// Returns: A list of [DoctorModel] matching the filter. Future> getDoctorByFilter( DoctorFilterModel doctorFilterModel); } +/// Implementation of [HospitalDetailRemoteDataSource] that uses an HTTP client. class HospitalDetailRemoteDataSoureImpl implements HospitalDetailRemoteDataSource { + /// The HTTP client for making requests. final http.Client client; + + /// Base API URL. String baseUrl = getBaseUrl(); + + /// Creates an instance with the provided [client]. HospitalDetailRemoteDataSoureImpl({required this.client}); @override @@ -30,13 +56,14 @@ class HospitalDetailRemoteDataSoureImpl HttpHeaders.contentTypeHeader: 'application/json', }, ); + if (response.statusCode == 200) { final responseBody = response.body; + if (responseBody.isNotEmpty) { final Map json = jsonDecode(responseBody)["value"]; - InstitutionDetailModel institutionDetailModel = - InstitutionDetailModel.fromJson(json); - return institutionDetailModel; + + return InstitutionDetailModel.fromJson(json); } else { throw ServerException(); } @@ -73,8 +100,6 @@ class HospitalDetailRemoteDataSoureImpl throw ServerException(); } } catch (e) { - print(e.toString()); - throw ServerException(); } } diff --git a/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_remote_datasource.dart b/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_remote_datasource.dart index 916f0c8..b055fbc 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_remote_datasource.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/datasources/hospital_remote_datasource.dart @@ -1,5 +1,3 @@ - - import 'dart:convert'; import 'dart:io'; @@ -10,29 +8,59 @@ import 'package:http/http.dart' as http; import '../models/hospital_search_model.dart'; - +/// Remote data source for searching hospitals. +/// +/// Provides methods for searching for hospitals by different criteria. abstract class HospitalSearchRemoteDataSource { + /// Searches for hospitals matching the filter criteria. + /// + /// Calls the `/InsitutionProfile/search-institutions` endpoint to find hospitals. + /// Throws a [ServerException] on any error. + /// + /// Parameters: + /// filterHospitalModel: Filter criteria to search by. + /// Returns: List of [InstitutionSearchModel] matching the filter. Future> searchByFilterHospitals( FilterHospitalModel filterHospitalModel); - Future> searchByNameHospitals( - String name); + /// Searches hospitals by name. + /// + /// Calls `/InsitutionProfile/search-by-name` to find hospitals. + /// Throws a [ServerException] on any error. + /// + /// Parameters: + /// name: Name to search hospitals by. + /// Returns: List of [InstitutionSearchModel] matching the name. + Future> searchByNameHospitals(String name); + + /// Gets all hospitals. + /// + /// Calls `/InsitutionProfile` to retrieve all hospitals. + /// Throws a [ServerException] on any error. + /// + /// Returns: List of all [InstitutionSearchModel] hospitals. Future> getAllHospitals(); } -class HospitalSearchRemoteDataSourceImpl implements HospitalSearchRemoteDataSource { +/// Implementation of [HospitalSearchRemoteDataSource] using HTTP client. +class HospitalSearchRemoteDataSourceImpl + implements HospitalSearchRemoteDataSource { + /// HTTP client for making requests. final http.Client client; + + /// Base API URL. String baseUrl = getBaseUrl(); + + /// Creates an instance with the provided HTTP [client]. HospitalSearchRemoteDataSourceImpl({required this.client}); @override - Future> searchByFilterHospitals(FilterHospitalModel filterHospitalModel) async { - + Future> searchByFilterHospitals( + FilterHospitalModel filterHospitalModel) async { try { - final response = await client.post( - - Uri.parse(baseUrl + '/InsitutionProfile/search-institutions?operationYears=${filterHospitalModel.operationYears}&openStatus=${filterHospitalModel.openStatus}'), + Uri.parse(baseUrl + + '/InsitutionProfile/search-institutions?operationYears=${filterHospitalModel.operationYears}&openStatus=${filterHospitalModel.openStatus}'), headers: { HttpHeaders.contentTypeHeader: 'application/json', }, @@ -40,22 +68,23 @@ class HospitalSearchRemoteDataSourceImpl implements HospitalSearchRemoteDataSour ); if (response.statusCode == 200) { - List returned = json.decode(response.body)["value"]; - List hospitals = returned.map((data) => InstitutionSearchModel.fromJson(data)).toList(); + List hospitals = returned + .map((data) => InstitutionSearchModel.fromJson(data)) + .toList(); return hospitals; } else { throw ServerException(); } - } catch (e) { throw ServerException(); } } @override - Future> searchByNameHospitals(String name) async { + Future> searchByNameHospitals( + String name) async { try { final response = await client.get( Uri.parse(baseUrl + '/InsitutionProfile/search-by-name?Name=$name'), @@ -65,15 +94,15 @@ class HospitalSearchRemoteDataSourceImpl implements HospitalSearchRemoteDataSour ); if (response.statusCode == 200) { - List returned = json.decode(response.body)["value"]; - List hospitals = returned.map((data) => InstitutionSearchModel.fromJson(data)).toList(); + List hospitals = returned + .map((data) => InstitutionSearchModel.fromJson(data)) + .toList(); return hospitals; } else { throw ServerException(); } - } catch (e) { throw ServerException(); } @@ -81,7 +110,6 @@ class HospitalSearchRemoteDataSourceImpl implements HospitalSearchRemoteDataSour @override Future> getAllHospitals() async { - try { final response = await client.get( Uri.parse(baseUrl + '/InsitutionProfile'), @@ -89,22 +117,19 @@ class HospitalSearchRemoteDataSourceImpl implements HospitalSearchRemoteDataSour HttpHeaders.contentTypeHeader: 'application/json', }, ); - if (response.statusCode == 200) { - List returned = json.decode(response.body)["value"]; - List hospitals = returned.map((data) => InstitutionSearchModel.fromJson(data)).toList(); + List hospitals = returned + .map((data) => InstitutionSearchModel.fromJson(data)) + .toList(); return hospitals; } else { - throw ServerException(); } - } catch (e) { throw ServerException(); } } - -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/eductational_institution.dart b/hakim_hub_mobile/lib/features/hospital/data/models/eductational_institution.dart index 2ec3125..2a1296a 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/eductational_institution.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/eductational_institution.dart @@ -1,16 +1,24 @@ import 'package:hakim_hub_mobile/features/hospital/domain/entities/educational_institute.dart'; +/// Model representing an educational institution. class EducationInstituteModel extends EductationalInstitutionDomain { + /// Name of the educational institution. String institutionName; + + /// URL of the institution's logo. String logoUrl; + + /// Unique ID for the institution. String id; + /// Create an instance from the provided data. EducationInstituteModel({ required this.institutionName, required this.logoUrl, required this.id, }) : super(id: id, institutionName: institutionName, logoUrl: logoUrl); + /// Construct an instance from a JSON map. factory EducationInstituteModel.fromJson(Map json) { return EducationInstituteModel( institutionName: json['institutionName'] ?? " ", @@ -18,6 +26,8 @@ class EducationInstituteModel extends EductationalInstitutionDomain { id: json['id'] ?? " ", ); } + + /// Convert an instance to a JSON map. Map toJson() { return { 'institutionName': institutionName, diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/example_model.dart b/hakim_hub_mobile/lib/features/hospital/data/models/example_model.dart deleted file mode 100644 index e69de29..0000000 diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/filter_doctors_model.dart b/hakim_hub_mobile/lib/features/hospital/data/models/filter_doctors_model.dart index cfe5a18..cee013f 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/filter_doctors_model.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/filter_doctors_model.dart @@ -1,21 +1,33 @@ import 'package:hakim_hub_mobile/features/hospital/domain/entities/filter_doctor_domain.dart'; +/// Model for filtering doctors. class DoctorFilterModel extends DoctorFilterDomain { + /// ID of the institution to filter by. String institutionId; + + /// Years of experience to filter by. String experienceYears; + + /// Educational institution name to filter by. String educationalName; + + /// List of specialities to filter by. List specialities; + /// Create an instance from provided data. DoctorFilterModel({ required this.institutionId, required this.experienceYears, required this.educationalName, required this.specialities, }) : super( - educationalName: educationalName, - experienceYears: experienceYears, - specialities: specialities, - institutionId: institutionId); + educationalName: educationalName, + experienceYears: experienceYears, + specialities: specialities, + institutionId: institutionId, + ); + + /// Convert to a JSON map. Map toJson() { return { 'institutionId': institutionId, diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/filter_hospital_model.dart b/hakim_hub_mobile/lib/features/hospital/data/models/filter_hospital_model.dart index e7bc77f..444f601 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/filter_hospital_model.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/filter_hospital_model.dart @@ -1,12 +1,23 @@ +import 'package:hakim_hub_mobile/features/hospital/domain/entities/filter_hospital_domain.dart'; +/// Model for filtering hospitals. +class FilterHospitalModel extends FilterHospitalDomain { + /// Number of years the hospital has been active. + int activeFor; -import 'package:hakim_hub_mobile/features/hospital/domain/entities/filter_hospital_domain.dart'; + /// Whether the hospital is open now. + bool openNow; + + /// List of services offered by the hospital. + List services; -class FilterHospitalModel extends FilterHospitalDomain{ - + /// Create an instance with provided filter criteria. + FilterHospitalModel( + {required this.activeFor, required this.openNow, required this.services}) + : super( + operationYears: activeFor, openStatus: openNow, services: services); - FilterHospitalModel({required int activeFor, required bool openNow, required List services}):super(operationYears : activeFor, openStatus: openNow, services: services); - + /// Convert to JSON map. toJson() { return { 'openNow': openStatus, @@ -14,4 +25,4 @@ class FilterHospitalModel extends FilterHospitalDomain{ 'services': services }; } -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_address.dart b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_address.dart index d9eb96e..ece5e2d 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_address.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_address.dart @@ -1,18 +1,50 @@ import '../../domain/entities/hospital_address_domain.dart'; +/// Model representing a hospital address. class AddressModel extends AddressDomain { - AddressModel({ - required String country, - required String region, - required String zone, - required String woreda, - required String city, - required String subCity, - required double longitude, - required double latitude, - required String summary, - required String id, - }) : super( + /// Country name. + String country; + + /// Region name. + String region; + + /// Zone name. + String zone; + + /// Woreda name. + String woreda; + + /// City name. + String city; + + /// Sub-city name. + String subCity; + + /// Longitude coordinate. + double longitude; + + /// Latitude coordinate. + double latitude; + + /// Summary of full address. + String summary; + + /// Unique ID of the address. + String id; + + /// Create an instance with provided address data. + AddressModel( + {required this.country, + required this.region, + required this.zone, + required this.woreda, + required this.city, + required this.subCity, + required this.longitude, + required this.latitude, + required this.summary, + required this.id}) + : super( city: city, country: country, id: id, @@ -24,6 +56,7 @@ class AddressModel extends AddressDomain { woreda: woreda, zone: zone); + /// Construct instance from JSON data. factory AddressModel.fromJson(Map json) { return AddressModel( country: json['country'] ?? "country", @@ -38,6 +71,8 @@ class AddressModel extends AddressDomain { id: json['id'] ?? "id", ); } + + /// Convert instance to JSON. Map toJson() { return { 'country': country, diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_availability.dart b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_availability.dart index 5873c03..8191091 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_availability.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_availability.dart @@ -1,22 +1,42 @@ import '../../domain/entities/hospital_availability_domain.dart'; +/// Model representing a hospital's availability schedule. class InstitutionAvailabilityModel extends InstitutionAvailabilityDomain { - InstitutionAvailabilityModel({ - required String startDay, - required String endDay, - required String opening, - required String closing, - required bool twentyFourHours, - required String id, - }) : super( - startDay: startDay, - endDay: endDay, - opening: opening, - closing: closing, - twentyFourHours: twentyFourHours, - id: id, - ); + /// Index of start day of schedule (0-6). + String startDay; + /// Index of end day of schedule (0-6). + String endDay; + + /// Opening time. + String opening; + + /// Closing time. + String closing; + + /// Whether open 24 hours. + bool twentyFourHours; + + /// Unique ID. + String id; + + /// Create new instance with provided data. + InstitutionAvailabilityModel( + {required this.startDay, + required this.endDay, + required this.opening, + required this.closing, + required this.twentyFourHours, + required this.id}) + : super( + startDay: startDay, + endDay: endDay, + opening: opening, + closing: closing, + twentyFourHours: twentyFourHours, + id: id); + + /// Construct from JSON data. factory InstitutionAvailabilityModel.fromJson(Map json) { return InstitutionAvailabilityModel( startDay: json['startDay'] ?? "0", @@ -27,6 +47,8 @@ class InstitutionAvailabilityModel extends InstitutionAvailabilityDomain { id: json['id'] ?? "id", ); } + + /// Convert to JSON. Map toJson() { return { 'startDay': startDay, diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_detail_model.dart b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_detail_model.dart index 1b3d88c..c367211 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_detail_model.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_detail_model.dart @@ -4,7 +4,9 @@ import 'hospital_address.dart'; import 'hospital_availability.dart'; import 'hospital_doctor_model.dart'; +/// Model representing detailed institution (hospital) data. class InstitutionDetailModel extends InstitutionDetailDomain { + /// Create new instance with provided data. InstitutionDetailModel({ required String institutionName, required String branchName, @@ -45,21 +47,15 @@ class InstitutionDetailModel extends InstitutionDetailDomain { id: id, ); + /// Construct from JSON data. factory InstitutionDetailModel.fromJson(Map json) { List returnedEducationInstitutuions = json['allEducationalInstitutions'] ?? []; List returnedDoctors = json['doctors'] ?? []; - - // List educationInstituteModel = - // List.from(returnedEducationInstitutuions - // .map((x) => EducationInstituteModel.fromJson(x))); - List educationInstituteModel = returnedEducationInstitutuions .map((x) => EducationInstituteModel.fromJson(x)) .toList(); - print(returnedDoctors); - print("before doctors"); List returnedDoctorsModel = returnedDoctors.map((x) => DoctorModel.fromJson(x)).toList(); @@ -86,6 +82,8 @@ class InstitutionDetailModel extends InstitutionDetailDomain { doctors: returnedDoctorsModel, ); } + + /// Convert to JSON. Map toJson() { final Map data = new Map(); diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_doctor_model.dart b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_doctor_model.dart index 6db616a..27166c9 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_doctor_model.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_doctor_model.dart @@ -1,6 +1,7 @@ import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_doctor_domain.dart'; class DoctorModel extends DoctorDomain { + /// Create a new instance with provided data. DoctorModel({ required fullName, required about, @@ -25,6 +26,7 @@ class DoctorModel extends DoctorDomain { id: id, ); + /// Construct instance from JSON data. factory DoctorModel.fromJson(Map json) { return DoctorModel( fullName: json['fullName'] ?? 'No Doctor Name', @@ -41,6 +43,8 @@ class DoctorModel extends DoctorDomain { id: json['id'] ?? '', ); } + + /// Convert instance to JSON. Map toJson() { return { 'fullName': fullName, diff --git a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_search_model.dart b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_search_model.dart index 02b9bad..e5c4074 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/models/hospital_search_model.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/models/hospital_search_model.dart @@ -2,6 +2,7 @@ import '../../domain/entities/hospital_search_domain.dart'; import 'hospital_address.dart'; import 'hospital_availability.dart'; +/// Model representing institution search (hospital search) data. class InstitutionSearchModel extends InstitutionSearchDomain { InstitutionSearchModel({ required String institutionName, @@ -42,7 +43,8 @@ class InstitutionSearchModel extends InstitutionSearchDomain { website: json['website'] ?? "website", phoneNumber: json['phoneNumber'] ?? "phoneNumber", summary: json['summary'] ?? "summary", - establishedOn: DateTime.parse(json['establishedOn'] ?? DateTime.now().toString()) , + establishedOn: + DateTime.parse(json['establishedOn'] ?? DateTime.now().toString()), rate: (json['rate'] ?? "0.0").toDouble(), status: json['status'] ?? "Close", logoUrl: json['logoUrl'] ?? "assets/images/hospital_img.png", @@ -50,8 +52,8 @@ class InstitutionSearchModel extends InstitutionSearchDomain { institutionAvailability: InstitutionAvailabilityModel.fromJson( json['institutionAvailability'] ?? {}), address: AddressModel.fromJson(json['address'] ?? {}), - services: List.from(json['services'] ?? ["General","Cardio"]), - id: json['id']?? "ss", + services: List.from(json['services'] ?? ["General", "Cardio"]), + id: json['id'] ?? "ss", ); } } diff --git a/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_detail_repository_impl.dart b/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_detail_repository_impl.dart index 4adc568..51f9aff 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_detail_repository_impl.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_detail_repository_impl.dart @@ -9,14 +9,24 @@ import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_deta import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_doctor_domain.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/repositories/hospital_detail_repository.dart'; +/// Repository for fetching hospital detail data from a remote source. class HospitalDetailRepositoryImpl implements HospitalDetailRepository { + /// The remote data source where hospital data is fetched from. final HospitalDetailRemoteDataSource remoteDataSource; + + /// Provides network connectivity information. final NetworkInfo networkInfo; - HospitalDetailRepositoryImpl({ - required this.remoteDataSource, - required this.networkInfo, - }); + /// Create a new instance that fetches data from the provided [remoteDataSource]. + /// + /// [networkInfo] is used to check for internet connectivity before making a request. + HospitalDetailRepositoryImpl( + {required this.remoteDataSource, required this.networkInfo}); + + /// Get the detailed data for a hospital by ID. + /// + /// If the device is connected to the internet, requests the data from + /// [remoteDataSource]. Otherwise returns a [ServerFailure]. @override Future> getHospitalDetail( @@ -34,6 +44,10 @@ class HospitalDetailRepositoryImpl implements HospitalDetailRepository { } } + /// Get a list of doctors filtered by the provided criteria. + /// + /// If the device has internet connectivity, requests matching doctors from + /// [remoteDataSource]. Otherwise returns a [ServerFailure]. @override Future>> getFilteredDoctors( DoctorFilterDomain doctorFilterDomain) async { diff --git a/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_repository_impl.dart b/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_repository_impl.dart index 743c267..c81e630 100644 --- a/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_repository_impl.dart +++ b/hakim_hub_mobile/lib/features/hospital/data/repositories/hospital_repository_impl.dart @@ -1,5 +1,3 @@ - - import 'package:dartz/dartz.dart'; import 'package:hakim_hub_mobile/features/hospital/data/models/filter_hospital_model.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/entities/filter_hospital_domain.dart'; @@ -11,24 +9,34 @@ import '../../../../core/network/network_info.dart'; import '../../domain/repositories/search_hospitals_repository.dart'; import '../datasources/hospital_remote_datasource.dart'; +/// Implementation of [HospitalsSearchRepository] to search for hospitals. class HospitalSearchRepositoryImpl implements HospitalsSearchRepository { + /// The remote data source to search hospitals from. final HospitalSearchRemoteDataSource remoteDataSource; + + /// Provides network connectivity information. final NetworkInfo networkInfo; + /// Create new instance with required dependencies. HospitalSearchRepositoryImpl({ required this.remoteDataSource, required this.networkInfo, }); + /// Search hospitals matching the provided filter criteria. + /// + /// Calls remote data source if device is online, otherwise returns [ServerFailure]. @override - Future>> searchByFilterHospitals( - FilterHospitalDomain filterHospital) async { - + Future>> + searchByFilterHospitals(FilterHospitalDomain filterHospital) async { if (await networkInfo.isConnected) { try { - FilterHospitalModel filterHospitalModel = FilterHospitalModel(activeFor: filterHospital.operationYears, openNow: filterHospital.openStatus, services: filterHospital.services); - final remoteHospitals = await remoteDataSource - .searchByFilterHospitals(filterHospitalModel); + FilterHospitalModel filterHospitalModel = FilterHospitalModel( + activeFor: filterHospital.operationYears, + openNow: filterHospital.openStatus, + services: filterHospital.services); + final remoteHospitals = + await remoteDataSource.searchByFilterHospitals(filterHospitalModel); return Right(remoteHospitals); } on ServerException { return Left(ServerFailure()); @@ -38,12 +46,16 @@ class HospitalSearchRepositoryImpl implements HospitalsSearchRepository { } } + /// Search hospitals by name. + /// + /// Requests remote data source if connected, otherwise returns [ServerFailure]. @override Future>> searchByNameHospitals( String name) async { if (await networkInfo.isConnected) { try { - final remoteHospitals = await remoteDataSource.searchByNameHospitals(name); + final remoteHospitals = + await remoteDataSource.searchByNameHospitals(name); return Right(remoteHospitals); } on ServerException { return Left(ServerFailure()); @@ -53,8 +65,12 @@ class HospitalSearchRepositoryImpl implements HospitalsSearchRepository { } } + /// Get all hospitals. + /// + /// Fetches from remote if device is online, otherwise returns [ServerFailure]. @override - Future>> getAllHospitals() async { + Future>> + getAllHospitals() async { if (await networkInfo.isConnected) { try { final remoteHospitals = await remoteDataSource.getAllHospitals(); @@ -66,4 +82,4 @@ class HospitalSearchRepositoryImpl implements HospitalsSearchRepository { return Left(ServerFailure()); } } -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/educational_institute.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/educational_institute.dart index 5a9bc82..d3083c2 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/educational_institute.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/educational_institute.dart @@ -1,18 +1,29 @@ import 'package:equatable/equatable.dart'; +/// Domain entity representing an educational institution. class EductationalInstitutionDomain extends Equatable { + /// Name of the educational institution. final String institutionName; + + /// URL of the institution's logo image. final String logoUrl; + + /// Unique identifier for the institution. final String id; + /// Create a new instance with the provided data. EductationalInstitutionDomain({ required this.institutionName, required this.logoUrl, required this.id, }); + /// List of properties to check for equality. @override List get props => [institutionName, logoUrl, id]; + /// Convert object to JSON. + /// + /// This base class returns an empty map. Subclasses should override to fully implement. toJson() {} } diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_doctor_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_doctor_domain.dart index f6b1820..2f60154 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_doctor_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_doctor_domain.dart @@ -1,11 +1,20 @@ import 'package:equatable/equatable.dart'; +/// Domain entity representing doctor filter criteria. class DoctorFilterDomain extends Equatable { + /// ID of the institution to filter by. final String institutionId; + + /// Minimum years of experience to filter by. final String experienceYears; + + /// Name of educational institute to filter by. final String educationalName; + + /// List of specialities to filter doctors by. final List specialities; + /// Create a new instance with provided filter criteria. DoctorFilterDomain({ required this.institutionId, required this.experienceYears, @@ -13,6 +22,7 @@ class DoctorFilterDomain extends Equatable { required this.specialities, }); + /// Properties to check for equality. @override List get props => [institutionId, experienceYears, educationalName, specialities]; diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_hospital_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_hospital_domain.dart index 0240150..6835649 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_hospital_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/filter_hospital_domain.dart @@ -1,16 +1,24 @@ import 'package:equatable/equatable.dart'; +/// Domain entity for hospital filter criteria. class FilterHospitalDomain extends Equatable { + /// Whether the hospital should be open currently. final bool openStatus; + + /// Number of years the hospital has been operating. final int operationYears; + + /// List of services offered by the hospital. final List services; + /// Create a new instance with the provided filter criteria. FilterHospitalDomain({ required this.operationYears, required this.openStatus, required this.services, }); + /// List of properties to check for equality. @override List get props => [openStatus, operationYears, services]; } diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_address_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_address_domain.dart index 6479711..6631e03 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_address_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_address_domain.dart @@ -1,30 +1,51 @@ import 'package:equatable/equatable.dart'; +/// Domain entity representing an address. class AddressDomain extends Equatable { + /// Country name. final String country; + + /// Region name. final String region; + + /// Zone name. final String zone; + + /// Woreda name. final String woreda; + + /// City name. final String city; + + /// Sub-city name. final String subCity; + + /// Longitude coordinate. final double longitude; + + /// Latitude coordinate. final double latitude; + + /// Summary of the full address. final String summary; + + /// Unique identifier for the address. final String id; - AddressDomain({ - required this.country, - required this.region, - required this.zone, - required this.woreda, - required this.city, - required this.subCity, - required this.longitude, - required this.latitude, - required this.summary, - required this.id, - }); + /// Create a new instance with the provided address data. + AddressDomain( + {required this.country, + required this.region, + required this.zone, + required this.woreda, + required this.city, + required this.subCity, + required this.longitude, + required this.latitude, + required this.summary, + required this.id}); + /// List of properties to check for equality. @override List get props => [ country, diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_availability_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_availability_domain.dart index 0e1af82..01ef06c 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_availability_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_availability_domain.dart @@ -1,13 +1,26 @@ import 'package:equatable/equatable.dart'; +/// Domain entity representing a hospital's availability schedule. class InstitutionAvailabilityDomain extends Equatable { - String startDay; - String endDay; - String opening; - String closing; - bool twentyFourHours; - String id; + /// Index of the start day of the schedule (0-6). + final String startDay; + /// Index of the end day of the schedule (0-6). + final String endDay; + + /// Opening time. + final String opening; + + /// Closing time. + final String closing; + + /// Whether open 24 hours. + final bool twentyFourHours; + + /// Unique identifier. + final String id; + + /// Create a new instance with provided availability data. InstitutionAvailabilityDomain({ required this.startDay, required this.endDay, @@ -17,8 +30,13 @@ class InstitutionAvailabilityDomain extends Equatable { required this.id, }); + /// Properties to check for equality. @override - List get props => [startDay, endDay, opening, closing, twentyFourHours, id]; + List get props => + [startDay, endDay, opening, closing, twentyFourHours, id]; + /// Convert to JSON. + /// + /// This base class returns an empty map. Subclasses should override to fully implement. toJson() {} -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_detail_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_detail_domain.dart index 07c0c00..51d76b0 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_detail_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_detail_domain.dart @@ -5,26 +5,63 @@ import 'hospital_address_domain.dart'; import 'hospital_availability_domain.dart'; import 'hospital_doctor_domain.dart'; +/// Domain entity representing detailed hospital data. class InstitutionDetailDomain extends Equatable { + /// Educational institutions associated with the hospital. List educationalInstitutions; + + /// Name of the hospital. String institutionName; + + /// Name of the hospital branch. String branchName; + + /// Website URL of the hospital. String website; + + /// Phone number of the hospital. String phoneNumber; + + /// Summary description of the hospital. String summary; + + /// Date when the hospital was established. DateTime establishedOn; + + /// Average rating for the hospital. double rate; + + /// Current status of the hospital. String status; + + /// URL of the hospital's logo image. String logoUrl; + + /// URL of the hospital's banner image. String bannerUrl; + + /// The hospital's availability schedule. InstitutionAvailabilityDomain institutionAvailability; + + /// Address of the hospital. AddressDomain address; + + /// List of services offered by the hospital. List services; + + /// List of photo URLs for the hospital. List photos; + + /// Doctors working at the hospital. List doctors; + + /// Unique ID of the hospital. String id; + + /// All specialities available at the hospital. List allSpecialities; + /// Create a new instance with the provided hospital data. InstitutionDetailDomain({ required this.allSpecialities, required this.educationalInstitutions, @@ -46,6 +83,7 @@ class InstitutionDetailDomain extends Equatable { required this.id, }); + /// Properties to check for equality. @override List get props => [ educationalInstitutions, diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_doctor_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_doctor_domain.dart index 1162647..a7428b5 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_doctor_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_doctor_domain.dart @@ -1,17 +1,38 @@ import 'package:equatable/equatable.dart'; +/// Domain entity representing a doctor. class DoctorDomain extends Equatable { + /// Full name of the doctor. final String fullName; + + /// Short description about the doctor. final String about; + + /// Gender of the doctor. final String gender; + + /// Email address of the doctor. final String? email; + + /// URL of the doctor's photo. final String photoUrl; + + /// Number of years of experience. final int yearsOfExperience; + + /// ID of the main institution the doctor works at. final String mainInstitutionId; + + /// Name of the main institution the doctor works at. final String mainInstitutionName; + + /// List of the doctor's specialities. final List specialities; + + /// Unique ID of the doctor. final String id; + /// Create a new instance with the provided doctor data. DoctorDomain({ required this.fullName, required this.about, @@ -25,6 +46,7 @@ class DoctorDomain extends Equatable { required this.id, }); + /// Properties to check for equality. @override List get props => [ fullName, @@ -39,5 +61,8 @@ class DoctorDomain extends Equatable { id, ]; + /// Convert to JSON. + /// + /// This base class returns an empty map. Subclasses should override to fully implement. toJson() {} } diff --git a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_search_domain.dart b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_search_domain.dart index 0621470..3f587a3 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_search_domain.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/entities/hospital_search_domain.dart @@ -2,22 +2,51 @@ import 'package:equatable/equatable.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_address_domain.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_availability_domain.dart'; +/// Domain entity representing summary hospital data. class InstitutionSearchDomain extends Equatable { - String institutionName; - String branchName; - String website; - String phoneNumber; - String summary; - DateTime establishedOn; - double rate; - String status; - String logoUrl; - String bannerUrl; - InstitutionAvailabilityDomain institutionAvailability; - AddressDomain address; - List services; - String id; + /// Name of the hospital. + final String institutionName; + /// Name of the hospital branch. + final String branchName; + + /// Website URL of the hospital. + final String website; + + /// Phone number of the hospital. + final String phoneNumber; + + /// Summary description of the hospital. + final String summary; + + /// Date when the hospital was established. + final DateTime establishedOn; + + /// Average rating for the hospital. + final double rate; + + /// Current status of the hospital. + final String status; + + /// URL of the hospital's logo image. + final String logoUrl; + + /// URL of the hospital's banner image. + final String bannerUrl; + + /// The hospital's availability schedule. + final InstitutionAvailabilityDomain institutionAvailability; + + /// Address of the hospital. + final AddressDomain address; + + /// List of services offered by the hospital. + final List services; + + /// Unique ID of the hospital. + final String id; + + /// Create a new instance with the provided hospital data. InstitutionSearchDomain({ required this.institutionName, required this.branchName, @@ -35,6 +64,7 @@ class InstitutionSearchDomain extends Equatable { required this.id, }); + /// Properties to check for equality. @override List get props => [ institutionName, diff --git a/hakim_hub_mobile/lib/features/hospital/domain/repositories/hospital_detail_repository.dart b/hakim_hub_mobile/lib/features/hospital/domain/repositories/hospital_detail_repository.dart index 7f5a53c..d9cffd3 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/repositories/hospital_detail_repository.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/repositories/hospital_detail_repository.dart @@ -5,10 +5,17 @@ import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_deta import 'package:dartz/dartz.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_doctor_domain.dart'; +/// Repository for fetching hospital detail data. abstract class HospitalDetailRepository { + /// Get the detailed data for a hospital by ID. + /// + /// Returns either a [Failure] or the [InstitutionDetailDomain] hospital data. Future> getHospitalDetail( String hospitalID); + /// Get a list of doctors filtered by the provided criteria. + /// + /// Returns either a [Failure] or a list of [DoctorDomain] matching the filter. Future>> getFilteredDoctors( - DoctorFilterDomain doctorFilterDomain); + DoctorFilterDomain filterCriteria); } diff --git a/hakim_hub_mobile/lib/features/hospital/domain/repositories/search_hospitals_repository.dart b/hakim_hub_mobile/lib/features/hospital/domain/repositories/search_hospitals_repository.dart index a9655cc..14c6211 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/repositories/search_hospitals_repository.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/repositories/search_hospitals_repository.dart @@ -5,12 +5,22 @@ import 'package:dartz/dartz.dart'; import '../entities/hospital_search_domain.dart'; - +/// Repository for searching and retrieving hospitals. abstract class HospitalsSearchRepository { - Future>> searchByFilterHospitals( - FilterHospitalDomain filterHospitalDomain); + /// Search for hospitals matching the provided filter criteria. + /// + /// Returns either a [Failure] or a list of [InstitutionSearchDomain] hospitals. + Future>> + searchByFilterHospitals(FilterHospitalDomain filterCriteria); + /// Search for hospitals by name. + /// + /// Returns either a [Failure] or a list of [InstitutionSearchDomain] hospitals. Future>> searchByNameHospitals( String name); + + /// Get all hospitals. + /// + /// Returns either a [Failure] or a list of all [InstitutionSearchDomain] hospitals. Future>> getAllHospitals(); -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_all_hospitals.dart b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_all_hospitals.dart index 7744f06..2a496f2 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_all_hospitals.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_all_hospitals.dart @@ -1,19 +1,26 @@ - - import 'package:dartz/dartz.dart'; - import '../../../../core/error/failures.dart'; import '../../../../core/usecases/usecase.dart'; import '../entities/hospital_search_domain.dart'; import '../repositories/search_hospitals_repository.dart'; -class GetAllHospitals implements UseCase, NoParams> { +/// Use case for retrieving all hospitals. +class GetAllHospitals + implements UseCase, NoParams> { + /// The repository to retrieve hospitals from. final HospitalsSearchRepository repository; + /// Create an instance that will get hospitals from the provided [repository]. GetAllHospitals(this.repository); + /// Execute this use case. + /// + /// Gets all hospitals from the [repository]. + /// + /// Returns either a [Failure] or the list of [InstitutionSearchDomain] hospitals. @override - Future>> call(NoParams noParams) async { + Future>> call( + NoParams noParams) async { return await repository.getAllHospitals(); } -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_doctor_by_filter.dart b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_doctor_by_filter.dart index 7384b91..5f2ff2f 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_doctor_by_filter.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_doctor_by_filter.dart @@ -5,15 +5,27 @@ import 'package:hakim_hub_mobile/features/hospital/domain/entities/filter_doctor import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_doctor_domain.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/repositories/hospital_detail_repository.dart'; +/// Use case for getting doctors by filter criteria. class GetDoctorByFilter implements UseCase, DoctorFilterDomain> { + /// The repository to retrieve doctors from. final HospitalDetailRepository repository; + /// Create an instance that will get doctors from the provided [repository]. GetDoctorByFilter(this.repository); + /// Execute this use case. + /// + /// Gets a list of doctors from the [repository] filtered by the provided criteria. + /// + /// Parameters: + /// filterCriteria: The criteria to filter doctors by. + /// + + /// Returns either a [Failure] or the list of [DoctorDomain] doctors. @override Future>> call( - DoctorFilterDomain params) async { - return await repository.getFilteredDoctors(params); + DoctorFilterDomain filterCriteria) async { + return await repository.getFilteredDoctors(filterCriteria); } } diff --git a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospital_detail.dart b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospital_detail.dart index 018abe7..f4f7573 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospital_detail.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospital_detail.dart @@ -4,11 +4,22 @@ import 'package:hakim_hub_mobile/core/usecases/usecase.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/entities/hospital_detail_domain.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/repositories/hospital_detail_repository.dart'; +/// Use case for getting detailed hospital data. class GetHospitalDetail implements UseCase { + /// The repository to retrieve hospital details from. final HospitalDetailRepository repository; + /// Create an instance that will get hospital details from the provided [repository]. GetHospitalDetail(this.repository); + /// Execute this use case. + /// + /// Gets the detailed hospital data from the [repository] for the provided ID. + /// + /// Parameters: + /// hospitalId: ID of the hospital to get details for. + /// + /// Returns either a [Failure] or the [InstitutionDetailDomain] hospital details. @override Future> call( String hospitalId) async { diff --git a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_filter.dart b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_filter.dart index 2f8af4c..9047c4c 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_filter.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_filter.dart @@ -1,6 +1,3 @@ - - - import 'package:dartz/dartz.dart'; import 'package:hakim_hub_mobile/features/hospital/domain/entities/filter_hospital_domain.dart'; @@ -9,13 +6,27 @@ import '../../../../core/usecases/usecase.dart'; import '../entities/hospital_search_domain.dart'; import '../repositories/search_hospitals_repository.dart'; -class GetHospitalsByFilter implements UseCase, FilterHospitalDomain> { +/// Use case for searching hospitals by filter criteria. +class GetHospitalsByFilter + implements UseCase, FilterHospitalDomain> { + /// The repository to search for hospitals. final HospitalsSearchRepository repository; + /// Create an instance that will search in the provided [repository]. GetHospitalsByFilter(this.repository); + /// Execute this use case. + /// + /// Searches for hospitals in the [repository] based on the provided filter criteria. + /// + /// Parameters: + /// filterCriteria: Criteria to filter hospitals by. + /// + /// Returns either a [Failure] or a list of [InstitutionSearchDomain] hospitals. + @override - Future>> call(FilterHospitalDomain params) async { - return await repository.searchByFilterHospitals(params); + Future>> call( + FilterHospitalDomain filterCriteria) async { + return await repository.searchByFilterHospitals(filterCriteria); } -} \ No newline at end of file +} diff --git a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_name.dart b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_name.dart index 67a7d10..7ce92d5 100644 --- a/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_name.dart +++ b/hakim_hub_mobile/lib/features/hospital/domain/usecases/get_hospitals_by_name.dart @@ -1,18 +1,29 @@ - import 'package:dartz/dartz.dart'; - import '../../../../core/error/failures.dart'; import '../../../../core/usecases/usecase.dart'; import '../entities/hospital_search_domain.dart'; import '../repositories/search_hospitals_repository.dart'; -class GetHospitalsByName implements UseCase, String> { +/// Use case for searching hospitals by name. +class GetHospitalsByName + implements UseCase, String> { + /// The repository to search for hospitals. final HospitalsSearchRepository repository; + /// Create an instance that will search in the provided [repository]. GetHospitalsByName(this.repository); + /// Execute this use case. + /// + /// Searches for hospitals by name in the [repository]. + /// + /// Parameters: + /// name: Name to search hospitals by. + /// + /// Returns either a [Failure] or a list of [InstitutionSearchDomain] hospitals. @override - Future>> call(String params) async { - return await repository.searchByNameHospitals(params); + Future>> call( + String name) async { + return await repository.searchByNameHospitals(name); } -} \ No newline at end of file +}