diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json index 6c0bd8a..56b0977 100644 --- a/.dart_tool/package_config.json +++ b/.dart_tool/package_config.json @@ -1,6 +1,18 @@ { "configVersion": 2, "packages": [ + { + "name": "animation_list", + "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/animation_list-3.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "animations", + "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/animations-2.0.11", + "packageUri": "lib/", + "languageVersion": "3.2" + }, { "name": "args", "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/args-2.5.0", @@ -151,6 +163,12 @@ "packageUri": "lib/", "languageVersion": "3.3" }, + { + "name": "flutter_animate", + "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_animate-4.5.2", + "packageUri": "lib/", + "languageVersion": "2.17" + }, { "name": "flutter_cache_manager", "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_cache_manager-3.4.1", @@ -169,6 +187,12 @@ "packageUri": "lib/", "languageVersion": "2.17" }, + { + "name": "flutter_shaders", + "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_shaders-0.1.3", + "packageUri": "lib/", + "languageVersion": "2.19" + }, { "name": "flutter_svg", "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_svg-2.0.10+1", @@ -199,6 +223,12 @@ "packageUri": "lib/", "languageVersion": "3.0" }, + { + "name": "gap", + "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/gap-3.0.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, { "name": "get_it", "rootUri": "file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/get_it-8.0.3", @@ -590,7 +620,7 @@ "languageVersion": "3.4" } ], - "generated": "2025-01-21T13:28:23.681235Z", + "generated": "2025-01-24T13:29:48.830847Z", "generator": "pub", "generatorVersion": "3.4.4", "flutterRoot": "file:///Users/rajeevsingh/Documents/allSoftwares/flutter", diff --git a/.dart_tool/package_config_subset b/.dart_tool/package_config_subset index 55d1dd8..dbdb2bf 100644 --- a/.dart_tool/package_config_subset +++ b/.dart_tool/package_config_subset @@ -1,3 +1,11 @@ +animation_list +2.12 +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/animation_list-3.1.0/ +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/animation_list-3.1.0/lib/ +animations +3.2 +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/animations-2.0.11/ +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/animations-2.0.11/lib/ args 3.0 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/args-2.5.0/ @@ -94,6 +102,10 @@ fixnum 2.19 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/fixnum-1.1.0/ file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib/ +flutter_animate +2.17 +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_animate-4.5.2/ +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_animate-4.5.2/lib/ flutter_cache_manager 3.0 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_cache_manager-3.4.1/ @@ -106,6 +118,10 @@ flutter_screenutil 2.17 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_screenutil-5.9.3/ file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_screenutil-5.9.3/lib/ +flutter_shaders +2.19 +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_shaders-0.1.3/ +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_shaders-0.1.3/lib/ flutter_svg 2.19 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/flutter_svg-2.0.10+1/ @@ -118,6 +134,10 @@ fpdart 3.0 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/fpdart-1.1.1/ file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/fpdart-1.1.1/lib/ +gap +2.12 +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/gap-3.0.1/ +file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/gap-3.0.1/lib/ get_it 3.0 file:///Users/rajeevsingh/.pub-cache/hosted/pub.dev/get_it-8.0.3/ diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 7810bd5..bc492ee 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_android-2.2.10/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_android-2.3.2/","native_build":true,"dependencies":[]},{"name":"sqflite","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.2/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]}],"date_created":"2025-01-21 18:58:23.867638","version":"3.22.3"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_android-2.2.10/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_android-2.3.2/","native_build":true,"dependencies":[]},{"name":"sqflite","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.4/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"connectivity_plus","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/connectivity_plus-6.1.2/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/rajeevsingh/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.2/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]}],"date_created":"2025-01-24 18:59:49.009756","version":"3.22.3"} \ No newline at end of file diff --git a/assets/images/svgs/add.svg b/assets/images/svgs/add.svg new file mode 100644 index 0000000..47a2743 --- /dev/null +++ b/assets/images/svgs/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svgs/remove.svg b/assets/images/svgs/remove.svg new file mode 100644 index 0000000..4740f3b --- /dev/null +++ b/assets/images/svgs/remove.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/main.dart b/lib/main.dart index 5e004eb..c662930 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:grocery_app/src/core/network_services/service_locator.dart'; import 'package:grocery_app/src/core/routes/routes.dart'; +import 'package:grocery_app/src/logic/provider/auth_provider.dart'; import 'package:grocery_app/src/ui/splash/splash_screen.dart'; import 'package:grocery_app/utils/constants/color_constant.dart'; import 'package:grocery_app/utils/constants/string_constant.dart'; @@ -9,6 +11,8 @@ import 'package:provider/provider.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); + WidgetsFlutterBinding.ensureInitialized(); + ServiceLocator.setup(); runApp(const MyApplication()); } @@ -17,51 +21,49 @@ class MyApplication extends StatelessWidget { @override Widget build(BuildContext context) { - return - - // ScreenUtilInit( - // designSize: const Size(360, 690), - // minTextAdapt: true, - // splitScreenMode: true, - // builder: (context, child) => GlobalLoaderOverlay( - // overlayColor: APPCOLOR.appGreen, - // useDefaultLoading: false, - // // overlayWidgetBuilder: (progress) => const GlobalLoader(), - // child: MultiProvider( - // providers: [ - // // ChangeNotifierProvider(create: (_) => PageNotifier()), - // // ChangeNotifierProvider(create: (_) => DaySelectionProvider()), - // // ChangeNotifierProvider(create: (_) => LoginProvider()), - // // ChangeNotifierProvider(create: (_) => ProductProvider()), - // // ChangeNotifierProvider(create: (_) => HomeProvider()), - // ], - // child: MaterialApp.router( - // routerConfig: MyRoutes.router, - // debugShowCheckedModeBanner: false, - // theme: ThemeData( - // colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - // scaffoldBackgroundColor: Colors.white, - // canvasColor: const Color.fromRGBO(255, 255, 255, 1), - // fontFamily: 'GoogleSans', - // primarySwatch: Colors.blue, - // ), - // themeMode: ThemeMode.light, - // title: APPSTRING.appName, - // ), - // ), - // ), - // ); - - MaterialApp.router( - title: 'Customer App', - routerConfig: MyRoutes.router, - - debugShowCheckedModeBanner: false, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, + return ScreenUtilInit( + designSize: const Size(360, 690), + minTextAdapt: true, + splitScreenMode: true, + builder: (context, child) => GlobalLoaderOverlay( + overlayColor: APPCOLOR.whiteFBFEFB.withOpacity(0.5), + useDefaultLoading: false, + // overlayWidgetBuilder: (progress) => const GlobalLoader(), + child: MultiProvider( + providers: [ + ChangeNotifierProvider(create: (_) => AuthProvider()), + // ChangeNotifierProvider(create: (_) => DaySelectionProvider()), + // ChangeNotifierProvider(create: (_) => LoginProvider()), + // ChangeNotifierProvider(create: (_) => ProductProvider()), + // ChangeNotifierProvider(create: (_) => HomeProvider()), + ], + child: MaterialApp.router( + routerConfig: MyRoutes.router, + debugShowCheckedModeBanner: false, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + scaffoldBackgroundColor: Colors.white, + canvasColor: const Color.fromRGBO(255, 255, 255, 1), + fontFamily: 'GoogleSans', + primarySwatch: Colors.blue, + ), + themeMode: ThemeMode.light, + title: APPSTRING.appName, + ), + ), ), - // home: const SplashScreen(), ); + + // MaterialApp.router( + // title: 'Customer App', + // routerConfig: MyRoutes.router, + + // debugShowCheckedModeBanner: false, + // theme: ThemeData( + // colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + // useMaterial3: true, + // ), + // // home: const SplashScreen(), + // ); } } diff --git a/lib/src/core/constant/api.dart b/lib/src/core/constant/api.dart index 9dd7de1..261ca01 100644 --- a/lib/src/core/constant/api.dart +++ b/lib/src/core/constant/api.dart @@ -1,14 +1,16 @@ class APIURL { static const BASE_URL = "http://210.89.44.183:3333/xam/"; - static const String sendOtp = "${BASE_URL}auth/send-otp/vendor"; - static const String verifyOtp = "${BASE_URL}auth/verify-otp/vendor"; + static const String sendOtp = "${BASE_URL}auth/send-otp/customer"; + + static const String verifyOtp = "${BASE_URL}auth/verify-otp/customer"; static const String login = "${BASE_URL}auth/login/vendor"; - static const String vendorRegister = "${BASE_URL}auth/register/vendor"; + static const String customerRegister = "${BASE_URL}auth/register/customer"; static const String createStore = "${BASE_URL}stores"; static const String getStore = "${BASE_URL}stores/"; static const String updateStore = "${BASE_URL}stores/"; static const String forgetPassword = "${BASE_URL}auth/forgot-password/vendor"; - static const String verifyForgetPassword = "${BASE_URL}auth/forgot-password-verify-otp/vendor"; + static const String verifyForgetPassword = + "${BASE_URL}auth/forgot-password-verify-otp/vendor"; static const String reset_password = "${BASE_URL}auth/reset-password/vendor"; static const String get_category = "${BASE_URL}categories"; static const String getProduct = "${BASE_URL}products"; diff --git a/lib/src/core/network_services/service_locator.dart b/lib/src/core/network_services/service_locator.dart index 7997f9d..18b417e 100644 --- a/lib/src/core/network_services/service_locator.dart +++ b/lib/src/core/network_services/service_locator.dart @@ -3,6 +3,8 @@ import 'package:dio/dio.dart'; import 'package:get_it/get_it.dart'; import 'package:grocery_app/src/core/network_services/dio_client.dart'; +import 'package:grocery_app/src/logic/repo/auth_repo.dart'; +import 'package:grocery_app/src/logic/services/auth_service_locator.dart'; @@ -16,22 +18,15 @@ class ServiceLocator // dio client getIt.registerSingleton(Dio()); getIt.registerSingleton(DioClient(getIt())); - // getIt.registerSingleton(AuthServices()); + getIt.registerSingleton(AuthServices()); // getIt.registerSingleton(ProductService()); // getIt.registerSingleton(StoreService()); // getIt.registerSingleton(HomeService()); - // StoreRepo - - // getIt.registerSingleton(ContactApiService()); - // getIt.registerSingleton(BuzzService()); - // getIt.registerSingleton(CmsServices()); - // getIt.registerSingleton(SettingService()); - // getIt.registerSingleton(ActivityService()); - + // Repos -// getIt.registerSingleton(AuthRepo(getIt())); + getIt.registerSingleton(AuthRepo(getIt())); // getIt.registerSingleton(ProductRepo(getIt())); // getIt.registerSingleton(StoreRepo(getIt())); // getIt.registerSingleton(HomeRepo(getIt())); diff --git a/lib/src/core/utils/common_utils.dart b/lib/src/core/utils/common_utils.dart new file mode 100644 index 0000000..92f8eb4 --- /dev/null +++ b/lib/src/core/utils/common_utils.dart @@ -0,0 +1,88 @@ +import 'dart:math' as math; + + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:gap/gap.dart'; +import 'package:grocery_app/utils/constants/globle_variable.dart'; +import 'package:grocery_app/utils/extensions/extensions.dart'; + + + + + +/// Hides soft keyboard if already shown +/// +enum SnackType { + success, + alert, + error +} + + +void hideKeyBoard() { + FocusManager.instance.primaryFocus?.unfocus(); +} + + + +/// Show snackbar +void showSnackBar( + { BuildContext ?context, + required String message, + SnackType snackType = SnackType.success, + bool canDismiss = true, + bool sticky = false, + SnackBarBehavior behaviour = SnackBarBehavior.floating, + }) { + //if (!context?.mounted??) return; + //Clear snack bars + ScaffoldMessenger.of(context??GlobalVariable.globalScaffoldKey.currentContext!).clearSnackBars(); + // Snack bar + final snackBar = SnackBar( + behavior: behaviour, + padding: EdgeInsets.zero, + elevation: 0, + content: Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.h), + decoration: BoxDecoration( + gradient: LinearGradient( + colors:snackType==SnackType.success? const [ + Color(0xFF61B15A), + Color(0xFF6ABE8B) + ]:snackType==SnackType.alert? + const [ + Color(0xFFFF8906), + Color(0xFFFFA745), + ]: + const [ + Colors.red, + Colors.redAccent, + ], + ), + ), + child: Text( + message, + style: (context??GlobalVariable.globalScaffoldKey.currentContext!).titleStyle.copyWith(fontSize: 16.sp,color: Colors.white), + textAlign: TextAlign.center, + ), + ), + duration: sticky ? const Duration(days: 365) : const Duration(seconds: 3), + dismissDirection: + canDismiss ? DismissDirection.down : DismissDirection.none, + ); + +// Find the ScaffoldMessenger in the widget tree +// and use it to show a SnackBar. + ScaffoldMessenger.of(context??GlobalVariable.globalScaffoldKey.currentContext!).showSnackBar(snackBar); +} + +// Format File Size +String getFileSizeString({required int bytes, int decimals = 0}) { + if (bytes <= 0) { + return "0"; + } + const suffixes = ["b", "kb", "mb", "gb", "tb"]; + var i = (math.log(bytes) / math.log(1024)).floor(); + return ((bytes / math.pow(1024, i)).toStringAsFixed(decimals)) + suffixes[i]; +} diff --git a/lib/src/core/utils/custom_dio_exception.dart b/lib/src/core/utils/custom_dio_exception.dart new file mode 100644 index 0000000..7375454 --- /dev/null +++ b/lib/src/core/utils/custom_dio_exception.dart @@ -0,0 +1,142 @@ +import 'package:dio/dio.dart'; + +import 'package:dio/dio.dart'; + +import 'package:dio/dio.dart'; +import 'package:grocery_app/src/core/utils/response_type_def.dart'; + +class CustomDioExceptions implements Exception { + late String message; + + CustomDioExceptions.fromDioException(DioException dioException) { + switch (dioException.type) { + case DioExceptionType.cancel: + message = "Request to API server was cancelled"; + break; + case DioExceptionType.connectionTimeout: + message = "Connection timeout with API server"; + break; + case DioExceptionType.receiveTimeout: + message = "Receive timeout in connection with API server"; + break; + case DioExceptionType.badResponse: + message = _handleStatusError( + dioException.response?.statusCode, + dioException.response?.data, + ); + break; + case DioExceptionType.sendTimeout: + message = "Send timeout in connection with API server"; + break; + case DioExceptionType.unknown: + message = "Unexpected error occurred"; + break; + default: + message = "Something went wrong"; + break; + } + } + + String _handleStatusError(int? statusCode, dynamic error) { + switch (statusCode) { + case 400: + return error["message"] ?? 'Bad request'; + case 401: + return error["message"] ?? 'Unauthorized'; + case 403: + return error["message"] ?? 'Forbidden'; + case 404: + return error["message"] ?? 'Not Found'; + case 422: + return error["message"] ?? 'Cannot proceed with the data provided.'; + case 406: + return error["message"] ?? 'Input Mismatched'; + case 500: + return error["message"] ?? 'Internal server error'; + case 502: + return error["message"] ?? 'Bad gateway'; + default: + return error["message"] ?? 'Oops something went wrong'; + } + } + + /// Handle the error and return a `CustomError` + static CustomError handleError(DioException e) { + final errorMessage = CustomDioExceptions.fromDioException(e).toString(); + return CustomError(errorMessage, e.response?.statusCode); + } + + @override + String toString() => message; +} + + + + +// class CustomDioExceptions implements Exception { +// late String message; + +// CustomDioExceptions.fromDioException(DioException dioException) { +// switch (dioException.type) +// { +// case DioExceptionType.cancel: +// message = "Request to API server was cancelled"; +// break; +// case DioExceptionType.connectionTimeout: +// message = "Connection timeout with API server"; +// break; +// case DioExceptionType.receiveTimeout: +// message = "Receive timeout in connection with API server"; +// break; +// case DioExceptionType.badResponse: +// message = _handleStatusError( +// dioException.response?.statusCode, +// dioException.response?.data, +// ); +// break; +// case DioExceptionType.sendTimeout: +// message = "Send timeout in connection with API server"; +// break; +// case DioExceptionType.unknown: +// message = "Unexpected error occurred"; +// break; +// default: +// message = "Something went wrong"; +// break; +// } +// } + +// String _handleStatusError(int? statusCode, dynamic error) { +// switch (statusCode) { +// case 400: +// return error["message"] ?? 'Bad request'; +// case 401: +// return error["message"] ?? 'Unauthorized'; +// case 403: +// return error["message"] ?? 'Forbidden'; +// case 404: +// return error["message"] ?? 'Not Found'; +// case 422: +// return error["message"] ?? 'Can not proceed with the data provided.'; +// case 406: +// return error["message"] ?? 'Input Mismatched'; +// case 500: +// return error["message"] ?? 'Internal server error'; +// case 502: +// return error["message"] ?? 'Bad gateway'; +// default: +// return error["message"] ?? 'Oops something went wrong'; +// } +// } + +// /// call this method from api repo to handle the error +// static CustomError handleError(DioException e) +// { +// final errorMessage = CustomDioExceptions.fromDioException(e).toString(); + +// return CustomError(errorMessage, e.response?.statusCode); +// } + +// @override +// String toString() => message; +// } diff --git a/lib/src/core/utils/response_type_def.dart b/lib/src/core/utils/response_type_def.dart new file mode 100644 index 0000000..bda390a --- /dev/null +++ b/lib/src/core/utils/response_type_def.dart @@ -0,0 +1,10 @@ +import 'package:fpdart/fpdart.dart'; + +typedef FutureResult = Future>; +typedef VoidResult = Future>; + +class CustomError { + final String message; + final int? code; + CustomError(this.message, this.code); +} diff --git a/lib/src/core/utils/snack_bar.dart b/lib/src/core/utils/snack_bar.dart new file mode 100644 index 0000000..060ed76 --- /dev/null +++ b/lib/src/core/utils/snack_bar.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; + +void showTopSnackBar(BuildContext context, String message, Color color) { + final overlay = Overlay.of(context); + final overlayEntry = OverlayEntry( + builder: (context) => Positioned( + top: MediaQuery.of(context).padding.top + 10, // Adjust based on the device's status bar + left: 10, + right: 10, + child: Material( + color: Colors.transparent, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Text( + message, + style: const TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + ), + ), + ), + ); + + overlay.insert(overlayEntry); + + // Automatically remove the snackbar after a delay + Future.delayed(const Duration(seconds: 3)).then((_) { + overlayEntry.remove(); + }); +} diff --git a/lib/src/data/OTPResponseModel copy.dart b/lib/src/data/OTPResponseModel copy.dart new file mode 100644 index 0000000..79cfe49 --- /dev/null +++ b/lib/src/data/OTPResponseModel copy.dart @@ -0,0 +1,49 @@ +// To parse this JSON data, do +// +// final otpResponseModel = otpResponseModelFromJson(jsonString); + +import 'dart:convert'; + +OtpResponseModel otpResponseModelFromJson(String str) => + OtpResponseModel.fromJson(json.decode(str)); + +String otpResponseModelToJson(OtpResponseModel data) => + json.encode(data.toJson()); + +class OtpResponseModel + { + String? message; + Data? data; + + OtpResponseModel({ + this.message, + this.data, + }); + + factory OtpResponseModel.fromJson(Map json) => + OtpResponseModel( + message: json["message"], + data: Data.fromJson(json["data"]), + ); + + Map toJson() => { + "message": message, + "data": data!.toJson(), + }; +} + +class Data { + String? otp; + + Data({ + this.otp, + }); + + factory Data.fromJson(Map json) => Data( + otp: json["otp"], + ); + + Map toJson() => { + "otp": otp, + }; +} diff --git a/lib/src/data/OTPResponseModel.dart b/lib/src/data/OTPResponseModel.dart new file mode 100644 index 0000000..79cfe49 --- /dev/null +++ b/lib/src/data/OTPResponseModel.dart @@ -0,0 +1,49 @@ +// To parse this JSON data, do +// +// final otpResponseModel = otpResponseModelFromJson(jsonString); + +import 'dart:convert'; + +OtpResponseModel otpResponseModelFromJson(String str) => + OtpResponseModel.fromJson(json.decode(str)); + +String otpResponseModelToJson(OtpResponseModel data) => + json.encode(data.toJson()); + +class OtpResponseModel + { + String? message; + Data? data; + + OtpResponseModel({ + this.message, + this.data, + }); + + factory OtpResponseModel.fromJson(Map json) => + OtpResponseModel( + message: json["message"], + data: Data.fromJson(json["data"]), + ); + + Map toJson() => { + "message": message, + "data": data!.toJson(), + }; +} + +class Data { + String? otp; + + Data({ + this.otp, + }); + + factory Data.fromJson(Map json) => Data( + otp: json["otp"], + ); + + Map toJson() => { + "otp": otp, + }; +} diff --git a/lib/src/data/product_model.dart b/lib/src/data/product_model.dart new file mode 100644 index 0000000..51c01b5 --- /dev/null +++ b/lib/src/data/product_model.dart @@ -0,0 +1,13 @@ +class ProductModel { + String productImage; + String productName; + String quantity; + String amount; + + ProductModel( + this.productImage, + this.productName, + this.quantity, + this.amount, + ); +} diff --git a/lib/src/data/vendor_otpModel.dart b/lib/src/data/vendor_otpModel.dart new file mode 100644 index 0000000..f94cd5c --- /dev/null +++ b/lib/src/data/vendor_otpModel.dart @@ -0,0 +1,78 @@ +// To parse this JSON data, do +// +// final vendorOtpModel = vendorOtpModelFromJson(jsonString); + +import 'dart:convert'; + +VendorOtpModel vendorOtpModelFromJson(String str) => + VendorOtpModel.fromJson(json.decode(str)); + +String vendorOtpModelToJson(VendorOtpModel data) => json.encode(data.toJson()); + +class VendorOtpModel { + String? message; + Data? data; + + VendorOtpModel({ + this.message, + this.data, + }); + + factory VendorOtpModel.fromJson(Map json) => VendorOtpModel( + message: json["message"], + data: Data.fromJson(json["data"]), + ); + + Map toJson() => { + "message": message, + "data": data!.toJson(), + }; +} + +class Data { + User? user; + String? accessToken; + String? refreshToken; + + Data({ + this.user, + this.accessToken, + this.refreshToken, + }); + + factory Data.fromJson(Map json) => Data( + user: User.fromJson(json["user"]), + accessToken: json["access_token"], + refreshToken: json["refresh_token"], + ); + + Map toJson() => { + "user": user!.toJson(), + "access_token": accessToken, + "refresh_token": refreshToken, + }; +} + +class User { + String? id; + String? phone; + bool? isPhoneVerified; + + User({ + this.id, + this.phone, + this.isPhoneVerified, + }); + + factory User.fromJson(Map json) => User( + id: json["id"], + phone: json["phone"], + isPhoneVerified: json["isPhoneVerified"], + ); + + Map toJson() => { + "id": id, + "phone": phone, + "isPhoneVerified": isPhoneVerified, + }; +} diff --git a/lib/src/logic/provider/auth_provider.dart b/lib/src/logic/provider/auth_provider.dart new file mode 100644 index 0000000..e708be5 --- /dev/null +++ b/lib/src/logic/provider/auth_provider.dart @@ -0,0 +1,218 @@ +import 'package:flutter/material.dart'; +import 'package:grocery_app/src/core/network_services/service_locator.dart'; +import 'package:grocery_app/src/core/utils/snack_bar.dart'; +import 'package:grocery_app/src/logic/repo/auth_repo.dart'; +import 'package:grocery_app/utils/constants/shared_pref_utils.dart'; +import 'package:grocery_app/utils/extensions/extensions.dart'; + +class AuthProvider extends ChangeNotifier { + int _currentIndex = 0; + final int _totalPages = 4; // Set total number of pages + final PageController _pageController = PageController(); + + final TextEditingController name = TextEditingController(); + final TextEditingController lastName = TextEditingController(); + final TextEditingController email = TextEditingController(); + final TextEditingController address = TextEditingController(); + + final TextEditingController passwordController = TextEditingController(); + final TextEditingController confirmPasswordController = + TextEditingController(); + + int get currentIndex => _currentIndex; + PageController get pageController => _pageController; + + // Calculate progress as a percentage + double get progress => (_currentIndex + 1) / _totalPages; + + final _authRepo = getIt(); + String numberwithCode = ''; + + Future sendOtp(String number, BuildContext context) async { + context.showLoader(show: true); + + var data = {"phone": "+91" + number}; + + numberwithCode = "+91" + number; + try { + var response = await _authRepo.sendOtp(data); + print("check response ${response}"); + context.showLoader(show: false); + + return response.fold( + (error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(error.message), + backgroundColor: Colors.red, + ), + ); + return false; + }, + (response) { + print("hdsfvjhdfghjdf"); + _showSnackBar(context, "OTP sent successfully", Colors.green); + + return true; + }, + ); + } catch (e) { + context.showLoader(show: false); + print("Unexpected error: $e"); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Something went wrong. Please try again."), + backgroundColor: Colors.red, + ), + ); + return false; + } + } + + Future verifiOtp(String otp, BuildContext context) async { + context.showLoader(show: true); + var data = { + "phone": numberwithCode, + "otp": otp, + }; + + try { + var result = await _authRepo.verifyOtp(data); + + return result.fold( + (error) { + // Show error Snackbar + context.showLoader(show: false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(error.message), + backgroundColor: Colors.red, + ), + ); + return false; // Login failed + }, + (response) { + // Login success + context.showLoader(show: false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("OTP Verify successful!"), + backgroundColor: Colors.green, + ), + ); + return true; + }, + ); + } catch (e) { + context.showLoader(show: false); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Something went wrong. Please try again."), + backgroundColor: Colors.red, + ), + ); + return false; + } + } + + // //login + + // //vendorRegister + + Future vendorRegister(BuildContext context) async { + context.showLoader(show: true); + var data = { + "firstName": await SharedPrefUtils.getFirstName(), + "lastName": await SharedPrefUtils.getLastName(), + "email": await SharedPrefUtils.getEmail(), + "password": await SharedPrefUtils.getPassword(), + "vendorType": "individual", + + }; + + try { + var result = await _authRepo.customerRegister(data); + return result.fold( + (error) { + // Show error Snackbar + context.showLoader(show: false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(error.message), + backgroundColor: Colors.red, + ), + ); + return false; // Login failed + }, + (response) { + // Login success + context.showLoader(show: false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Vendor Register successful!"), + backgroundColor: Colors.green, + ), + ); + return true; + }, + ); + } catch (e) { + context.showLoader(show: false); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Something went wrong. Please try again."), + backgroundColor: Colors.red, + ), + ); + return false; + } + } + + // void goToNextPage() { + // // Ensure that the current index is updated correctly + // if (_currentIndex < _totalPages - 1) { + // _currentIndex++; // Increment the index here + // _pageController.animateToPage( + // _currentIndex, + // duration: const Duration(milliseconds: 300), + // curve: Curves.ease, + // ); + // notifyListeners(); // Notify listeners to update the view + // } + // } + + // void goToPage(int index) { + // if (index >= 0 && index < _totalPages) { + // _currentIndex = index; + // print("Navigating to page: $_currentIndex"); // Debug print + // _pageController.animateToPage( + // _currentIndex, + // duration: const Duration(milliseconds: 300), + // curve: Curves.ease, + // ); + // notifyListeners(); + // } + // } + + @override + void dispose() { + _pageController.dispose(); + super.dispose(); + } + + // bool _isChecked = false; + + // bool get isChecked => _isChecked; + + // void toggleCheckbox(bool value) { + // _isChecked = value; + // notifyListeners(); + // } + + void _showSnackBar(BuildContext context, String message, Color color) { + showTopSnackBar(context, message, color); + } +} diff --git a/lib/src/logic/provider/crate_store_provider.dart b/lib/src/logic/provider/crate_store_provider.dart new file mode 100644 index 0000000..3ec9d81 --- /dev/null +++ b/lib/src/logic/provider/crate_store_provider.dart @@ -0,0 +1,350 @@ +// import 'dart:io'; + +// import 'package:flutter/material.dart'; +// import 'package:intl/intl.dart'; +// import 'package:vendor_app/src/core/network_services/service_locator.dart'; +// import 'package:vendor_app/src/core/routes/routes.dart'; +// import 'package:vendor_app/src/core/utiils_lib/extensions.dart'; +// import 'package:vendor_app/src/core/utiils_lib/shared_pref_utils.dart'; +// import 'package:vendor_app/src/data/store_model.dart'; +// import 'package:vendor_app/src/logic/repo/auth_repo.dart'; +// import 'package:vendor_app/src/logic/repo/store_repo.dart'; + +// class DaySelectionProvider with ChangeNotifier { +// List _selectedDays = []; + +// List get selectedDays => _selectedDays; +// final _storeRepo = getIt(); + +// void toggleDay(String day) { +// if (_selectedDays.contains(day)) { +// _selectedDays.remove(day); +// } else { +// _selectedDays.add(day); +// } +// notifyListeners(); +// } + +// void removeDay(String day) { +// _selectedDays.remove(day); +// notifyListeners(); +// } + +// final TextEditingController storeName = TextEditingController(); +// final TextEditingController storeDescription = TextEditingController(); +// final TextEditingController officialPhoneNumber = TextEditingController(); +// final TextEditingController storeAddress = TextEditingController(); +// final TextEditingController storeGSTNumber = TextEditingController(); +// final TextEditingController storeGumastaNumber = TextEditingController(); + +// bool _editStore = false; + +// bool get editStore => _editStore; + +// setEditStore(bool type) { +// _editStore = type; +// notifyListeners(); +// } + +// File? _image; + +// File? get image => _image; + +// void setImage(File? image) { +// _image = image; +// notifyListeners(); +// } + +// //// create store ///////////////////////////////////////////////////// + +// final TextEditingController bankName = TextEditingController(); +// final TextEditingController accountHoldername = TextEditingController(); +// final TextEditingController accountNumber = TextEditingController(); +// final TextEditingController ifscCode = TextEditingController(); +// final TextEditingController appwithdrawalPin = TextEditingController(); + +// String _selectedTime = 'Open'; + +// String _selectedClosedTime = 'Close'; + +// String get selectedTime => _selectedTime; + +// String get selectedClosedTime => _selectedClosedTime; + +// Future Opening(BuildContext context) async { +// TimeOfDay? pickedTime = await showTimePicker( +// context: context, +// initialTime: TimeOfDay.now(), +// ); + +// if (pickedTime != null) { +// _selectedTime = pickedTime.format(context); +// notifyListeners(); +// } +// } + +// Future closedTiming(BuildContext context) async { +// TimeOfDay? pickedTime = await showTimePicker( +// context: context, +// initialTime: TimeOfDay.now(), +// ); + +// if (pickedTime != null) { +// _selectedClosedTime = pickedTime.format(context); +// notifyListeners(); +// } +// } + +// String _pin = ''; +// String _confirmPin = ''; +// bool _isMatch = true; + +// String get pin => _pin; +// String get confirmPin => _confirmPin; +// bool get isMatch => _isMatch; + +// void setPin(String pin) { +// _pin = pin; +// _validatePins(); +// } + +// void setConfirmPin(String confirmPin) { +// _confirmPin = confirmPin; +// _validatePins(); +// } + +// void _validatePins() { +// _isMatch = _pin == _confirmPin; +// notifyListeners(); +// } + +// void reset() { +// _pin = ''; +// _confirmPin = ''; +// _isMatch = true; +// notifyListeners(); +// } + +// // create store + +// // Dynamically build the operateDates map +// Map getOperateDates(List selectedDays) { +// // Define all possible days +// List allDays = [ +// 'monday', +// 'tuesday', +// 'wednesday', +// 'thursday', +// 'friday', +// 'saturday', +// 'sunday' +// ]; + +// // Create the operateDates map +// Map operateDates = { +// for (var day in allDays) +// day: selectedDays.map((e) => e.toLowerCase()).contains(day) +// }; + +// return operateDates; +// } + +// Future createStore(BuildContext context) async { +// context.showLoader(show: true); + +// var data = { +// "storeName": storeName.text, +// "storeDescription": storeDescription.text, +// "officialPhoneNumber": officialPhoneNumber.text, +// "storeAddress": storeAddress.text, +// "gstNumber": storeGSTNumber.text, +// "gumastaNumber": storeGumastaNumber.text, +// "storePicture": image!.path.split('/').last, +// "operateDates": getOperateDates(selectedDays), +// "operateTimes": { +// "startTime": selectedTime, +// "endTime": selectedClosedTime +// }, +// "paymentDetails": { +// "bankName": bankName.text, +// "accountHolder": accountHoldername.text, +// "accountNumber": accountNumber.text, +// "ifscCode": ifscCode.text, +// "appWithdrawalPin": confirmPin.toString() +// } +// }; + +// try { +// var result = await _storeRepo.createStore(data); + +// context.showLoader(show: false); + +// return result.fold( +// (error) { +// // Show error Snackbar +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(error.message), +// backgroundColor: Colors.red, +// ), +// ); +// return false; // Login failed +// }, +// (response) { +// // Login success +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Store created successful!"), +// backgroundColor: Colors.green, +// ), +// ); +// return true; +// }, +// ); +// } catch (e) { +// context.showLoader(show: false); +// print("Unexpected error: $e"); + +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Something went wrong. Please try again."), +// backgroundColor: Colors.red, +// ), +// ); +// return false; +// } +// } + +// Future updateSore(BuildContext context,String id) async { +// context.showLoader(show: true); + +// var data = { +// "operateDates": getOperateDates(selectedDays), +// "operateTimes": { +// "startTime": selectedTime, +// "endTime": selectedClosedTime +// }, +// "paymentDetails": { +// "bankName": bankName.text, +// "accountHolder": accountHoldername.text, +// "accountNumber": accountNumber.text, +// "ifscCode": ifscCode.text, +// "appWithdrawalPin": confirmPin.toString() +// } +// }; + +// print("dfhgkjhg ${data}"); + +// try { +// var result = await _storeRepo.updateStore(data); + +// context.showLoader(show: false); + +// return result.fold( +// (error) { +// // Show error Snackbar +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(error.message), +// backgroundColor: Colors.red, +// ), +// ); +// return false; // Login failed +// }, +// (response) { +// // Login success +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Store created successful!"), +// backgroundColor: Colors.green, +// ), +// ); +// return true; +// }, +// ); +// } catch (e) { +// context.showLoader(show: false); +// print("Unexpected error: $e"); + +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Something went wrong. Please try again."), +// backgroundColor: Colors.red, +// ), +// ); +// return false; +// } +// } + +// bool isLoading = false; + +// StoreModel? store_model; +// Future getStore() async { +// isLoading = true; +// notifyListeners(); + +// final result = await _storeRepo.getStore({}); +// result.fold( +// (error) { +// // Handle error +// isLoading = false; +// notifyListeners(); +// }, +// (store) { +// setEditStore(false); +// print("lksjdfdkjf ${store.createdAt}"); +// isLoading = false; +// store_model = store; +// notifyListeners(); +// }, +// ); +// } + +// Future vendorLogOut(BuildContext context) async { +// context.showLoader(show: true); + +// var data = {}; + +// try { +// var result = await _storeRepo.vendorLogOut(data); + +// context.showLoader(show: false); + +// return result.fold( +// (error) { +// // Show error Snackbar +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(error.message), +// backgroundColor: Colors.red, +// ), +// ); +// return false; // Login failed +// }, +// (response) async { +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Store created successful!"), +// backgroundColor: Colors.green, +// ), +// ); +// await SharedPrefUtils.clear(); +// context.clearAndPush(routePath: MyRoutes.SELECTACCOUNT); + +// return true; +// }, +// ); +// } catch (e) { +// context.showLoader(show: false); +// print("Unexpected error: $e"); + +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Something went wrong. Please try again."), +// backgroundColor: Colors.red, +// ), +// ); +// return false; +// } +// } +// } diff --git a/lib/src/logic/provider/create_product_provider.dart b/lib/src/logic/provider/create_product_provider.dart new file mode 100644 index 0000000..1f565a6 --- /dev/null +++ b/lib/src/logic/provider/create_product_provider.dart @@ -0,0 +1,443 @@ +// import 'dart:io'; + +// import 'package:flutter/material.dart'; +// import 'package:image_picker/image_picker.dart'; +// import 'package:vendor_app/src/core/network_services/service_locator.dart'; +// import 'package:vendor_app/src/core/utiils_lib/extensions.dart'; +// import 'package:vendor_app/src/core/utiils_lib/snack_bar.dart'; +// import 'package:vendor_app/src/data/ProductCategoryModel.dart'; +// import 'package:vendor_app/src/data/prdouct_model.dart'; +// import 'package:vendor_app/src/logic/repo/product_repo.dart'; + +// import 'package:flutter/material.dart'; +// import 'package:vendor_app/src/core/network_services/service_locator.dart'; +// import 'package:vendor_app/src/data/prdouct_model.dart'; +// import 'package:vendor_app/src/logic/repo/product_repo.dart'; +// import 'package:vendor_app/src/logic/services/product_locator.dart'; + +// class ProductProvider extends ChangeNotifier { +// ProductCategoryModel? selectedCategory; +// // String selectedSubcategory = ''; +// // String selectedProduct = ''; + +// ProductCategoryModel? selectedSubcategory; +// ProductCategoryModel? selectedProduct; + +// String productId = ''; +// // String productDescription = ''; +// // String productUnit = ''; +// // double productPrice = 0.0; +// // double discountPrice = 0.0; +// bool inStock = true; + +// String selectedProductQuantity = ''; + +// bool isLoading = false; + +// final _authRepo = getIt(); + +// // Dynamic Data +// List categories = []; +// Map> subcategories = {}; +// Map> products = {}; + +// void setCategory(ProductCategoryModel category) { +// selectedCategory = category; +// selectedSubcategory = null; +// selectedProduct = null; +// products.clear(); +// loadSubcategories(category); +// notifyListeners(); +// } + +// void setSubcategory(ProductCategoryModel subcategory) { +// selectedSubcategory = subcategory; +// selectedProduct = null; +// loadProducts(subcategory); // Load products for the selected subcategory +// notifyListeners(); +// } + +// void loadSubcategories(ProductCategoryModel category) { +// if (category.childCategories != null) { +// subcategories[category.name!] = category.childCategories!; +// } else { +// subcategories.clear(); +// } +// notifyListeners(); +// } + +// // Load products for a selected subcategory +// void loadProducts(ProductCategoryModel subcategory) { +// if (subcategory.childCategories != null) { +// products[subcategory.name!] = subcategory.childCategories!; +// } else { +// products.clear(); +// } +// notifyListeners(); +// } + +// void setProduct(ProductCategoryModel product) { +// productId = product.id!; +// selectedProduct = product; +// notifyListeners(); +// } + +// void setProductQuantity(String value) { +// selectedProductQuantity = value; +// notifyListeners(); +// } + +// void toggleStock(bool value) { +// inStock = value; +// notifyListeners(); +// } + +// void clearData() { +// _isImageLoading = false; + +// productDescriptionController.clear(); +// productUnitController.clear(); +// productPriceController.clear(); +// productProductDiscountPriceController.clear(); +// productStockController.clear(); +// productNameController.clear(); +// productquantityController.clear(); +// productqlongDescriptionController.clear(); +// _isImageLoading = false; +// _selectedImage = null; + +// selectedCategory = null; +// selectedSubcategory = null; +// selectedProduct = null; +// selectedSubcategory; +// categories = []; + +// subcategories.forEach((key, value) => value.clear()); +// products.forEach((key, value) => value.clear()); +// subcategories = {}; +// products = {}; +// } + +// // Fetch categories from API +// Future getCategoryByLevel() async { +// clearData(); +// isLoading = true; +// notifyListeners(); + +// final result = await _authRepo.getCategoryByLevel({}); +// result.fold( +// (error) { +// isLoading = false; +// notifyListeners(); +// }, +// (categoryList) { +// // Populate categories and subcategories dynamically +// categories = categoryList; + +// // Populate subcategories for each category +// for (var category in categoryList) { +// if (category.childCategories != null) { +// subcategories[category.name!] = category.childCategories!; +// } + +// if (category.childCategories != null) { +// products[category.name!] = category.childCategories!; +// } +// } + +// isLoading = false; +// notifyListeners(); +// }, +// ); +// } + +// // Load subcategories for a selected category + +// final ImagePicker _picker = ImagePicker(); +// File? _selectedImage; + +// File? get selectedImage => _selectedImage; + +// // Method to pick an image +// Future pickImage(BuildContext context) async { +// final XFile? pickedFile = +// await _picker.pickImage(source: ImageSource.gallery); + +// if (pickedFile != null) { +// _selectedImage = File(pickedFile.path); +// uploadImage(context); +// notifyListeners(); +// } +// } + +// TextEditingController productDescriptionController = TextEditingController(); +// TextEditingController productUnitController = TextEditingController(); +// TextEditingController productPriceController = TextEditingController(); +// TextEditingController productProductDiscountPriceController = +// TextEditingController(); +// TextEditingController productStockController = TextEditingController(); +// TextEditingController productNameController = TextEditingController(); +// TextEditingController productquantityController = TextEditingController(); +// TextEditingController productqlongDescriptionController = +// TextEditingController(); + +// Future createProduct(BuildContext context) async { +// context.showLoader(show: true); + +// try { +// var data = { +// "categoryId": productId, +// "quantity": productquantityController.text, +// "description": productDescriptionController.text, +// "unit": productUnitController.text, +// "basePrice": productPriceController.text, +// "discountPrice": productProductDiscountPriceController.text, +// "isInStock": inStock, +// "stock": int.parse(productStockController.text.isEmpty +// ? '0' +// : productStockController.text), +// "name": selectedProduct!.name, +// "additionalInfo": productqlongDescriptionController.text, +// "productImages": [_uploadedUrl] +// }; + +// print("hjhdfjg ${data}"); +// var result = await _authRepo.createProduct(data); + +// context.showLoader(show: false); + +// return result.fold( +// (error) { +// // Show error Snackbar +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(error.message), +// backgroundColor: Colors.red, +// ), +// ); +// return false; // Login failed +// }, +// (response) { +// // Login success +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Product created successful!"), +// backgroundColor: Colors.green, +// ), +// ); +// return true; +// }, +// ); +// } catch (e) { +// context.showLoader(show: false); +// print("Unexpected error: $e"); + +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Something went wrong. Please try again."), +// backgroundColor: Colors.red, +// ), +// ); +// return false; +// } +// } + +// Future deleteProduct(BuildContext context, String id) async { +// context.showLoader(show: true); + +// try { +// var data = {}; + +// var result = await _authRepo.deleteProduct(data, id); + +// context.showLoader(show: false); + +// return result.fold( +// (error) { +// // Show error Snackbar +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(error.message), +// backgroundColor: Colors.red, +// ), +// ); +// return false; // Login failed +// }, +// (response) { +// _showSnackBar(context, "Product deleted successful!", Colors.green); + +// return true; +// }, +// ); +// } catch (e) { +// context.showLoader(show: false); +// print("Unexpected error: $e"); + +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Something went wrong. Please try again."), +// backgroundColor: Colors.red, +// ), +// ); +// return false; +// } +// } + +// Future updateProduct(BuildContext context, String id) async { +// context.showLoader(show: true); +// print("check stock ${productUnitController.text}"); +// try { +// var data = { +// "quantity": productquantityController.text, +// "description": productDescriptionController.text, +// "unit": productUnitController.text, +// "basePrice": productPriceController.text, +// "discountPrice": productProductDiscountPriceController.text, +// "isInStock": inStock, +// "stock": int.parse(productStockController.text.isEmpty +// ? '0' +// : productStockController.text), +// "name": productNameController!.text, +// "additionalInfo": productqlongDescriptionController.text, +// }; + +// print("check stock ${data}"); + +// var result = await _authRepo.updateProduct(data, id); + +// context.showLoader(show: false); + +// return result.fold( +// (error) { +// // Show error Snackbar +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(error.message), +// backgroundColor: Colors.red, +// ), +// ); +// return false; // Login failed +// }, +// (response) { +// _showSnackBar(context, "Product Updated successful!", Colors.green); + +// return true; +// }, +// ); +// } catch (e) { +// context.showLoader(show: false); +// print("Unexpected error: $e"); + +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text("Something went wrong. Please try again."), +// backgroundColor: Colors.red, +// ), +// ); +// return false; +// } +// } + +// bool isLoadingg = false; +// List products1 = []; + +// Future getProduct() async { +// isLoadingg = true; +// notifyListeners(); + +// final result = await _authRepo.getProduct({}); +// result.fold( +// (error) { +// // Handle error +// isLoadingg = false; +// notifyListeners(); +// }, +// (productList) { +// print("nfjkkjjfgk ${productList}"); +// products1 = productList.data!; +// isLoadingg = false; +// notifyListeners(); +// }, +// ); +// } + +// // Future uploadImage(BuildContext context) async +// // { +// // context.showLoader(show: true); + +// // try { +// // var data = { +// // "image": selectedImage!.path, + +// // }; +// // var result = await _authRepo.uploadImage(data); +// // context.showLoader(show: false); + +// // return result.fold( +// // (error) +// // { +// // // Show error Snackbar +// // ScaffoldMessenger.of(context).showSnackBar( +// // SnackBar( +// // content: Text(error.message), +// // backgroundColor: Colors.red, +// // ), +// // ); +// // return false; // Login failed +// // }, +// // (response) +// // { + +// // print("check thie respodnse ${ response.status}"); + +// // ScaffoldMessenger.of(context).showSnackBar( +// // SnackBar( +// // content: Text("Product created successful!"), +// // backgroundColor: Colors.green, +// // ), +// // ); +// // return true; +// // }, +// // ); +// // } catch (e) { +// // context.showLoader(show: false); +// // print("Unexpected error: $e"); + +// // ScaffoldMessenger.of(context).showSnackBar( +// // SnackBar( +// // content: Text("Something went wrong. Please try again."), +// // backgroundColor: Colors.red, +// // ), +// // ); +// // return false; +// // } +// // } + +// bool _isImageLoading = false; +// bool get isImageLoading => _isImageLoading; + +// String _uploadedUrl = ''; + +// Future uploadImage(BuildContext context) async { +// final result = await _authRepo.uploadImage(selectedImage!); + +// return result.fold( +// (error) { +// // _showSnackBar(context, error.message, Colors.red); +// return false; +// }, +// (uploadImage) { +// _isImageLoading = true; +// _uploadedUrl = uploadImage.data!.url.toString(); +// notifyListeners(); + +// _showSnackBar(context, "Image uploaxded successfully!", Colors.green); +// return true; +// }, +// ); +// } + +// void _showSnackBar(BuildContext context, String message, Color color) { +// showTopSnackBar(context, message, color); +// } +// } diff --git a/lib/src/logic/provider/home_provider.dart b/lib/src/logic/provider/home_provider.dart new file mode 100644 index 0000000..1e72bcf --- /dev/null +++ b/lib/src/logic/provider/home_provider.dart @@ -0,0 +1,61 @@ +// import 'package:flutter/material.dart'; +// import 'package:vendor_app/src/core/network_services/service_locator.dart'; +// import 'package:vendor_app/src/core/utiils_lib/shared_pref_utils.dart'; +// import 'package:vendor_app/src/logic/repo/home_repo.dart'; + +// class HomeProvider extends ChangeNotifier { +// final _homeRepo = getIt(); + +// Future refreshToken(BuildContext context) async { +// var data = {"refresh_token": "${await SharedPrefUtils.getRefreshToken()}"}; + +// var result = await _homeRepo.refreshToken(data, context); +// return result.fold( +// (error) { +// print("dkjhsfgjkdfkg"); +// return true; +// }, +// (response) { +// print("dkjhssfdgdfgdfgfgjkdfkg"); +// return true; +// }, +// ); +// } + +// String _userName = ''; +// String _phone = ''; + +// String get userName => _userName; +// String get phone => _phone; + +// void setUserName(String name) { +// _userName = name; +// notifyListeners(); +// } + +// void setPhone(String phoneNumber) { +// _phone = phoneNumber; +// notifyListeners(); +// } + +// Future getMe() async { +// var data = {}; + +// try { +// var result = await _homeRepo.getMe(data); + +// return result.fold( +// (error) {}, +// (response) { +// setUserName(response.firstName); +// setPhone(response.phone); + +// SharedPrefUtils.USER_NAME = +// response.firstName + " " + response.lastName; +// SharedPrefUtils.PHONE = response.phone; +// notifyListeners(); +// }, +// ); +// } catch (e) {} +// } +// } diff --git a/lib/src/logic/provider/login_provider.dart b/lib/src/logic/provider/login_provider.dart new file mode 100644 index 0000000..431c769 --- /dev/null +++ b/lib/src/logic/provider/login_provider.dart @@ -0,0 +1,225 @@ +import 'package:flutter/material.dart'; +import 'package:grocery_app/src/core/network_services/service_locator.dart'; +import 'package:grocery_app/src/logic/repo/auth_repo.dart'; +import 'package:grocery_app/utils/extensions/extensions.dart'; + + +class LoginProvider extends ChangeNotifier { + final _authRepo = getIt(); + + final TextEditingController passwordController = TextEditingController(); + final TextEditingController emailOrPasswordController = + TextEditingController(); + final TextEditingController phoneController = TextEditingController(); + final TextEditingController newPassword = TextEditingController(); + final TextEditingController confirmsNewPassword = TextEditingController(); + final TextEditingController countryCodes = TextEditingController(); + + String countryCode = ''; + + // Future login(BuildContext context) async { + // context.showLoader(show: true); + + // var data = { + // "phone": "+91" + emailOrPasswordController.text, + // "password": passwordController.text + // }; + + // print("Check request data: $data"); + + // try { + // var result = await _authRepo.login(data); + + // context.showLoader(show: false); + + // return result.fold( + // (error) { + // // Show error Snackbar + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text(error.message), + // backgroundColor: Colors.red, + // ), + // ); + // return false; // Login failed + // }, + // (response) { + // // Login success + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Login successful!"), + // backgroundColor: Colors.green, + // ), + // ); + // return true; + // }, + // ); + // } catch (e) + // { + // context.showLoader(show: false); + + + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Something went wrong. Please try again."), + // backgroundColor: Colors.red, + // ), + // ); + + // return false; + // } + // } + + // Future forgetPassword(BuildContext context, String countryCode) async { + // context.showLoader(show: true); + // countryCodes.text = countryCode; + + // var data = {"phone": countryCode + phoneController.text}; + + // print("Check dddd data: $data"); + + // try { + // var result = await _authRepo.forgetPassword(data); + + // context.showLoader(show: false); + + // return result.fold( + // (error) { + // // Show error Snackbar + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text(error.message), + // backgroundColor: Colors.red, + // ), + // ); + // return false; // Login failed + // }, + // (response) { + // // Login success + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Send Otp successful!"), + // backgroundColor: Colors.green, + // ), + // ); + // return true; + // }, + // ); + // } catch (e) { + // context.showLoader(show: false); + // print("Unexpected error: $e"); + + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Something went wrong. Please try again."), + // backgroundColor: Colors.red, + // ), + // ); + // return false; + // } + // } + + // Future verifyForgetPassword(BuildContext context, String value) async { + // context.showLoader(show: true); + + // var data = { + // "phone": countryCodes.text + phoneController.text, + // "otp": value + // }; + + // print("Check request data: $data"); + + // try { + // var result = await _authRepo.verifyForgetPassword(data); + + // context.showLoader(show: false); + + // return result.fold( + // (error) { + // // Show error Snackbar + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text(error.message), + // backgroundColor: Colors.red, + // ), + // ); + // return false; // Login failed + // }, + // (response) { + // // Login success + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Otp verify successful!"), + // backgroundColor: Colors.green, + // ), + // ); + // return true; + // }, + // ); + // } catch (e) { + // context.showLoader(show: false); + // print("Unexpected error: $e"); + + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Something went wrong. Please try again."), + // backgroundColor: Colors.red, + // ), + // ); + // return false; + // } + // } + + // Future reset_password(BuildContext context) async { + // context.showLoader(show: true); + + // var data = { + // "resetToken": await SharedPrefUtils.getResetToken(), + // "newPassword": newPassword.text + // }; + + // print("Check request data: $data"); + + // try { + // var result = await _authRepo.reset_password(data); + + // context.showLoader(show: false); + + // return result.fold( + // (error) { + // // Show error Snackbar + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text(error.message), + // backgroundColor: Colors.red, + // ), + // ); + // return false; // Login failed + // }, + // (response) { + // // Login success + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Password successfully created!"), + // backgroundColor: Colors.green, + // ), + // ); + // return true; + // }, + // ); + // } catch (e) { + // context.showLoader(show: false); + // print("Unexpected error: $e"); + + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text("Something went wrong. Please try again."), + // backgroundColor: Colors.red, + // ), + // ); + // return false; + // } + // } + + +} diff --git a/lib/src/logic/provider/terms_conditions.dart b/lib/src/logic/provider/terms_conditions.dart new file mode 100644 index 0000000..84f29f7 --- /dev/null +++ b/lib/src/logic/provider/terms_conditions.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +// class TermsNotifier extends ChangeNotifier { + +// bool _isChecked = false; + +// bool get isChecked => _isChecked; + +// void toggleCheckbox(bool value) { +// _isChecked = value; +// notifyListeners(); +// } +// } diff --git a/lib/src/logic/repo/auth_repo.dart b/lib/src/logic/repo/auth_repo.dart new file mode 100644 index 0000000..0efa82c --- /dev/null +++ b/lib/src/logic/repo/auth_repo.dart @@ -0,0 +1,149 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:fpdart/fpdart.dart'; +import 'package:grocery_app/src/core/utils/custom_dio_exception.dart'; +import 'package:grocery_app/src/core/utils/response_type_def.dart'; +import 'package:grocery_app/src/data/OTPResponseModel.dart'; +import 'package:grocery_app/src/data/vendor_otpModel.dart'; +import 'package:grocery_app/src/logic/services/auth_service_locator.dart'; +import 'package:grocery_app/utils/constants/shared_pref_utils.dart'; + + +class AuthRepo { + final AuthServices _authServices; + + AuthRepo(this._authServices); + + FutureResult sendOtp(data) async { + try { + var response = await _authServices.sendOtp(data); + final String model = response.toString(); + // OtpResponseModel otpResponseModel = + // otpResponseModelFromJson(response.toString()); + + return right(model); + } on DioException catch (e) { + print("dhfgfdgjdhfgfgh ${e}"); + var error = CustomDioExceptions.handleError(e); + return left(error); + } + } + + + + FutureResult verifyOtp(data) async { + try { + var response = await _authServices.verifyOtp(data); + + final VendorOtpModel vendorOtpModel = + vendorOtpModelFromJson(response.toString()); + + if (vendorOtpModel.data != null) + { + await SharedPrefUtils.setToken( + authToken: vendorOtpModel.data!.accessToken ?? ""); + } + + // final String model = response.toString(); + + return right(vendorOtpModel); + } on DioException catch (e) { + var error = CustomDioExceptions.handleError(e); + return left(error); + } + } + + // FutureResult login(data) async { + // try { + // var response = await _authServices.login(data); + + // LoginResponse loginResponse = loginResponseFromJson(response.toString()); + // if (loginResponse.accessToken != null) { + // await SharedPrefUtils.setToken( + // authToken: loginResponse.accessToken ?? ""); + // await SharedPrefUtils.setRefreshToken( + // refresh_token: loginResponse.refreshToken ?? ""); + // } + + // print("Response status code: ${response.statusCode}"); + + // return right(loginResponse); + // } on DioException catch (e) { + // print("DioException occurred: $e"); + + // if (e.response != null) { + // int statusCode = e.response!.statusCode ?? 0; + // var errorData = e.response!.data; // Error body from the server + + // String errorMessage = + // errorData['message']['message'] ?? 'Unknown error'; + + // print("Error: $errorMessage (Status Code: $statusCode)"); + + // // Custom error handling + // var error = CustomDioExceptions.handleError(e); + // return left(error); + // } else { + // // Handle other DioExceptions without a response (e.g., network issues) + // var error = CustomDioExceptions.handleError(e); + // return left(error); + // } + // } + // } + + FutureResult customerRegister(data) async { + try { + var response = await _authServices.userRegister(data); + final String model = response.toString(); + return right(model); + } on DioException catch (e) { + var error = CustomDioExceptions.handleError(e); + return left(error); + } + } + + // FutureResult forgetPassword(data) async { + // try { + // var response = await _authServices.forgetPassword(data); + // final String model = response.toString(); + // return right(model); + // } on DioException catch (e) { + // var error = CustomDioExceptions.handleError(e); + // return left(error); + // } + // } + + // FutureResult verifyForgetPassword(data) async { + // try { + // var response = await _authServices.verifyForgetPassword(data); + + // PasswordModel passwordModel = passwordModelFromJson(response.toString()); + // if (passwordModel.data != null) { + // print("JHGhjhg ${passwordModel.data!.resetToken}"); + // await SharedPrefUtils.setResetToken( + // resetToken: passwordModel.data!.resetToken ?? ""); + // } + + // final String model = response.toString(); + // return right(model); + // } on DioException catch (e) { + // var error = CustomDioExceptions.handleError(e); + // return left(error); + // } + // } + + // FutureResult reset_password(data) async { + // try { + // var response = await _authServices.reset_password(data); + // final String model = response.toString(); + // return right(model); + // } on DioException catch (e) { + // var error = CustomDioExceptions.handleError(e); + // return left(error); + // } + // } + + + +} diff --git a/lib/src/logic/repo/home_repo.dart b/lib/src/logic/repo/home_repo.dart new file mode 100644 index 0000000..a8797e7 --- /dev/null +++ b/lib/src/logic/repo/home_repo.dart @@ -0,0 +1,68 @@ +// import 'package:dio/dio.dart'; +// import 'package:flutter/material.dart'; +// import 'package:fpdart/fpdart.dart'; +// import 'package:vendor_app/src/core/routes/routes.dart'; +// import 'package:vendor_app/src/core/utiils_lib/custom_dio_exception.dart'; +// import 'package:vendor_app/src/core/utiils_lib/extensions.dart'; +// import 'package:vendor_app/src/core/utiils_lib/response_type_def.dart'; +// import 'package:vendor_app/src/core/utiils_lib/shared_pref_utils.dart'; +// import 'package:vendor_app/src/data/login_response.dart'; +// import 'package:vendor_app/src/data/vendor_model.dart'; +// import 'package:vendor_app/src/logic/services/home_locator.dart'; + +// class HomeRepo { +// final HomeService _homeService; + +// HomeRepo(this._homeService); + +// FutureResult refreshToken(data, BuildContext context) async { +// try { +// var response = await _homeService.refresh_token(data); +// LoginResponse loginResponse = loginResponseFromJson(response.toString()); + +// if (loginResponse.accessToken != null) { +// print("chwckData ${loginResponse.accessToken}"); +// await SharedPrefUtils.setToken( +// authToken: loginResponse.accessToken ?? ""); +// await SharedPrefUtils.setRefreshToken( +// refresh_token: loginResponse.refreshToken ?? ""); +// } + +// final String model = response.toString(); + +// return right(model); +// } on DioException catch (e) +// { +// context.clearAndPush(routePath: MyRoutes.SELECTACCOUNT); + +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + +// FutureResult getMe(data) async { +// try { +// var response = await _homeService.getMe(data); + +// final VendorModel vendorModel = vendorModelFromJson(response.toString()); + +// if (vendorModel != null) +// { +// SharedPrefUtils.USER_NAME = +// vendorModel.firstName + " " + vendorModel.lastName; +// SharedPrefUtils.PHONE = vendorModel.phone; + +// print("dkfjhdkfhkfk ${SharedPrefUtils.USER_NAME}"); +// await SharedPrefUtils.setStoreId(storeId: vendorModel.storeId ?? ""); + +// } + +// final String model = response.toString(); + +// return right(vendorModel); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } +// } diff --git a/lib/src/logic/repo/product_repo.dart b/lib/src/logic/repo/product_repo.dart new file mode 100644 index 0000000..2d02df3 --- /dev/null +++ b/lib/src/logic/repo/product_repo.dart @@ -0,0 +1,126 @@ +// import 'dart:io'; + +// import 'package:dio/dio.dart'; +// import 'package:fpdart/fpdart.dart'; +// import 'package:vendor_app/src/core/utiils_lib/custom_dio_exception.dart'; +// import 'package:vendor_app/src/core/utiils_lib/response_type_def.dart'; +// import 'package:vendor_app/src/core/utiils_lib/shared_pref_utils.dart'; +// import 'package:vendor_app/src/data/ProductCategoryModel.dart'; +// import 'package:vendor_app/src/data/prdouct_model.dart'; +// import 'package:vendor_app/src/data/upload_image.dart'; +// import 'package:vendor_app/src/data/vendor_otpModel.dart'; +// import 'package:vendor_app/src/logic/services/product_locator.dart'; +// import 'package:vendor_app/src/logic/services/service_locator.dart'; + +// class ProductRepo { +// final ProductService _productServices; + +// ProductRepo(this._productServices); + +// FutureResult getProduct(data) async { +// try { +// var response = await _productServices.getProduct(data); + +// final PrdouctModel prdouctModel = +// prdouctModelFromJson(response.toString()); + +// if (prdouctModel.data!.isNotEmpty) +// { +// print("check data are fetch are note"); +// } + +// // final String model = response.toString(); + +// return right(prdouctModel); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + +// FutureResult> getCategoryByLevel(data) async +// { +// try { +// var response = await _productServices.getCategoryByLevel(data); + +// final List productModels = (response.data as List) +// .map((item) => ProductCategoryModel.fromJson(item)) +// .toList(); +// if (response != null && response.data != null) +// { +// // Parse the response data into a list of ProductCategoryModel +// final List productModels = (response.data as List) +// .map((item) => ProductCategoryModel.fromJson(item)) +// .toList(); + +// // Print or handle the fetched data +// if (productModels.isNotEmpty) +// { +// print( +// "Data successfully fetched and parsed: ${productModels.length} categories."); +// } +// } +// return right(productModels); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + +// FutureResult createProduct(data) async { +// try { +// var response = await _productServices.createProduct(data); +// final String model = response.toString(); + +// return right(model); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + +// FutureResult deleteProduct(data,id) async +// { +// try { +// var response = await _productServices.deleteProduct(data,id); +// final String model = response.toString(); + +// return right(model); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + +// FutureResult updateProduct(data,id) async +// { +// try { +// var response = await _productServices.updateProduct(data,id); +// final String model = response.toString(); + +// return right(model); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + + + + +// FutureResult uploadImage(File imageFile) +// async { +// try { +// final response = await _productServices.uploadImage(imageFile); +// UploadImage upload=uploadImageFromJson(response.toString()); +// return right(upload); +// } on DioException catch (e) { +// final error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + + + + +// } diff --git a/lib/src/logic/repo/store_repo.dart b/lib/src/logic/repo/store_repo.dart new file mode 100644 index 0000000..0098a1d --- /dev/null +++ b/lib/src/logic/repo/store_repo.dart @@ -0,0 +1,72 @@ +// import 'package:dio/dio.dart'; +// import 'package:fpdart/fpdart.dart'; +// import 'package:vendor_app/src/core/utiils_lib/custom_dio_exception.dart'; +// import 'package:vendor_app/src/core/utiils_lib/response_type_def.dart'; +// import 'package:vendor_app/src/data/store_model.dart'; +// import 'package:vendor_app/src/logic/services/store_locator.dart'; + +// class StoreRepo { +// final StoreService _storeService; + +// StoreRepo(this._storeService); + +// FutureResult createStore(data) async { +// try { +// var response = await _storeService.createStore(data); + +// final String model = response.toString(); +// return right(model); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + +// FutureResult updateStore(data) async { +// try { +// var response = await _storeService.updateStore(data); + +// final String model = response.toString(); +// return right(model); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + + + + +// FutureResult getStore(data) async +// { +// try { +// var response = await _storeService.getStore(data); + +// print("objectdjsfngjkdfjjfjb"); +// StoreModel storeModel = storeModelFromJson(response.toString()); +// if (storeModel != null) +// { +// print("objectdjsfngjkdfjjfjbetyrtytryut"); +// } + +// final String model = response.toString(); +// return right(storeModel); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } +// FutureResult vendorLogOut(data) async { +// try { +// var response = await _storeService.logoutVendor(data); + +// final String model = response.toString(); +// return right(model); +// } on DioException catch (e) { +// var error = CustomDioExceptions.handleError(e); +// return left(error); +// } +// } + + +// } diff --git a/lib/src/logic/services/auth_service_locator.dart b/lib/src/logic/services/auth_service_locator.dart new file mode 100644 index 0000000..7358b11 --- /dev/null +++ b/lib/src/logic/services/auth_service_locator.dart @@ -0,0 +1,129 @@ + +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:grocery_app/src/core/constant/api.dart'; +import 'package:grocery_app/src/core/network_services/api_services.dart'; + + + +class AuthServices extends ApiService { + /// Login + Future sendOtp(data) async + { + var response = await api.post(APIURL.sendOtp, data: jsonEncode(data)); + return response; + } + + + + + + Future verifyOtp(data) async { + var response = await api.post(APIURL.verifyOtp, data: jsonEncode(data)); + return response; + } + Future login(data) async + { + var response = await api.post(APIURL.login, data: jsonEncode(data)); + //response.statusCode + + return response; + } + + + + + + Future userRegister(data) async + { + var response = await api.post(APIURL.customerRegister, data: jsonEncode(data)); + return response; + } + + + + + Future forgetPassword(data) async + { + var response = await api.post(APIURL.forgetPassword, data: jsonEncode(data)); + return response; + } + + Future verifyForgetPassword(data) async + { + var response = await api.post(APIURL.verifyForgetPassword, data: jsonEncode(data)); + return response; + } + + + Future reset_password(data) async + { + var response = await api.post(APIURL.reset_password, data: jsonEncode(data)); + return response; + } + + + + + + + + + + + /// Login + // Future profileUpdate(data) async { + // var response = await api.put(Endpoints.update, data: data); + // return response; + // } + + // /// Update badges + // Future updateBadge(data) async { + // var response = await api.put(Endpoints.updateBadge, data: data); + // return response; + // } + + // /// Login + // Future getProfile() async { + // var response = await api.get( + // Endpoints.myProfile, + // ); + // return response; + // } + + // Future getAvatar() async { + // var response = await api.get( + // Endpoints.getAvatar, + // ); + // return response; + // } + + // Future getAllBadge() async { + // var response = await api.get( + // Endpoints.getAllBadge, + // ); + // return response; + // } + + // Future getOtherProfile(data) async { + // var response = + // await api.get(Endpoints.getOtherUserProfile, queryParameters: data); + // return response; + // } + + // setNotificatinStatus(data) async { + // var response = await api.put(Endpoints.notificationSettings, data: data); + // return response; + // } + + // Future reportUser(data) async { + // var response = await api.post(Endpoints.report, data: data); + // return response; + // } + + // Future logOut(data) async { + // var response = await api.post(Endpoints.signOut, data: data); + // return response; + // } +} diff --git a/lib/src/logic/services/home_locator.dart b/lib/src/logic/services/home_locator.dart new file mode 100644 index 0000000..28f357f --- /dev/null +++ b/lib/src/logic/services/home_locator.dart @@ -0,0 +1,27 @@ +// import 'dart:convert'; + +// import 'package:vendor_app/src/core/constant/api.dart'; +// import 'package:vendor_app/src/core/network_services/api_services.dart'; + +// class HomeService extends ApiService { + +// Future getMe(data) async { +// var response = await api.get(APIURL.getMe, data: jsonEncode(data)); +// //response.statusCode + +// return response; +// } + +// Future refresh_token(data) async +// { +// var response = await api.post(APIURL.refresh_token, data: jsonEncode(data)); +// //response.statusCode + +// return response; +// } + + + + + +// } diff --git a/lib/src/logic/services/product_locator.dart b/lib/src/logic/services/product_locator.dart new file mode 100644 index 0000000..c6e98a8 --- /dev/null +++ b/lib/src/logic/services/product_locator.dart @@ -0,0 +1,58 @@ +// import 'dart:convert'; +// import 'dart:io'; + +// import 'package:dio/dio.dart'; +// import 'package:vendor_app/src/core/constant/api.dart'; +// import 'package:vendor_app/src/core/network_services/api_services.dart'; + +// class ProductService extends ApiService { +// // Future createStore(data) async +// // { +// // var response = await api.get(APIURL.createStore, data: jsonEncode(data)); +// // return response; +// // } + +// Future getProduct(data) async { +// var response = await api.get(APIURL.getProduct, data: jsonEncode(data)); +// return response; +// } + +// Future createProduct(data) async { +// var response = await api.post(APIURL.getProduct, data: jsonEncode(data)); +// return response; +// } + +// Future deleteProduct(data, id) async { +// var response = +// await api.delete(APIURL.deleteProduct + id, data: jsonEncode(data)); +// return response; +// } + +// Future updateProduct(data, id) async { +// var response = +// await api.patch(APIURL.updateProduct + id, data: jsonEncode(data)); +// return response; +// } + +// Future getCategoryByLevel(data) async { +// var response = +// await api.get(APIURL.getCategoryByLevel, data: jsonEncode(data)); +// return response; +// } + +// // Future uploadImage(data) async +// // { +// // var response = await api.post(APIURL.uploadImage, data: jsonEncode(data)); +// // return response; +// // } + +// Future uploadImage(File imageFile, +// {Map? additionalFields}) async { +// const String url = APIURL.uploadImage; +// return await api.uploadImage( +// url, +// imageFile, +// additionalFields: additionalFields, +// ); +// } +// } diff --git a/lib/src/logic/services/store_locator.dart b/lib/src/logic/services/store_locator.dart new file mode 100644 index 0000000..0342518 --- /dev/null +++ b/lib/src/logic/services/store_locator.dart @@ -0,0 +1,33 @@ +// import 'dart:convert'; + +// import 'package:vendor_app/src/core/constant/api.dart'; +// import 'package:vendor_app/src/core/network_services/api_services.dart'; +// import 'package:vendor_app/src/core/utiils_lib/shared_pref_utils.dart'; + +// class StoreService extends ApiService { +// Future createStore(data) async { +// var response = await api.post(APIURL.createStore, data: jsonEncode(data)); +// return response; +// } + +// Future getStore(data) async { +// String storeId = "${await SharedPrefUtils.getStoreId()}"; +// print("lkdsjhgjhdfgh ${APIURL.getStore + storeId}"); + +// var response = +// await api.get(APIURL.getStore + storeId, data: jsonEncode(data)); +// return response; +// } + +// Future logoutVendor(data) async { +// var response = await api.post(APIURL.vendorLogOut, data: jsonEncode(data)); +// return response; +// } + +// Future updateStore(data) async { +// var response = await api.patch(APIURL.updateStore, data: jsonEncode(data)); +// return response; +// } + + +// } diff --git a/lib/src/ui/bottomnavigation/bottom_bar_widget.dart b/lib/src/ui/bottomnavigation/bottom_bar_widget.dart index d506f0a..f2ae3c8 100644 --- a/lib/src/ui/bottomnavigation/bottom_bar_widget.dart +++ b/lib/src/ui/bottomnavigation/bottom_bar_widget.dart @@ -1,6 +1,8 @@ // ignore_for_file: library_private_types_in_public_api import 'package:flutter/material.dart'; +import 'package:grocery_app/src/ui/cart/cartview_screen.dart'; +import 'package:grocery_app/src/ui/favourite/favourite_screen.dart'; import 'package:grocery_app/src/ui/home/home_screen.dart'; import 'package:grocery_app/src/ui/profilepage/profile_screen.dart'; import 'package:grocery_app/utils/constants/color_constant.dart'; @@ -25,7 +27,8 @@ class _BottomBarState extends State { }); if (bottomWidgetPageController.hasClients) { - bottomWidgetPageController.animateToPage(index, duration: const Duration(milliseconds: 100), curve: Curves.ease); + bottomWidgetPageController.animateToPage(index, + duration: const Duration(milliseconds: 100), curve: Curves.ease); } } @@ -47,10 +50,10 @@ class _BottomBarState extends State { body: PageView( controller: bottomWidgetPageController, physics: const NeverScrollableScrollPhysics(), - children: const [ + children: [ HomeScreen(), - Text('1'), - Text('2'), + FavouriteScreen(), + Mycart(), ProfileScreen(), ], ), diff --git a/lib/src/ui/cart/cart_item.dart b/lib/src/ui/cart/cart_item.dart new file mode 100644 index 0000000..6614b86 --- /dev/null +++ b/lib/src/ui/cart/cart_item.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:grocery_app/src/common_widget/network_image.dart'; +import 'package:grocery_app/src/ui/widgets/custom_icon_button.dart'; +import 'package:grocery_app/utils/constants/assets_constant.dart'; +import 'package:grocery_app/utils/constants/color_constant.dart'; +import 'package:grocery_app/utils/extensions/uicontext.dart'; + +class CartItem extends StatelessWidget { + // final ProductModel product; + const CartItem({ + Key? key, + // required this.product, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + // final theme = context.theme; + return Padding( + padding: EdgeInsets.symmetric(horizontal: 24.w), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + color: Colors.greenAccent.withOpacity(0.1), + borderRadius: BorderRadius.circular(5), + ), + child: AppNetworkImage( + width: 50.w, + height: 40.h, + imageUrl: + 'https://i.pinimg.com/originals/a5/f3/5f/a5f35fb23e942809da3df91b23718e8d.png', + backGroundColor: APPCOLOR.bgGrey, + radius: 10, + ), + ), + // Image.asset(product.image, width: 50.w, height: 40.h), + + 16.horizontalSpace, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Vegitables and Fruits", + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: context.customMedium(APPCOLOR.balck1A1A1A, 14), + ), + 5.verticalSpace, + Text( + '1kg, 10\$', + style: context.customMedium(APPCOLOR.balck1A1A1A, 14), + ), + ], + ), + const Spacer(), + Row( + children: [ + CustomIconButton( + width: 20.w, + height: 20.h, + onPressed: () {}, + icon: SvgPicture.asset( + APPASSETS.removeIcon, + fit: BoxFit.none, + ), + backgroundColor: APPCOLOR.appGreen, + ), + 16.horizontalSpace, + Text( + "10", + style: context.customMedium(APPCOLOR.balck1A1A1A, 14), + ), + 16.horizontalSpace, + CustomIconButton( + width: 20.w, + height: 20.h, + onPressed: () {}, + icon: SvgPicture.asset( + APPASSETS.addIcon, + fit: BoxFit.none, + ), + backgroundColor: APPCOLOR.appGreen, + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/src/ui/cart/cartview_screen.dart b/lib/src/ui/cart/cartview_screen.dart new file mode 100644 index 0000000..4507bee --- /dev/null +++ b/lib/src/ui/cart/cartview_screen.dart @@ -0,0 +1,244 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:grocery_app/src/common_widget/network_image.dart'; +import 'package:grocery_app/src/ui/bestdeal/bestdeal_screen.dart'; +import 'package:grocery_app/src/ui/cart/cart_item.dart'; +import 'package:grocery_app/src/ui/widgets/custom_icon_button.dart'; +import 'package:grocery_app/utils/constants/assets_constant.dart'; +import 'package:grocery_app/utils/constants/color_constant.dart'; +import 'package:grocery_app/utils/extensions/uicontext.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; + +class Mycart extends StatefulWidget { + const Mycart({super.key}); + + @override + State createState() => _MycartState(); +} + +class _MycartState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + // leading: Center( + // child: SizedBox( + // height: 20, + // width: 20, + // child: InkWell( + // onTap: () { + // Navigator.of(context).pop(); + // }, + // child: SvgPicture.asset( + // APPASSETS.back, + // height: 20, + // width: 20, + // )), + // ), + // ), + title: Center( + child: const Text( + 'Cart 🛒', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w700, + ), + ), + ), + // actions: [ + // InkWell( + // onTap: () {}, + // child: Icon( + // MdiIcons.magnify, + // size: 35, + // ), + // ) + // ], + ), + body: Column( + children: [ + Expanded( + child: ListView.separated( + separatorBuilder: (_, index) => Padding( + padding: EdgeInsets.only(top: 12.h, bottom: 24.h), + child: const Divider(thickness: 1), + ), + itemCount: 10, + itemBuilder: (context, index) => CartItem( + //product: controller.products[index], + ) + .animate(delay: (100 * index).ms) + .fade() + .slideX( + duration: 300.ms, + begin: -1, + curve: Curves.easeInSine, + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Text( + "Best Deal", + style: context.customExtraBold(Colors.black, 18), + ), + ), + InkWell( + onTap: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) { + return const BestDealScreen(); + }, + )); + }, + child: Text( + "See All", + style: context.customMedium(APPCOLOR.lightGreen, 16), + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + SizedBox( + height: 222, + child: ListView.builder( + itemCount: 5, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.only(right: 10, bottom: 5, top: 5), + child: Container( + height: 215, + width: 150, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + blurRadius: 1, + offset: const Offset(5, 5), + ), + ]), + child: Padding( + padding: const EdgeInsets.all(5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 100, + width: 150, + decoration: BoxDecoration( + color: APPCOLOR.bgGrey, + borderRadius: BorderRadius.circular(15)), + child: const Stack( + alignment: Alignment.center, + children: [ + AppNetworkImage( + height: 70, + width: 70, + imageUrl: + "https://5.imimg.com/data5/SELLER/Default/2024/2/385126988/OL/DA/VW/8627346/1l-fortune-sunflower-oil.jpg", + backGroundColor: Colors.transparent), + Positioned( + right: 5, + top: 5, + child: Icon(Icons.favorite_border)) + ], + ), + ), + Text( + "Fortune Arhar Dal (Toor Dal)", + textAlign: TextAlign.left, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: + context.customMedium(APPCOLOR.balck1A1A1A, 14), + ), + const SizedBox( + height: 5, + ), + Text( + "500 ML", + textAlign: TextAlign.left, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: context.customMedium( + Colors.grey.withOpacity(0.8), 12), + ), + const SizedBox( + height: 3, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + "\$12", + textAlign: TextAlign.left, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: context.customSemiBold( + Colors.black, 12), + ), + const SizedBox( + width: 5, + ), + Text( + "\$14", + textAlign: TextAlign.left, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: context + .customMedium( + Colors.grey.withOpacity(0.8), 12) + .copyWith( + decoration: + TextDecoration.lineThrough, + ), + ), + ], + )), + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Container( + height: 30, + width: 50, + decoration: BoxDecoration( + color: APPCOLOR.lightGreen, + borderRadius: BorderRadius.circular(5), + ), + child: Center( + child: Text( + 'Add', + style: context.customRegular( + Colors.white, 12), + )), + ), + ), + ) + ], + ), + ], + ), + ), + ), + ); + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/ui/entername/enter_fullname_screen.dart b/lib/src/ui/entername/enter_fullname_screen.dart index 4049e21..90a26e1 100644 --- a/lib/src/ui/entername/enter_fullname_screen.dart +++ b/lib/src/ui/entername/enter_fullname_screen.dart @@ -3,12 +3,14 @@ import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; import 'package:grocery_app/src/common_widget/textfield_widget.dart'; import 'package:grocery_app/src/core/routes/routes.dart'; +import 'package:grocery_app/src/logic/provider/auth_provider.dart'; import 'package:grocery_app/src/ui/bottomnavigation/bottom_bar_widget.dart'; import 'package:grocery_app/utils/constants/assets_constant.dart'; import 'package:grocery_app/utils/constants/color_constant.dart'; import 'package:grocery_app/utils/constants/string_constant.dart'; import 'package:grocery_app/utils/extensions/extensions.dart'; import 'package:grocery_app/utils/extensions/uicontext.dart'; +import 'package:provider/provider.dart'; class EnterFullNameScreen extends StatefulWidget { const EnterFullNameScreen({super.key}); @@ -23,6 +25,9 @@ class _EnterFullNameScreenState extends State { final _formKey = GlobalKey(); @override Widget build(BuildContext context) { + + final pageNotifier = Provider.of(context, listen: false); + return Scaffold( body: Container( width: MediaQuery.sizeOf(context).width, @@ -53,7 +58,7 @@ class _EnterFullNameScreenState extends State { child: Column( children: [ AppTextFieldWidget( - controller: TextEditingController(), + controller: pageNotifier.name, hintText: APPSTRING.firstNameHint, onValidate: (value){ if (value == null || value.isEmpty) { @@ -63,7 +68,7 @@ class _EnterFullNameScreenState extends State { }, ), AppTextFieldWidget( - controller: TextEditingController(), + controller: pageNotifier.lastName, hintText: APPSTRING.lastNameHint, onValidate: (value){ if (value == null || value.isEmpty) { @@ -72,6 +77,28 @@ class _EnterFullNameScreenState extends State { return null; }, ), + + AppTextFieldWidget( + controller: pageNotifier.email, + hintText: APPSTRING.emailHint, + onValidate: (value) { + if (value == null || value.isEmpty) { + return 'Please Enter eamil-id'; + } + return null; + }, + ), + AppTextFieldWidget( + controller: pageNotifier.address, + hintText: APPSTRING.addressHint, + onValidate: (value) { + if (value == null || value.isEmpty) + { + return 'Please Enter address'; + } + return null; + }, + ), ], ), ) @@ -88,11 +115,13 @@ class _EnterFullNameScreenState extends State { padding: context.bodyAllPadding.copyWith(bottom: 20), child: Center( child: InkWell( - onTap: () { + onTap: () + { - if (_formKey.currentState?.validate() ?? false) { - context.clearAndPush( routePath: MyRoutes.BOTTOMNAV); - } + if (_formKey.currentState?.validate() ?? false) + { + context.clearAndPush( routePath: MyRoutes.BOTTOMNAV); + } diff --git a/lib/src/ui/favourite/favourite_screen.dart b/lib/src/ui/favourite/favourite_screen.dart new file mode 100644 index 0000000..e25b12e --- /dev/null +++ b/lib/src/ui/favourite/favourite_screen.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; +import 'package:grocery_app/src/common_widget/network_image.dart'; +import 'package:grocery_app/src/data/product_model.dart'; +import 'package:grocery_app/src/ui/widgets/custom_title.dart'; +import 'package:grocery_app/utils/constants/color_constant.dart'; + +class FavouriteScreen extends StatefulWidget { + @override + _FavouriteScreenState createState() => _FavouriteScreenState(); +} + +class _FavouriteScreenState extends State + with SingleTickerProviderStateMixin { + late AnimationController _animationController; + late Animation _animation; + + List _favProducts = [ + ProductModel("", 'Bell pepper red', '7pcs', '\$4.99'), + ProductModel("", 'Ginger', '1kg', '\$4.99'), + ProductModel("", 'Egg pasta', '30gm', '\$15.9'), + ]; + + @override + void initState() { + _animationController = AnimationController( + duration: const Duration(milliseconds: 1000), + vsync: this, + ); + super.initState(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + CustomTitle(title: 'Favourite'), + Expanded( + child: ListView.separated( + itemCount: _favProducts.length, + shrinkWrap: true, + padding: const EdgeInsets.all(16), + itemBuilder: (_, index) + { + _animation = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: _animationController, + curve: Interval( + (0.5 / _favProducts.length) * index, + 1, + curve: Curves.easeOut, + ), + ), + ); + _animationController.forward(from: 0); + + return AnimatedBuilder( + animation: _animationController, + builder: (_, child) { + return FadeTransition( + opacity: _animation, + child: Transform( + transform: Matrix4.translationValues( + 0.0, + 50 * (1.0 - _animation.value), + 0.0, + ), + child: child, + ), + ); + }, + child: ListTile( + onTap: () {}, + leading: Container( + decoration: BoxDecoration( + color: Colors.greenAccent.withOpacity(0.1), + borderRadius: BorderRadius.circular(5), + ), + child: AppNetworkImage( + height: 80, + width: 80, + imageUrl: + 'https://i.pinimg.com/originals/a5/f3/5f/a5f35fb23e942809da3df91b23718e8d.png', + backGroundColor: APPCOLOR.bgGrey, + radius: 10, + ), + ), + // Image.asset(_favProducts[index].productImage), + title: Text(_favProducts[index].productName), + subtitle: Text(_favProducts[index].quantity), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(_favProducts[index].amount), + Icon( + Icons.navigate_next_rounded, + size: 32, + color: APPCOLOR.gray, + ) + ], + ), + ), + ); + }, + separatorBuilder: (_, index) { + _animation = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: _animationController, + curve: Interval( + (0.5 / _favProducts.length) * index, + 1, + curve: Curves.easeOut, + ), + ), + ); + _animationController.forward(from: 0); + return AnimatedBuilder( + animation: _animationController, + builder: (_, child) { + return FadeTransition( + opacity: _animation, + child: Transform( + transform: Matrix4.translationValues( + 0.0, + 50 * (1.0 - _animation.value), + 0.0, + ), + child: child, + ), + ); + }, + child: Divider(), + ); + }, + ), + ), + // Padding( + // padding: + // const EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 78), + // child: NectarButton( + // onPressed: () {}, + // text: 'Add All To Cart', + // ), + // ), + ], + ); + } +} diff --git a/lib/src/ui/login/login_screen.dart b/lib/src/ui/login/login_screen.dart index f846b3e..182287f 100644 --- a/lib/src/ui/login/login_screen.dart +++ b/lib/src/ui/login/login_screen.dart @@ -2,10 +2,12 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:grocery_app/src/common_widget/textfield_widget.dart'; import 'package:grocery_app/src/core/routes/routes.dart'; +import 'package:grocery_app/src/logic/provider/auth_provider.dart'; import 'package:grocery_app/src/ui/otp/otp_screen.dart'; import 'package:grocery_app/utils/constants/color_constant.dart'; import 'package:grocery_app/utils/constants/string_constant.dart'; import 'package:grocery_app/utils/extensions/uicontext.dart'; +import 'package:provider/provider.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @@ -15,6 +17,8 @@ class LoginScreen extends StatefulWidget { } class _LoginScreenState extends State { + TextEditingController phoneController = TextEditingController(); + String? validatePhoneNumber(String? value) { if (value == null || value.isEmpty) { return 'Phone number cannot be empty'; @@ -27,6 +31,8 @@ class _LoginScreenState extends State { final _formKey = GlobalKey(); @override Widget build(BuildContext context) { + final pageNotifier = Provider.of(context, listen: false); + return Scaffold( body: Container( width: MediaQuery.sizeOf(context).width, @@ -62,7 +68,7 @@ class _LoginScreenState extends State { key: _formKey, child: AppTextFieldWidget( length: 10, - controller: TextEditingController(), + controller: phoneController, hintText: APPSTRING.phoneNumberHint, onValidate: (value) => validatePhoneNumber(value), ), @@ -80,18 +86,26 @@ class _LoginScreenState extends State { padding: context.bodyAllPadding.copyWith(bottom: 20), child: Center( child: InkWell( - onTap: () { - print("djkhfjdgf ${_formKey.currentState?.validate()}"); - if (_formKey.currentState?.validate() ?? false) - { - context.push(MyRoutes.OTPSCREEN); + onTap: () async { + if (_formKey.currentState?.validate() ?? false) { + final success = + await pageNotifier.sendOtp(phoneController.text, context); - // Navigator.of(context).push(MaterialPageRoute( - // builder: (context) - // { - // return const OtpScreen(); - // }, - // )); + if (success) { + context.push(MyRoutes.OTPSCREEN); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Failed to send OTP. Please try again."), + ), + ); + } + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("Enter a valid 10-digit phone number."), + ), + ); } }, child: Container( diff --git a/lib/src/ui/mapscreen/map_screen.dart b/lib/src/ui/mapscreen/map_screen.dart index 85c3239..5064e65 100644 --- a/lib/src/ui/mapscreen/map_screen.dart +++ b/lib/src/ui/mapscreen/map_screen.dart @@ -32,7 +32,8 @@ class _MapScreenState extends State { APPASSETS.back, height: 20, width: 20, - )), + ) + ), ), ), title: const Text( diff --git a/lib/src/ui/onboarding/on_boarding_screen.dart b/lib/src/ui/onboarding/on_boarding_screen.dart index 0ff3eae..4940c6f 100644 --- a/lib/src/ui/onboarding/on_boarding_screen.dart +++ b/lib/src/ui/onboarding/on_boarding_screen.dart @@ -25,10 +25,9 @@ class _OnBoardingScreenState extends State { _pageController.nextPage(duration: _kDuration, curve: _kCurve); } - skipFunction() - { + skipFunction() { SharedPrefUtils.setFreshInstall(isFresh: false).then( - (value) => context.clearAndPush(routePath: MyRoutes.LOGIN, args: 0), + (value) => context.clearAndPush(routePath: MyRoutes.BOTTOMNAV, args: 0), ); // Navigator.pushReplacement(context, MaterialPageRoute( @@ -79,12 +78,12 @@ class _OnBoardingScreenState extends State { children: [ Stack( children: [ + Image.asset(APPASSETS.onBoardMan), Positioned( - top: 10, + top: 20, right: 0, - child: InkWell( + child: GestureDetector( onTap: () { - print("djfhgk"); skipFunction(); }, child: Row( @@ -95,15 +94,14 @@ class _OnBoardingScreenState extends State { style: context.customMedium(APPCOLOR.appGreen, 14), ), - const SizedBox( - width: 10, - ), + const SizedBox(width: 10), Container( height: 35, width: 35, decoration: BoxDecoration( - color: APPCOLOR.appGreen, - borderRadius: BorderRadius.circular(90)), + color: APPCOLOR.appGreen, + borderRadius: BorderRadius.circular(90), + ), child: const Center( child: Icon( Icons.arrow_forward, @@ -116,7 +114,6 @@ class _OnBoardingScreenState extends State { ), ), ), - Image.asset(APPASSETS.onBoardMan), Positioned( bottom: 100, right: 0, diff --git a/lib/src/ui/otp/otp_screen.dart b/lib/src/ui/otp/otp_screen.dart index c60d91e..845e538 100644 --- a/lib/src/ui/otp/otp_screen.dart +++ b/lib/src/ui/otp/otp_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; +import 'package:grocery_app/src/logic/provider/auth_provider.dart'; import 'package:grocery_app/src/ui/entername/enter_fullname_screen.dart'; import 'package:grocery_app/utils/constants/assets_constant.dart'; import 'package:grocery_app/utils/constants/color_constant.dart'; @@ -9,6 +10,7 @@ import 'package:grocery_app/utils/extensions/color_ex.dart'; import 'package:grocery_app/utils/extensions/uicontext.dart'; import 'package:otp_text_field/otp_text_field.dart'; import 'package:otp_text_field/style.dart'; +import 'package:provider/provider.dart'; import '../../core/routes/routes.dart'; @@ -20,8 +22,22 @@ class OtpScreen extends StatefulWidget { } class _OtpScreenState extends State { + String maskNumber(String number) { + // Ensure the input has at least 4 digits to avoid errors + if (number.length < 4) { + throw Exception('Number is too short to mask'); + } + + // Replace all characters except the last 4 with '*' + String maskedPart = '*' * (number.length - 4); + String visiblePart = number.substring(number.length - 4); + return maskedPart + visiblePart; + } + @override Widget build(BuildContext context) { + final pageNotifier = Provider.of(context, listen: false); + return Scaffold( body: Container( width: MediaQuery.sizeOf(context).width, @@ -49,7 +65,7 @@ class _OtpScreenState extends State { SizedBox( width: 300, child: Text( - APPSTRING.enterCode, + "Enter the 6-digit code sent to you at ${maskNumber(pageNotifier.numberwithCode)}", style: context.customRegular(APPCOLOR.grey666666, 16), ), ), @@ -57,16 +73,12 @@ class _OtpScreenState extends State { OTPTextField( length: 6, onChanged: (c) { - if (c.length == 6) - { - context.push(MyRoutes.FULLNAME); - - // Navigator.push(context, MaterialPageRoute( - // builder: (context) - // { - // return const EnterFullNameScreen(); - // }, - // )); + if (c.length == 6) { + Navigator.push(context, MaterialPageRoute( + builder: (context) { + return const EnterFullNameScreen(); + }, + )); } }, width: MediaQuery.of(context).size.width, @@ -77,7 +89,20 @@ class _OtpScreenState extends State { style: const TextStyle(fontSize: 17), textFieldAlignment: MainAxisAlignment.spaceBetween, fieldStyle: FieldStyle.box, - onCompleted: (pin) {}, + onCompleted: (pin) async { + final success = await pageNotifier.verifiOtp(pin, context); + + if (success) { + context.push(MyRoutes.FULLNAME); + } else { + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // backgroundColor: Colors.grey, + // content: Text("Failed to send OTP. Please try again."), + // ), + // ); + } + }, ), const SizedBox( height: 10, diff --git a/lib/src/ui/widgets/custom_icon_button.dart b/lib/src/ui/widgets/custom_icon_button.dart new file mode 100644 index 0000000..fa913bd --- /dev/null +++ b/lib/src/ui/widgets/custom_icon_button.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:grocery_app/utils/constants/color_constant.dart'; + +class CustomIconButton extends StatelessWidget { + final Function()? onPressed; + final Widget? icon; + final Color? backgroundColor; + final Color? borderColor; + final double? width; + final double? height; + const CustomIconButton({ + Key? key, + required this.onPressed, + required this.icon, + this.backgroundColor, + this.borderColor, + this.width, + this.height, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: width ?? 44.w, + height: height ?? 44.h, + child: Material( + color: backgroundColor, + shape: borderColor == null + ? const CircleBorder() + : CircleBorder( + side: BorderSide(color: borderColor!), + ), + child: InkWell( + onTap: onPressed, + child: icon, + highlightColor: Colors.red, + customBorder: const CircleBorder(), + ), + ), + ); + } +} diff --git a/lib/src/ui/widgets/custom_title.dart b/lib/src/ui/widgets/custom_title.dart new file mode 100644 index 0000000..18738e2 --- /dev/null +++ b/lib/src/ui/widgets/custom_title.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:grocery_app/utils/extensions/uicontext.dart'; + +class CustomTitle extends StatelessWidget { + final String title; + const CustomTitle({ + Key? key, + required this.title, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return SafeArea( + bottom: false, + child: Column( + children: [ + const SizedBox(height: 8), + Text( + title, + style: context.customExtraBold(Colors.black, 18), + ), + const SizedBox(height: 24), + Divider(), + ], + ), + ); + } +} diff --git a/lib/utils/constants/assets_constant.dart b/lib/utils/constants/assets_constant.dart index 302bfee..51e1ad2 100644 --- a/lib/utils/constants/assets_constant.dart +++ b/lib/utils/constants/assets_constant.dart @@ -4,6 +4,8 @@ class APPASSETS { //SVG static const String back = "$svgBaseUrl/back.svg"; + static const String removeIcon = "$svgBaseUrl/remove.svg"; + static const String addIcon = '$svgBaseUrl/add.svg'; //PNG static const String splashImagePNG = "$pngBaseUrl/splash.png"; static const String onBoardMan = "$pngBaseUrl/onboard_man.png"; diff --git a/lib/utils/constants/color_constant.dart b/lib/utils/constants/color_constant.dart index 306b09f..c66cea4 100644 --- a/lib/utils/constants/color_constant.dart +++ b/lib/utils/constants/color_constant.dart @@ -12,4 +12,5 @@ class APPCOLOR { static Color gery48514D = HexColor('48514D'); static Color lightGreyF4F5F5 = HexColor('F7FDF7'); static Color bgGrey = Colors.grey.withOpacity(0.0500); + static const Color gray = const Color(0xFFB3B3B3); } diff --git a/lib/utils/constants/string_constant.dart b/lib/utils/constants/string_constant.dart index cc382d7..0ba9697 100644 --- a/lib/utils/constants/string_constant.dart +++ b/lib/utils/constants/string_constant.dart @@ -13,6 +13,9 @@ class APPSTRING { static const String firstNameHint = "First Name"; static const String lastNameHint = "last Name"; + static const String emailHint = "Email-ID"; + static const String addressHint = "Address"; + //button static const String verifyButton = "Verify"; static const String continueBtn = "Continue"; diff --git a/lib/utils/extensions/extensions.dart b/lib/utils/extensions/extensions.dart index 4511b09..75fb05d 100644 --- a/lib/utils/extensions/extensions.dart +++ b/lib/utils/extensions/extensions.dart @@ -212,7 +212,8 @@ extension ContextExtension on BuildContext { } /// show global loader - void showLoader({bool show = true}) { + void showLoader({bool show = true}) + { if (mounted) { if (show) { loaderOverlay.show(); diff --git a/pubspec.lock b/pubspec.lock index 4f1a2a1..9723b2c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animation_list: + dependency: "direct main" + description: + name: animation_list + sha256: "5d193f53a6616dc6496eb7eff297da84a6f18c1c042412bbfe05dfc8be7be926" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + animations: + dependency: "direct main" + description: + name: animations + sha256: d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb + url: "https://pub.dev" + source: hosted + version: "2.0.11" args: dependency: transitive description: @@ -198,6 +214,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_animate: + dependency: "direct main" + description: + name: flutter_animate + sha256: "7befe2d3252728afb77aecaaea1dec88a89d35b9b1d2eea6d04479e8af9117b5" + url: "https://pub.dev" + source: hosted + version: "4.5.2" flutter_cache_manager: dependency: transitive description: @@ -222,6 +246,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.9.3" + flutter_shaders: + dependency: transitive + description: + name: flutter_shaders + sha256: "34794acadd8275d971e02df03afee3dee0f98dbfb8c4837082ad0034f612a3e2" + url: "https://pub.dev" + source: hosted + version: "0.1.3" flutter_svg: dependency: "direct main" description: @@ -256,6 +288,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + gap: + dependency: "direct main" + description: + name: gap + sha256: f19387d4e32f849394758b91377f9153a1b41d79513ef7668c088c77dbc6955d + url: "https://pub.dev" + source: hosted + version: "3.0.1" get_it: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index eff1960..d4290cf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,12 @@ dependencies: loader_overlay: ^4.0.0 provider: any + gap: ^3.0.1 + + flutter_animate: + + animations: ^2.0.1 + animation_list: ^3.1.0