From c86f7dcf5a67c5200ec20407b592ee9a627d91dd Mon Sep 17 00:00:00 2001 From: Eldar2021 Date: Tue, 8 Oct 2024 20:49:08 +0600 Subject: [PATCH] added namaz time --- .../home/presentation/view/home_view.dart | 2 +- .../widgets/pray_time_widget.dart | 2 +- app/lib/modules/namaz_time/data/data.dart | 2 +- .../model/namaz_times_model_response.dart | 54 +++++++++++ ...dart => namaz_times_model_response.g.dart} | 33 ++++--- .../data/model/namaz_times_response.dart | 95 ------------------- .../namaz_times_repository_impl.dart | 16 +++- .../domain/entity/namaz_time_entity.dart | 27 ++++-- .../namaz_time/presentation/presentation.dart | 4 +- .../presentation/view/choose_city_view.dart | 53 +++++++++++ .../view/choose_continent_view.dart | 51 ++++++++++ ...ons_view.dart => choose_regions_view.dart} | 8 +- .../presentation/view/namaz_time_view.dart | 48 ++++++---- 13 files changed, 244 insertions(+), 151 deletions(-) create mode 100644 app/lib/modules/namaz_time/data/model/namaz_times_model_response.dart rename app/lib/modules/namaz_time/data/model/{namaz_times_response.g.dart => namaz_times_model_response.g.dart} (65%) delete mode 100644 app/lib/modules/namaz_time/data/model/namaz_times_response.dart create mode 100644 app/lib/modules/namaz_time/presentation/view/choose_city_view.dart create mode 100644 app/lib/modules/namaz_time/presentation/view/choose_continent_view.dart rename app/lib/modules/namaz_time/presentation/view/{regions_view.dart => choose_regions_view.dart} (81%) diff --git a/app/lib/modules/home/presentation/view/home_view.dart b/app/lib/modules/home/presentation/view/home_view.dart index 730122a0..dd9b4331 100644 --- a/app/lib/modules/home/presentation/view/home_view.dart +++ b/app/lib/modules/home/presentation/view/home_view.dart @@ -64,7 +64,7 @@ class _HomeViewState extends State { Navigator.push( context, MaterialPageRoute( - builder: (BuildContext context) => const NamazTimeView(), + builder: (BuildContext context) => const ChooseContinentView(), ), ); }, diff --git a/app/lib/modules/home/presentation/widgets/pray_time_widget.dart b/app/lib/modules/home/presentation/widgets/pray_time_widget.dart index 6e71c819..e5be2627 100644 --- a/app/lib/modules/home/presentation/widgets/pray_time_widget.dart +++ b/app/lib/modules/home/presentation/widgets/pray_time_widget.dart @@ -111,7 +111,7 @@ class _PrayTimeWidgetState extends State { onTap: () => Navigator.push( context, MaterialPageRoute( - builder: (BuildContext context) => const NamazTimeView(), + builder: (BuildContext context) => const ChooseContinentView(), ), ), child: SizedBox( diff --git a/app/lib/modules/namaz_time/data/data.dart b/app/lib/modules/namaz_time/data/data.dart index ef4a1747..37437125 100644 --- a/app/lib/modules/namaz_time/data/data.dart +++ b/app/lib/modules/namaz_time/data/data.dart @@ -1,6 +1,6 @@ export 'source/namaz_times_local_data_source.dart'; export 'source/namaz_times_remote_data_source.dart'; export 'source/remote/namaz_time_remote_data_source_impl.dart'; -export 'model/namaz_times_response.dart'; +export 'model/namaz_times_model_response.dart'; export 'model/continent_model_response.dart'; export 'model/region_model_response.dart'; diff --git a/app/lib/modules/namaz_time/data/model/namaz_times_model_response.dart b/app/lib/modules/namaz_time/data/model/namaz_times_model_response.dart new file mode 100644 index 00000000..4cf23465 --- /dev/null +++ b/app/lib/modules/namaz_time/data/model/namaz_times_model_response.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'namaz_times_model_response.g.dart'; + +@JsonSerializable() +@immutable +class NamazTimesResponse { + const NamazTimesResponse({ + required this.id, + this.title, + this.titleRu, + this.titleEn, + this.lat, + this.lon, + this.bagymdatOffset, + this.sunriseOffset, + this.zuhrOffset, + this.asrOffset, + this.magribOffset, + this.ishaOffset, + this.useFormula, + this.validUntil, + this.startDateTz, + this.startDateSecondTz, + this.timezone, + this.secondTimezone, + this.times, + }); + + factory NamazTimesResponse.fromJson(Map json) => _$NamazTimesResponseFromJson(json); + + Map toJson() => _$NamazTimesResponseToJson(this); + + final int id; + final String? title; + final String? titleRu; + final String? titleEn; + final double? lat; + final double? lon; + final int? bagymdatOffset; + final int? sunriseOffset; + final int? zuhrOffset; + final int? asrOffset; + final int? magribOffset; + final int? ishaOffset; + final int? useFormula; + final String? validUntil; + final String? startDateTz; + final String? startDateSecondTz; + final int? timezone; + final int? secondTimezone; + final Map>? times; +} diff --git a/app/lib/modules/namaz_time/data/model/namaz_times_response.g.dart b/app/lib/modules/namaz_time/data/model/namaz_times_model_response.g.dart similarity index 65% rename from app/lib/modules/namaz_time/data/model/namaz_times_response.g.dart rename to app/lib/modules/namaz_time/data/model/namaz_times_model_response.g.dart index 7bde71e2..b66c1c2a 100644 --- a/app/lib/modules/namaz_time/data/model/namaz_times_response.g.dart +++ b/app/lib/modules/namaz_time/data/model/namaz_times_model_response.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'namaz_times_response.dart'; +part of 'namaz_times_model_response.dart'; // ************************************************************************** // JsonSerializableGenerator @@ -9,10 +9,7 @@ part of 'namaz_times_response.dart'; NamazTimesResponse _$NamazTimesResponseFromJson(Map json) => NamazTimesResponse( id: (json['id'] as num).toInt(), - title: json['title'] as String, - subLocations: (json['subLocations'] as List?) - ?.map((e) => SubLocation.fromJson(e as Map)) - .toList(), + title: json['title'] as String?, titleRu: json['titleRu'] as String?, titleEn: json['titleEn'] as String?, lat: (json['lat'] as num?)?.toDouble(), @@ -23,15 +20,16 @@ NamazTimesResponse _$NamazTimesResponseFromJson(Map json) => asrOffset: (json['asrOffset'] as num?)?.toInt(), magribOffset: (json['magribOffset'] as num?)?.toInt(), ishaOffset: (json['ishaOffset'] as num?)?.toInt(), - useFormula: json['useFormula'] as bool?, - startDateTz: json['startDateTz'] == null - ? null - : DateTime.parse(json['startDateTz'] as String), - startDateSecondTz: json['startDateSecondTz'] == null - ? null - : DateTime.parse(json['startDateSecondTz'] as String), - timezone: json['timezone'] as String?, - secondTimezone: json['secondTimezone'] as String?, + useFormula: (json['useFormula'] as num?)?.toInt(), + validUntil: json['validUntil'] as String?, + startDateTz: json['startDateTz'] as String?, + startDateSecondTz: json['startDateSecondTz'] as String?, + timezone: (json['timezone'] as num?)?.toInt(), + secondTimezone: (json['secondTimezone'] as num?)?.toInt(), + times: (json['times'] as Map?)?.map( + (k, e) => + MapEntry(k, (e as List).map((e) => e as String).toList()), + ), ); Map _$NamazTimesResponseToJson(NamazTimesResponse instance) => @@ -49,9 +47,10 @@ Map _$NamazTimesResponseToJson(NamazTimesResponse instance) => 'magribOffset': instance.magribOffset, 'ishaOffset': instance.ishaOffset, 'useFormula': instance.useFormula, - 'startDateTz': instance.startDateTz?.toIso8601String(), - 'startDateSecondTz': instance.startDateSecondTz?.toIso8601String(), + 'validUntil': instance.validUntil, + 'startDateTz': instance.startDateTz, + 'startDateSecondTz': instance.startDateSecondTz, 'timezone': instance.timezone, 'secondTimezone': instance.secondTimezone, - 'subLocations': instance.subLocations, + 'times': instance.times, }; diff --git a/app/lib/modules/namaz_time/data/model/namaz_times_response.dart b/app/lib/modules/namaz_time/data/model/namaz_times_response.dart deleted file mode 100644 index 23c197fc..00000000 --- a/app/lib/modules/namaz_time/data/model/namaz_times_response.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'namaz_times_response.g.dart'; - -@JsonSerializable() -@immutable -class NamazTimesResponse { - const NamazTimesResponse({ - required this.id, - required this.title, - this.subLocations, - this.titleRu, - this.titleEn, - this.lat, - this.lon, - this.bagymdatOffset, - this.sunriseOffset, - this.zuhrOffset, - this.asrOffset, - this.magribOffset, - this.ishaOffset, - this.useFormula, - this.startDateTz, - this.startDateSecondTz, - this.timezone, - this.secondTimezone, - }); - - factory NamazTimesResponse.fromJson(Map json) => _$NamazTimesResponseFromJson(json); - - Map toJson() => _$NamazTimesResponseToJson(this); - final int id; - final String title; - final String? titleRu; - final String? titleEn; - final double? lat; - final double? lon; - final int? bagymdatOffset; - final int? sunriseOffset; - final int? zuhrOffset; - final int? asrOffset; - final int? magribOffset; - final int? ishaOffset; - final bool? useFormula; - final DateTime? startDateTz; - final DateTime? startDateSecondTz; - final String? timezone; - final String? secondTimezone; - final List? subLocations; -} - -class SubLocation { - SubLocation({ - required this.id, - required this.title, - required this.titleRu, - required this.titleEn, - required this.parentId, - required this.createdAt, - required this.updatedAt, - }); - - factory SubLocation.fromJson(Map json) { - return SubLocation( - id: (json['id'] as num?)?.toInt() ?? 0, - title: json['title'] as String, - titleRu: json['title_ru'] as String, - titleEn: json['title_en'] as String, - parentId: (json['parent_id'] as num?)?.toInt() ?? 0, - createdAt: DateTime.parse(json['created_at'] as String), - updatedAt: DateTime.parse(json['updated_at'] as String), - ); - } - - final int id; - final String title; - final String titleRu; - final String titleEn; - final int parentId; - final DateTime createdAt; - final DateTime updatedAt; - - Map toJson() { - return { - 'id': id, - 'title': title, - 'title_ru': titleRu, - 'title_en': titleEn, - 'parent_id': parentId, - 'created_at': createdAt.toIso8601String(), - 'updated_at': updatedAt.toIso8601String(), - }; - } -} diff --git a/app/lib/modules/namaz_time/data/repository/namaz_times_repository_impl.dart b/app/lib/modules/namaz_time/data/repository/namaz_times_repository_impl.dart index 32421ef3..2f1f1a0e 100644 --- a/app/lib/modules/namaz_time/data/repository/namaz_times_repository_impl.dart +++ b/app/lib/modules/namaz_time/data/repository/namaz_times_repository_impl.dart @@ -30,9 +30,14 @@ final class NamazTimesRepositoryImpl implements NamazTimesRepository { asrOffset: 1, magribOffset: 1, ishaOffset: 1, - timezone: ' 1', id: 1, - subLocations: [], + useFormula: 1, + validUntil: '', + startDateTz: '', + startDateSecondTz: '', + timezone: 1, + secondTimezone: 1, + times: {}, ); } } @@ -52,7 +57,12 @@ final class NamazTimesRepositoryImpl implements NamazTimesRepository { ishaOffset: response.ishaOffset, timezone: response.timezone, id: response.id, - subLocations: response.subLocations ?? [], + useFormula: response.useFormula, + validUntil: response.validUntil, + startDateTz: response.startDateTz, + startDateSecondTz: response.startDateSecondTz, + secondTimezone: response.secondTimezone, + times: response.times, ); } diff --git a/app/lib/modules/namaz_time/domain/entity/namaz_time_entity.dart b/app/lib/modules/namaz_time/domain/entity/namaz_time_entity.dart index e5224831..6b501d1b 100644 --- a/app/lib/modules/namaz_time/domain/entity/namaz_time_entity.dart +++ b/app/lib/modules/namaz_time/domain/entity/namaz_time_entity.dart @@ -1,12 +1,11 @@ +import 'package:intl/intl.dart'; import 'package:meta/meta.dart'; -import 'package:my_quran/modules/namaz_time/data/model/namaz_times_response.dart'; @immutable final class NamazTimesEntity { const NamazTimesEntity({ required this.id, - required this.title, - required this.subLocations, + this.title, this.titleRu, this.titleEn, this.lat, @@ -18,14 +17,16 @@ final class NamazTimesEntity { this.magribOffset, this.ishaOffset, this.useFormula, + this.validUntil, this.startDateTz, this.startDateSecondTz, this.timezone, this.secondTimezone, + this.times, }); final int id; - final String title; + final String? title; final String? titleRu; final String? titleEn; final double? lat; @@ -36,10 +37,16 @@ final class NamazTimesEntity { final int? asrOffset; final int? magribOffset; final int? ishaOffset; - final bool? useFormula; - final DateTime? startDateTz; - final DateTime? startDateSecondTz; - final String? timezone; - final String? secondTimezone; - final List subLocations; + final int? useFormula; + final String? validUntil; + final String? startDateTz; + final String? startDateSecondTz; + final int? timezone; + final int? secondTimezone; + final Map>? times; + + List? getTodaysTimes() { + final today = DateFormat('dd.MM').format(DateTime.now()); + return times![today]; + } } diff --git a/app/lib/modules/namaz_time/presentation/presentation.dart b/app/lib/modules/namaz_time/presentation/presentation.dart index 7b769743..fe81d16d 100644 --- a/app/lib/modules/namaz_time/presentation/presentation.dart +++ b/app/lib/modules/namaz_time/presentation/presentation.dart @@ -1,3 +1,5 @@ export 'cubit/namaz_time_cubit.dart'; +export 'view/choose_continent_view.dart'; +export 'view/choose_regions_view.dart'; +export 'view/choose_city_view.dart'; export 'view/namaz_time_view.dart'; -export 'view/regions_view.dart'; diff --git a/app/lib/modules/namaz_time/presentation/view/choose_city_view.dart b/app/lib/modules/namaz_time/presentation/view/choose_city_view.dart new file mode 100644 index 00000000..81856bbd --- /dev/null +++ b/app/lib/modules/namaz_time/presentation/view/choose_city_view.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:my_quran/core/core.dart'; +import 'package:my_quran/modules/modules.dart'; + +class CityView extends StatelessWidget { + const CityView({required this.regionId, super.key}); + + final int regionId; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('City'), + ), + body: BlocProvider( + create: (context) => context.read()..getRegions(regionId), + child: BlocBuilder( + builder: (context, state) { + if (state.status == FetchStatus.loading) { + return const Center(child: CircularProgressIndicator()); + } else if (state.status == FetchStatus.error) { + return const Center(child: Text('Error fetching regions.')); + } else if (state.status == FetchStatus.success) { + final regions = state.regionsEntity?.list ?? []; + + return ListView.builder( + itemCount: regions.length, + itemBuilder: (context, index) { + final region = regions[index]; + return ListTile( + title: Text(region.title ?? ''), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => NamazTimeView(cityId: region.id), + ), + ); + // context.read().getRegions(region.id); + }, + ); + }, + ); + } + return const Center(child: Text('No regions found.')); + }, + ), + ), + ); + } +} diff --git a/app/lib/modules/namaz_time/presentation/view/choose_continent_view.dart b/app/lib/modules/namaz_time/presentation/view/choose_continent_view.dart new file mode 100644 index 00000000..00211af5 --- /dev/null +++ b/app/lib/modules/namaz_time/presentation/view/choose_continent_view.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:my_quran/core/core.dart'; +import 'package:my_quran/modules/modules.dart'; + +class ChooseContinentView extends StatelessWidget { + const ChooseContinentView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Шаар тандоо')), + body: BlocProvider( + create: (context) => context.read()..getContinents(), + child: BlocBuilder( + builder: (context, state) { + if (state.status == FetchStatus.loading) { + return const Center(child: CircularProgressIndicator()); + } else if (state.status == FetchStatus.success) { + final continentsList = state.continentsEntity?.list; + if (continentsList == null || continentsList.isEmpty) { + return const Center(child: Text('No continents found.')); + } + + return ListView.builder( + itemCount: continentsList.length, + itemBuilder: (context, index) { + final continent = continentsList[index]; + return ListTile( + title: Text(continent.title ?? 'Unknown'), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => RegionsView(continentId: continent.id), + ), + ); + }, + ); + }, + ); + } else if (state.status == FetchStatus.error) { + return const Center(child: Text('Error getting namaz times.')); + } + return const Center(child: Text('Unexpected state.')); + }, + ), + ), + ); + } +} diff --git a/app/lib/modules/namaz_time/presentation/view/regions_view.dart b/app/lib/modules/namaz_time/presentation/view/choose_regions_view.dart similarity index 81% rename from app/lib/modules/namaz_time/presentation/view/regions_view.dart rename to app/lib/modules/namaz_time/presentation/view/choose_regions_view.dart index 9d199007..8dfe2ac7 100644 --- a/app/lib/modules/namaz_time/presentation/view/regions_view.dart +++ b/app/lib/modules/namaz_time/presentation/view/choose_regions_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:my_quran/core/core.dart'; import 'package:my_quran/modules/modules.dart'; +import 'package:my_quran/modules/namaz_time/presentation/view/choose_city_view.dart'; class RegionsView extends StatelessWidget { const RegionsView({required this.continentId, super.key}); @@ -32,7 +33,12 @@ class RegionsView extends StatelessWidget { return ListTile( title: Text(region.title ?? ''), onTap: () { - context.read().getRegions(region.id); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CityView(regionId: region.id), + ), + ); }, ); }, diff --git a/app/lib/modules/namaz_time/presentation/view/namaz_time_view.dart b/app/lib/modules/namaz_time/presentation/view/namaz_time_view.dart index b3bba1fd..aa5a52df 100644 --- a/app/lib/modules/namaz_time/presentation/view/namaz_time_view.dart +++ b/app/lib/modules/namaz_time/presentation/view/namaz_time_view.dart @@ -1,49 +1,55 @@ import 'package:flutter/material.dart'; + import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:my_quran/core/core.dart'; import 'package:my_quran/modules/modules.dart'; class NamazTimeView extends StatelessWidget { - const NamazTimeView({super.key}); + const NamazTimeView({required this.cityId, super.key}); + + final int cityId; @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text('Шаар тандоо')), + appBar: AppBar( + title: const Text("Today's Namaz Times"), + ), body: BlocProvider( - create: (context) => context.read()..getContinents(), + create: (context) => context.read()..getNamazTimes(cityId), child: BlocBuilder( builder: (context, state) { if (state.status == FetchStatus.loading) { return const Center(child: CircularProgressIndicator()); + } else if (state.status == FetchStatus.error) { + return const Center(child: Text('Error fetching Namaz times.')); } else if (state.status == FetchStatus.success) { - // Check if continentsEntity is not null and has a list - final continentsList = state.continentsEntity?.list; - if (continentsList == null || continentsList.isEmpty) { - return const Center(child: Text('No continents found.')); + final namazTime = state.namazTimesModel; + final todayTimes = namazTime?.getTodaysTimes(); + + if (todayTimes == null) { + return const Center(child: Text('No Namaz times available for today.')); } + final prayerNames = [ + 'Fajr', + 'Sunrise', + 'Dhuhr', + 'Asr', + 'Maghrib', + 'Isha', + ]; return ListView.builder( - itemCount: continentsList.length, + itemCount: prayerNames.length, itemBuilder: (context, index) { - final continent = continentsList[index]; return ListTile( - title: Text(continent.title ?? 'Unknown'), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => RegionsView(continentId: continent.id), - ), - ); - }, + title: Text(prayerNames[index]), + trailing: Text(todayTimes[index]), ); }, ); - } else if (state.status == FetchStatus.error) { - return const Center(child: Text('Error getting namaz times.')); } - return const Center(child: Text('Unexpected state.')); + return const Center(child: Text('No Namaz times available.')); }, ), ),