diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..de26301 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dart.flutterSdkPath": "D:\\pooja\\fluttersdk\\flutter_3.22.2\\flutter" +} \ No newline at end of file diff --git a/assets/images/welcome_screen/svg/tanamibg.svg b/assets/images/welcome_screen/svg/tanamibg.svg new file mode 100644 index 0000000..f19115f --- /dev/null +++ b/assets/images/welcome_screen/svg/tanamibg.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Api_Helper/base_manager.dart b/lib/Api_Helper/base_manager.dart new file mode 100644 index 0000000..a8bae41 --- /dev/null +++ b/lib/Api_Helper/base_manager.dart @@ -0,0 +1,18 @@ +class ResponseData { + ResponseData(this.message, this.status, {this.data}); + + final T? data; + final String message; + final ResponseStatus status; + + @override + String toString() => message; +} + +enum ResponseStatus { + SUCCESS, + + FAILED, + + PRIVATE, +} diff --git a/lib/core/styles/app_images.dart b/lib/core/styles/app_images.dart index a885969..7990c31 100644 --- a/lib/core/styles/app_images.dart +++ b/lib/core/styles/app_images.dart @@ -1,7 +1,7 @@ class AppImages { //Splash static const String splashBg = - "assets/images/welcome_screen/svg/Splash_BG.svg"; + "assets/images/welcome_screen/svg/tanamibg.svg"; static const String splashLogo = "assets/images/welcome_screen/svg/Tanami_Capital_Splash_Logo.svg"; diff --git a/lib/domain/model/GetCountry_model.dart b/lib/domain/model/GetCountry_model.dart new file mode 100644 index 0000000..78638a3 --- /dev/null +++ b/lib/domain/model/GetCountry_model.dart @@ -0,0 +1,72 @@ +class GetCountryModel { + List? data; + + GetCountryModel({ this.data}); + + GetCountryModel.fromJson(Map json) { + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data!.add(new Data.fromJson(v)); + }); + } + + } + + Map toJson() { + final Map data = new Map(); + if (this.data != null) { + data['data'] = this.data!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Data { + String? id; + String? countryName; + String? countryCode; + String? isdCode; + String? flagIcon; + Null? currencyXid; + bool? isActive; + Null? createdBy; + Null? modifiedBy; + + Data( + {this.id, + this.countryName, + this.countryCode, + this.isdCode, + this.flagIcon, + this.currencyXid, + this.isActive, + this.createdBy, + this.modifiedBy}); + + Data.fromJson(Map json) { + id = json['id']; + countryName = json['countryName']; + countryCode = json['countryCode']; + isdCode = json['isdCode']; + flagIcon = json['flagIcon']; + currencyXid = json['currency_xid']; + isActive = json['isActive']; + createdBy = json['createdBy']; + modifiedBy = json['modifiedBy']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['countryName'] = this.countryName; + data['countryCode'] = this.countryCode; + data['isdCode'] = this.isdCode; + data['flagIcon'] = this.flagIcon; + data['currency_xid'] = this.currencyXid; + data['isActive'] = this.isActive; + data['createdBy'] = this.createdBy; + data['modifiedBy'] = this.modifiedBy; + return data; + } +} diff --git a/lib/features/countrySelection/presentation/bloc/GetCountry/GetCountryAPI.dart b/lib/features/countrySelection/presentation/bloc/GetCountry/GetCountryAPI.dart new file mode 100644 index 0000000..7cc0a8b --- /dev/null +++ b/lib/features/countrySelection/presentation/bloc/GetCountry/GetCountryAPI.dart @@ -0,0 +1,15 @@ + +import '../../../../../Api_Helper/base_manager.dart'; +import '../../../../../shared/api/api_endpoints.dart'; +import '../../../../../shared/api/network_api_services.dart'; + +class GetCountryAPI { + GetCountryAPI(); + Future getcountryAPI() async { + String url=ApiEndpoints.getcountryurl; + final response = await NetworkApiService().get( + url, + ); + return response; + } +} \ No newline at end of file diff --git a/lib/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart b/lib/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart new file mode 100644 index 0000000..564c41c --- /dev/null +++ b/lib/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart @@ -0,0 +1,30 @@ +import 'package:bloc/bloc.dart'; +import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart'; + +import '../../../../../Api_Helper/base_manager.dart'; +import '../../../../../domain/model/GetCountry_model.dart'; +import 'GetCountryAPI.dart'; + + +class GetCountryBlock extends Bloc { + GetCountryBlock() : super(CountryInitial()) { + on(mapEventToState); + } + Future mapEventToState( + GetCountry event, Emitter emit) async { + if (event is GetCountry) { + emit(CountryLoading()); + try { + ResponseData response = await GetCountryAPI().getcountryAPI(); + if (response.status == ResponseStatus.SUCCESS) { + GetCountryModel countryModel = + GetCountryModel.fromJson(response.data); + emit(CountryLoaded(countryModel)); + } + print("//"); + } catch (e) { + emit(CountryError("Oops Something went wrong")); + } + } + } +} diff --git a/lib/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart b/lib/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart new file mode 100644 index 0000000..bc6bb65 --- /dev/null +++ b/lib/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart @@ -0,0 +1,31 @@ +import '../../../../../domain/model/GetCountry_model.dart'; + +abstract class GetCountryEvent { + const GetCountryEvent(); + + get props => []; +} + +class GetCountry extends GetCountryEvent { + GetCountry(); + + +} +abstract class GetCountryState{} +// Define states +//enum GetCountryState { initial, loading, success, failure, error } +class CountryInitial extends GetCountryState {} + +class CountryLoading extends GetCountryState {} + +class CountryLoaded extends GetCountryState { + final GetCountryModel countryModel; + + CountryLoaded(this.countryModel); +} + +class CountryError extends GetCountryState { + final String message; + + CountryError(this.message); +} \ No newline at end of file diff --git a/lib/features/countrySelection/presentation/widgets/country_selection_list.dart b/lib/features/countrySelection/presentation/widgets/country_selection_list.dart index 4c31feb..db26358 100644 --- a/lib/features/countrySelection/presentation/widgets/country_selection_list.dart +++ b/lib/features/countrySelection/presentation/widgets/country_selection_list.dart @@ -3,6 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:gap/gap.dart'; import 'package:tanami_app/core/styles/app_color.dart'; import 'package:tanami_app/core/utils/constant/country_flag_data.dart'; +import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart'; +import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; import '../bloc/choose_country_bloc.dart'; @@ -15,6 +17,56 @@ class CountrySelectionList extends StatelessWidget { @override Widget build(BuildContext context) { final radioBloc = context.read(); + /* return BlocConsumer( + listener: (context, state) { + /* if (state == GetCountryState.success) { + const SnackBar(content: Text("Successfully fetch")); + } else if (state == GetCountryState.error) { + const SnackBar(content: Text(" error")); + } else { + const SnackBar(content: Text(" not fetch")); + } */ + }, builder: (context, state) { + print(state); + if (state is CountryLoading) { + return Center(child: CircularProgressIndicator()); + } else if (state is CountryLoaded) { + return ListView.builder( + itemCount: state.countryModel.data?.length ?? 0, + itemBuilder: (context, index) { + var country = state.countryModel.data![index]; + return ListTile( + title: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Adjust according to how you handle flags + Image.asset( + countryFlag[index], + width: 24, + height: 24, + ), + const SizedBox(width: 10), + Text(country.countryName ?? ''), + ], + ), + leading: Radio( + activeColor: Colors.blue, + value: index, + groupValue: -1, // You can update this to manage selected index + onChanged: (int? value) { + // Handle radio button change + }, + ), + ); + }, + ); + } else if (state is CountryError) { + return Center(child: Text(state.message)); + } else { + return Center(child: Text('Press button to fetch country data')); + } + }); */ + return BlocBuilder( builder: (context, state) { int selectedIndex = -1; @@ -22,35 +74,60 @@ class CountrySelectionList extends StatelessWidget { selectedIndex = state.selectedIndex; } - return Column( - children: List.generate(countryFlag.length, (int index) { - return ListTile( - title: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.asset( - countryFlag[index], - width: 24, - height: 24, + return BlocConsumer( + listener: (context, state) { + if (state == CountryLoaded) { + const SnackBar(content: Text("Successfully fetch")); + } else if (state == CountryError) { + const SnackBar(content: Text("error while fetching data")); + Future.delayed(Duration(milliseconds: 3), () { + context.read().add(GetCountry()); + }); + } else { + const SnackBar(content: Text(" not fetch")); + } + }, builder: (context, state) { + print(state); + if (state is CountryLoading) { + return Center(child: CircularProgressIndicator()); + } else if (state is CountryLoaded) { + return ListView.builder( + itemCount: state.countryModel.data?.length ?? 0, + itemBuilder: (context, index) { + var country = state.countryModel.data![index]; + return ListTile( + title: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + countryFlag[index], + width: 24, + height: 24, + ), + const Gap(10), + TextWidget().text14W500(country.countryName.toString(), + clr: AppColor.charcoalColor), + ], ), - const Gap(10), - TextWidget().text14W500(countryName[index], - clr: AppColor.charcoalColor), - ], - ), - leading: Radio( - activeColor: AppColor.radioActiveColor, - value: index, - groupValue: selectedIndex, - onChanged: (int? value) { - if (value != null) { - radioBloc.add(RadioSelected(value)); - } - }, - ), + leading: Radio( + activeColor: AppColor.radioActiveColor, + value: index, + groupValue: selectedIndex, + onChanged: (int? value) { + if (value != null) { + radioBloc.add(RadioSelected(value)); + } + }, + ), + ); + }, ); - }), - ); + } else if (state is CountryError) { + return Center(child: Text(state.message)); + } else { + return Center(child: Text('Press button to fetch country data')); + } + }); }, ); } diff --git a/lib/features/splash/presentation/pages/splash_layout.dart b/lib/features/splash/presentation/pages/splash_layout.dart index 3b7dd46..d34acf7 100644 --- a/lib/features/splash/presentation/pages/splash_layout.dart +++ b/lib/features/splash/presentation/pages/splash_layout.dart @@ -25,7 +25,7 @@ class SplashLayout extends StatelessWidget { fit: BoxFit.cover, ), ), - Positioned.fill( + /* Positioned.fill( child: Align( alignment: Alignment.center, child: SvgPicture.asset( @@ -39,7 +39,7 @@ class SplashLayout extends StatelessWidget { alignment: Alignment.bottomCenter, child: BottomVersionWidget(), ), - ), + ), */ ], ), ), diff --git a/lib/features/welcome/presentation/widgets/login_signup_button.dart b/lib/features/welcome/presentation/widgets/login_signup_button.dart index 8a59018..7770381 100644 --- a/lib/features/welcome/presentation/widgets/login_signup_button.dart +++ b/lib/features/welcome/presentation/widgets/login_signup_button.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:gap/gap.dart'; import 'package:tanami_app/core/routes/route_name.dart'; import 'package:tanami_app/core/routes/routes.dart'; import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart'; +import 'package:tanami_app/features/countrySelection/presentation/bloc/GetCountry/getcountryevent_bloc.dart'; import 'package:tanami_app/shared/components/button_widget.dart'; import '../../../../core/styles/app_text.dart'; @@ -28,6 +31,7 @@ class LoginSignUpButton extends StatelessWidget { height: 56.h, child: ButtonWidget().elevatedBtn( function: () { + context.read().add(GetCountry()); goRouter.goNamed(RouteName.registerStepScreen, pathParameters: { "fromScreentype": "welcome", }); diff --git a/lib/main.dart b/lib/main.dart index 81353c2..0bfa343 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,6 +11,7 @@ import 'core/utils/language/localizations_delegate.dart'; import 'core/utils/secure/secure_storage_service.dart'; import 'features/biometric/presentation/bloc/biometric_bloc.dart'; import 'features/biometric/presentation/bloc/biometric_event.dart'; +import 'features/countrySelection/presentation/bloc/GetCountry/getcountry_bloc.dart'; import 'features/countrySelection/presentation/bloc/choose_country_bloc.dart'; import 'shared/components/bloc/bottom_nav_bar/bottom_navigation_bloc.dart'; import 'shared/components/bloc/language/lng_bloc.dart'; @@ -98,6 +99,12 @@ class _MyAppState extends State with WidgetsBindingObserver { create: (_) => BiometricBloc(LocalAuthentication())..add(CheckBiometricEvent()), ), + BlocProvider( + create: (_) => LocalizationBloc(), + ), + BlocProvider( + create: (_) => GetCountryBlock(), + ), ], child: ScreenUtilInit( builder: (BuildContext context, Widget? child) => diff --git a/lib/shared/api/api_endpoints.dart b/lib/shared/api/api_endpoints.dart index 99d024a..800a206 100644 --- a/lib/shared/api/api_endpoints.dart +++ b/lib/shared/api/api_endpoints.dart @@ -1,3 +1,6 @@ class ApiEndpoints { - static const base = ""; //App Base url + static const baseurl = + "https://tanami.betadelivery.com/api/development/v1/"; //App Base url + + static const getcountryurl = baseurl + "country/getAllCountry"; } diff --git a/lib/shared/api/commonAPI.dart b/lib/shared/api/commonAPI.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/shared/api/network_api_services.dart b/lib/shared/api/network_api_services.dart index c8336b6..b3a486a 100644 --- a/lib/shared/api/network_api_services.dart +++ b/lib/shared/api/network_api_services.dart @@ -1,42 +1,63 @@ // common_api.dart import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; + +import '../../Api_Helper/base_manager.dart'; class NetworkApiService { final Dio _dio = Dio(); // Common function for GET requests - Future get(String endpoint, + Future get(String url, {Map? queryParameters}) async { + if (kDebugMode) { + print("api url is >>> $url"); + } + Response response; try { - return await _dio.get(endpoint, queryParameters: queryParameters); + response = await _dio.get(url); + if (response.statusCode == 201 || response.statusCode == 200) { + return ResponseData("success", ResponseStatus.SUCCESS, + data: response.data); + } else { + try { + return ResponseData( + response.data['message'].toString(), ResponseStatus.FAILED); + } catch (_) { + return ResponseData( + data: response.data, + response.statusMessage!, + ResponseStatus.FAILED); + }} } catch (e) { - throw _handleError(e); + return ResponseData( + "Something went wrong", ResponseStatus.FAILED); } } // Common function for POST requests - Future post(String endpoint, dynamic data) async { + Future post(String url, dynamic data) async { try { - return await _dio.post(endpoint, data: data); + return await _dio.post(url, data: data); } catch (e) { throw _handleError(e); } } // Common function for PUT requests - Future put(String endpoint, dynamic data) async { + Future put(String url, dynamic data) async { try { - return await _dio.put(endpoint, data: data); + return await _dio.put(url, data: data); } catch (e) { throw _handleError(e); } } // Common function for DELETE requests - Future delete(String endpoint) async { + Future delete(String url) async { try { - return await _dio.delete(endpoint); + return await _dio.delete(url); } catch (e) { throw _handleError(e); }