From 410c8903aee6d53f2af079f9de7b20d430ef447b Mon Sep 17 00:00:00 2001 From: saritabirare Date: Fri, 20 Sep 2024 15:38:21 +0530 Subject: [PATCH] 1)Push notification added --- android/settings.gradle | 4 + lib/controller/notification_api_service.dart | 36 ++++ lib/controller/notification_controller.dart | 50 +++++ lib/controller/product_mannual_service.dart | 4 +- lib/controller/product_service.dart | 6 +- lib/main.dart | 15 ++ lib/models/notification_model.dart | 67 +++++++ lib/notification_service.dart | 165 ++++++++++++++++ lib/screens/home_screen.dart | 182 +++++++++++------- .../inventory_management_screen.dart | 2 +- .../notification/notification_screen.dart | 131 +++++++++++++ lib/screens/order/checkout_screen.dart | 2 +- .../order/order_confermation_screen.dart | 2 +- lib/screens/order/order_detail_screen.dart | 2 +- lib/screens/order/order_tracking_screen.dart | 2 +- .../order/shipment_tracking_screen.dart | 2 +- .../order_management_screen.dart | 2 +- lib/screens/product/cart_screen.dart | 2 +- .../product/product_catalog_screen.dart | 2 +- .../product/product_detail_screen.dart | 2 +- lib/screens/product/product_mannual.dart | 1 + lib/utils/common_api_service.dart | 8 +- lib/utils/secure__storage_service.dart | 37 ++++ lib/widgets/common_appbar.dart | 5 +- 24 files changed, 646 insertions(+), 85 deletions(-) create mode 100644 lib/controller/notification_api_service.dart create mode 100644 lib/controller/notification_controller.dart create mode 100644 lib/models/notification_model.dart create mode 100644 lib/notification_service.dart create mode 100644 lib/screens/notification/notification_screen.dart create mode 100644 lib/utils/secure__storage_service.dart diff --git a/android/settings.gradle b/android/settings.gradle index 536165d..5959482 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -19,6 +19,10 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.3.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + id "com.google.firebase.crashlytics" version "2.8.1" apply false + // END: FlutterFire Configuration id "org.jetbrains.kotlin.android" version "1.7.10" apply false } diff --git a/lib/controller/notification_api_service.dart b/lib/controller/notification_api_service.dart new file mode 100644 index 0000000..24f07d3 --- /dev/null +++ b/lib/controller/notification_api_service.dart @@ -0,0 +1,36 @@ +import 'package:cheminova/models/notification_model.dart'; +import 'package:cheminova/utils/api_urls.dart'; + +import '../utils/common_api_service.dart'; + +class NotificationApiService { + Future?> getNotification(String token) async { + try { + String url =ApiUrls.getNotificationUrl; // Base URL to fetch product manuals + + final response = await commonApiService>( + method: "GET", + url: url, + additionalHeaders: { // Pass the token here + 'Authorization': 'Bearer $token', + }, + fromJson: (json) { + if (json['notifications'] != null) { + // Map the list of product manuals from the response + final List notification = (json['notifications'] as List) + .map((manualJson) => NotificationModel.fromJson(manualJson as Map)) + .toList(); + return notification; + } else { + return []; + } + }, + ); + return response; + } catch (e) { + + print(e.toString()); + return null; + } + } +} diff --git a/lib/controller/notification_controller.dart b/lib/controller/notification_controller.dart new file mode 100644 index 0000000..1c602f1 --- /dev/null +++ b/lib/controller/notification_controller.dart @@ -0,0 +1,50 @@ +import 'package:cheminova/controller/notification_api_service.dart'; +import 'package:cheminova/controller/product_mannual_service.dart'; +import 'package:cheminova/models/notification_model.dart'; +import 'package:cheminova/notification_service.dart'; +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import '../models/product_mannual_model.dart'; // Your model import +// Your service import + +class NotificationController extends GetxController { + + var notificationList = [].obs; + + // Service to fetch data + final NotificationApiService notificationApiService = NotificationApiService(); + + // Loading state + var isLoading = false.obs; + + // Method to fetch product manuals from the service + void fetchNotificationApiService() async { + try { + // Set loading to true + isLoading.value = true; + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + var manuals = await notificationApiService.getNotification(token!); + + // If data is returned, update the list + if (manuals != null) { + notificationList .value = manuals; + } else { + notificationList.value = []; // If no data, set an empty list + } + } catch (e) { + // Handle error here, for example logging or showing an error message + print("Error fetching product manuals: $e"); + } finally { + // Set loading to false + isLoading.value = false; + } + } + + @override + void onInit() { + // Fetch product manuals when the controller is initialized + fetchNotificationApiService(); + super.onInit(); + } +} diff --git a/lib/controller/product_mannual_service.dart b/lib/controller/product_mannual_service.dart index 937835c..3580a4a 100644 --- a/lib/controller/product_mannual_service.dart +++ b/lib/controller/product_mannual_service.dart @@ -1,12 +1,14 @@ +import 'package:cheminova/utils/api_urls.dart'; + import '../models/product_mannual_model.dart'; import '../utils/common_api_service.dart'; // Replace with your actual common API service import class ProductMannualService { Future?> getProductManuals(String token) async { try { - String url = "/api/productmanual/getall"; // Base URL to fetch product manuals + String url = ApiUrls.getProductManualUrl; // Base URL to fetch product manuals final response = await commonApiService>( method: "GET", diff --git a/lib/controller/product_service.dart b/lib/controller/product_service.dart index b9796cb..c0734d7 100644 --- a/lib/controller/product_service.dart +++ b/lib/controller/product_service.dart @@ -1,3 +1,5 @@ +import 'package:cheminova/utils/api_urls.dart'; + import '../models/product_model1.dart'; import '../utils/common_api_service.dart'; import '../utils/show_snackbar.dart'; @@ -7,7 +9,7 @@ class ProductService { try { String url; if (category != null && category.isNotEmpty) { - url = "/api/product/getAll/user?page=$page&category=$category"; + url = "ApiUrls.getProductUrl?page=$page&category=$category"; } else { url = "/api/product/getAll/user?page=$page"; // URL without category filter } @@ -39,7 +41,7 @@ class ProductService { try { final response = await commonApiService>>( method: "GET", - url: "/api/category/getCategories", + url: ApiUrls.getCategoryUrl, fromJson: (json) { if (json['categories'] != null) { final List> category = (json['categories'] as List) diff --git a/lib/main.dart b/lib/main.dart index 57040fd..c15bce6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,23 @@ import 'package:cheminova/screens/splash_screen.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:hive_flutter/adapters.dart'; +import 'firebase_options.dart'; + +var box; void main()async{ + + WidgetsFlutterBinding.ensureInitialized(); + + + + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + await Hive.initFlutter(); + await Hive.openBox('cartBox'); runApp(const MyApp()); } diff --git a/lib/models/notification_model.dart b/lib/models/notification_model.dart new file mode 100644 index 0000000..d39c8e2 --- /dev/null +++ b/lib/models/notification_model.dart @@ -0,0 +1,67 @@ +class NotificationModel { + String? id; + String? title; + String? msg; + String? addedFor; + String? createdAt; + String? updatedAt; + int? v; + + NotificationModel({ + this.id, + this.title, + this.msg, + this.addedFor, + this.createdAt, + this.updatedAt, + this.v, + }); + + factory NotificationModel.fromJson(Map json) { + return NotificationModel( + id: json['_id'], + title: json['title'], + msg: json['msg'], + addedFor: json['added_for'], + createdAt: json['createdAt'], + updatedAt: json['updatedAt'], + v: json['__v'], + ); + } + + Map toJson() { + return { + '_id': id, + 'title': title, + 'msg': msg, + 'added_for': addedFor, + 'createdAt': createdAt, + 'updatedAt': updatedAt, + '__v': v, + }; + } +} + +class NotificationResponse { + String? returnMessage; + List? notifications; + + NotificationResponse({this.returnMessage, this.notifications}); + + factory NotificationResponse.fromJson(Map json) { + return NotificationResponse( + returnMessage: json['return_message'], + notifications: json['notifications'] != null + ? List.from(json['notifications'] + .map((notification) => NotificationModel.fromJson(notification))) + : null, + ); + } + + Map toJson() { + return { + 'return_message': returnMessage, + 'notifications': notifications?.map((notification) => notification.toJson()).toList(), + }; + } +} diff --git a/lib/notification_service.dart b/lib/notification_service.dart new file mode 100644 index 0000000..51d9a35 --- /dev/null +++ b/lib/notification_service.dart @@ -0,0 +1,165 @@ +import 'dart:io'; + +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; + +class NotificationServices { + //initialising firebase message plugin + FirebaseMessaging messaging = FirebaseMessaging.instance; + + //initialising firebase message plugin + final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); + + //function to initialise flutter local notification plugin to show notifications for android when app is active + void initLocalNotifications( + BuildContext context, RemoteMessage message) async { + var androidInitializationSettings = + const AndroidInitializationSettings('@mipmap/ic_launcher'); + var iosInitializationSettings = const DarwinInitializationSettings(); + + var initializationSetting = InitializationSettings( + android: androidInitializationSettings, iOS: iosInitializationSettings); + + await _flutterLocalNotificationsPlugin.initialize(initializationSetting, + onDidReceiveNotificationResponse: (payload) { + // handle interaction when app is active for android + handleMessage(context, message); + }); + } + + void firebaseInit(BuildContext context) { + FirebaseMessaging.onMessage.listen((message) { + RemoteNotification? notification = message.notification; + AndroidNotification? android = message.notification!.android; + + if (kDebugMode) { + print("notifications title:${notification!.title}"); + print("notifications body:${notification.body}"); + print('count:${android!.count}'); + print('data:${message.data.toString()}'); + } + + if (Platform.isIOS) { + forgroundMessage(); + } + + if (Platform.isAndroid) { + initLocalNotifications(context, message); + showNotification(message); + } + }); + } + + void requestNotificationPermission() async { + NotificationSettings settings = await messaging.requestPermission( + alert: true, + announcement: true, + badge: true, + carPlay: true, + criticalAlert: true, + provisional: true, + sound: true, + ); + + if (settings.authorizationStatus == AuthorizationStatus.authorized) { + if (kDebugMode) { + print('user granted permission'); + } + } else if (settings.authorizationStatus == + AuthorizationStatus.provisional) { + if (kDebugMode) { + print('user granted provisional permission'); + } + } else { + //appsetting.AppSettings.openNotificationSettings(); + if (kDebugMode) { + print('user denied permission'); + } + } + } + + // function to show visible notification when app is active + Future showNotification(RemoteMessage message) async { + AndroidNotificationChannel channel = AndroidNotificationChannel( + message.notification!.android!.channelId.toString(), + message.notification!.android!.channelId.toString(), + importance: Importance.max, + showBadge: true, + playSound: true, + sound: const RawResourceAndroidNotificationSound('jetsons_doorbell')); + + AndroidNotificationDetails androidNotificationDetails = + AndroidNotificationDetails( + channel.id.toString(), channel.name.toString(), + channelDescription: 'your channel description', + importance: Importance.high, + priority: Priority.high, + playSound: true, + ticker: 'ticker', + sound: channel.sound + // sound: RawResourceAndroidNotificationSound('jetsons_doorbell') + // icon: largeIconPath + ); + + const DarwinNotificationDetails darwinNotificationDetails = + DarwinNotificationDetails( + presentAlert: true, presentBadge: true, presentSound: true); + + NotificationDetails notificationDetails = NotificationDetails( + android: androidNotificationDetails, iOS: darwinNotificationDetails); + + Future.delayed(Duration.zero, () { + _flutterLocalNotificationsPlugin.show( + 0, + message.notification!.title.toString(), + message.notification!.body.toString(), + notificationDetails, + ); + }); + } + + //function to get device token on which we will send the notifications + Future getDeviceToken() async { + String? token = await messaging.getToken(); + return token!; + } + + void isTokenRefresh() async { + messaging.onTokenRefresh.listen((event) { + event.toString(); + if (kDebugMode) { + print('refresh'); + } + }); + } + + //handle tap on notification when app is in background or terminated + Future setupInteractMessage(BuildContext context) async { + // when app is terminated + RemoteMessage? initialMessage = + await FirebaseMessaging.instance.getInitialMessage(); + + if (initialMessage != null) { + handleMessage(context, initialMessage); + } + + //when app ins background + FirebaseMessaging.onMessageOpenedApp.listen((event) { + handleMessage(context, event); + }); + } + + void handleMessage(BuildContext context, RemoteMessage message) {} + + Future forgroundMessage() async { + await FirebaseMessaging.instance + .setForegroundNotificationPresentationOptions( + alert: true, + badge: true, + sound: true, + ); + } +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 94167be..97d5f73 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -1,8 +1,11 @@ import 'package:cheminova/controller/home_controller.dart'; import 'package:cheminova/screens/inventory/inventory_management_screen.dart'; +import 'package:cheminova/screens/kyc/kyc_screen.dart'; +import 'package:cheminova/screens/notification/notification_screen.dart'; import 'package:cheminova/screens/order/order_tracking_screen.dart'; import 'package:cheminova/screens/order_management/order_management_screen.dart'; import 'package:cheminova/screens/product/product_catalog_screen.dart'; +import 'package:cheminova/screens/product/product_mannual.dart'; import 'package:cheminova/screens/report/order_history_report_screen.dart'; import 'package:cheminova/screens/report/reporting_analytics_screen.dart'; import 'package:cheminova/screens/retail/retail_distributer_on_boarding_screen.dart'; @@ -13,6 +16,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; +import 'kyc/kyc_retailer_info_screen.dart'; + class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @@ -46,8 +51,23 @@ class _HomeScreenState extends State { title: const Text( "Welcome", ), + actions: [ + GestureDetector( + onTap: () { + // Action for notification icon tap + Get.to(() => NotificationScreen()); + }, + child: Padding( + padding: const EdgeInsets.only(right: 16.0), // Add padding to align with the AppBar edges + child: const Icon( + Icons.notifications, // Notification icon + color: Colors.white, // Icon color (customize as needed) + ), + ), + ), + ], ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ @@ -59,80 +79,106 @@ class _HomeScreenState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - HomeCard( - title: 'Product Catalogue', - onTap: () => - Get.to(() => const ProductCatalogScreen()), - ), - HomeCard( - title: 'Order Tracking', - onTap: () => Get.to( - () => const OrderTrackingScreen(), + child: Padding( + padding: const EdgeInsets.only(left: 15.0,), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + HomeCard( + title: 'Product Catalogue', + onTap: () => + Get.to(() => const ProductCatalogScreen()), ), - ), - ], - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - HomeCard( - title: 'Order Management', - onTap: () => Get.to( - () => OrderManagementScreen(), + HomeCard( + title: 'Order Tracking', + onTap: () => Get.to( + () => const OrderTrackingScreen(), + ), ), - ), - HomeCard( - title: 'Shipping Management', - onTap: () => Get.to( - () => const ShippingManagementScreen(), + ], + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + HomeCard( + title: 'Order Management', + onTap: () => Get.to( + () => OrderManagementScreen(), + ), ), - ), - ], - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - HomeCard( - title: 'Inventory Management', - onTap: () => Get.to( - () => const InventoryManagementScreen(), + HomeCard( + title: 'Shipping Management', + onTap: () => Get.to( + () => const ShippingManagementScreen(), + ), ), - ), - HomeCard( - title: 'Reporting & Analytics', - onTap: () => Get.to( - () => const ReportingAnalyticsScreen(), + ], + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + HomeCard( + title: 'Inventory Management', + onTap: () => Get.to( + () => const InventoryManagementScreen(), + ), ), - ), - ], - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - HomeCard( - title: 'Order Data Export', - onTap: () => Get.to( - () => const OrderHistoryReportScreen(), + HomeCard( + title: 'Reporting & Analytics', + onTap: () => Get.to( + () => const ReportingAnalyticsScreen(), + ), ), - ), - HomeCard( - title: 'Retail Distributors Onboarding', - onTap: () => Get.to( - () => const RetailDistributerOnBoardingScreen(), + + ], + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + HomeCard( + title: 'Order Data Export', + onTap: () => Get.to( + () => const OrderHistoryReportScreen(), + ), ), - ), - ], - ), - ], + HomeCard( + title: 'Retail Distributors Onboarding', + onTap: () => Get.to( + () => const RetailDistributerOnBoardingScreen(), + ), + ), + ], + + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + HomeCard( + title: 'Product Mannual', + onTap: () => Get.to( + () => const ProductsManualScreen(), + ), + ), + HomeCard( + title: 'Kyc', + onTap: () => Get.to( + () => KycRetailerInfoScreen(), + ), + ), + + + ], + ), + + ], + ), ), ), ), diff --git a/lib/screens/inventory/inventory_management_screen.dart b/lib/screens/inventory/inventory_management_screen.dart index 9d4e385..6dca3af 100644 --- a/lib/screens/inventory/inventory_management_screen.dart +++ b/lib/screens/inventory/inventory_management_screen.dart @@ -67,7 +67,7 @@ class _InventoryManagementScreenState extends State { "Inventory Management", ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/notification/notification_screen.dart b/lib/screens/notification/notification_screen.dart new file mode 100644 index 0000000..42b5fb8 --- /dev/null +++ b/lib/screens/notification/notification_screen.dart @@ -0,0 +1,131 @@ +import 'package:cheminova/controller/notification_controller.dart'; +import 'package:cheminova/models/notification_model.dart'; +import 'package:cheminova/widgets/my_drawer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart'; + +import '../../widgets/comman_background.dart'; +import '../../widgets/common_appbar.dart'; + +class NotificationScreen extends StatelessWidget { + NotificationScreen({super.key}); + + // Initialize the controller + final NotificationController notificationController = Get.put(NotificationController()); + + @override + Widget build(BuildContext context) { + // Fetch notifications when the screen is first built + notificationController.fetchNotificationApiService(); + + return CommonBackground( + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: CommonAppBar( + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: SvgPicture.asset('assets/svg/back_arrow.svg'), + padding: const EdgeInsets.only(right: 20), + ), + ], + title: const Text('Notification', + style: TextStyle( + fontSize: 20, + color: Colors.black, + fontWeight: FontWeight.w400, + fontFamily: 'Anek')), + backgroundColor: Colors.transparent, + elevation: 0, + ), + drawer: MyDrawer(), + body: Obx(() { + // Show a loading indicator while data is being fetched + if (notificationController.isLoading.value) { + return const Center(child: CircularProgressIndicator()); + } else if (notificationController.notificationList.isEmpty) { + // Handle empty state + return const Center(child: Text("No notifications available")); + } else { + // Show the notification list once data is fetched + return MyListView(notificationList: notificationController.notificationList); + } + }), + ), + ); + } +} + +class MyListView extends StatelessWidget { + final List notificationList; + + const MyListView({super.key, required this.notificationList}); + + @override + Widget build(BuildContext context) { + // Group notifications by date + Map> groupedNotifications = {}; + + for (var notification in notificationList) { + // Ensure that 'notifications' is not null + if (notification != null) { + String date = DateFormat("dd MMM yyyy") + .format(DateTime.parse(notification.createdAt ?? '')); + if (!groupedNotifications.containsKey(date)) { + groupedNotifications[date] = []; + } + groupedNotifications[date]!.add(notification); + } + } + + return ListView.builder( + padding: const EdgeInsets.only(top: 15), + itemCount: groupedNotifications.length, + itemBuilder: (context, index) { + String date = groupedNotifications.keys.elementAt(index); + List notificationsForDate = groupedNotifications[date]!; + + return Padding( + padding: const EdgeInsets.only(bottom: 10, left: 10, right: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Display the date once + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + date, + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.bold), + ), + ), + // Display notifications for the date + ...notificationsForDate.map( + (notification) { + return Padding( + padding: const EdgeInsets.only(bottom: 10), + child: ExpansionTile( + collapsedBackgroundColor: Colors.white, + backgroundColor: Colors.white, + trailing: const SizedBox.shrink(), + title: Text( + notification.title ?? 'No title', + style: const TextStyle( + fontSize: 17, fontWeight: FontWeight.w500), + ), + subtitle: Text(notification.msg ?? 'No message'), + ), + ); + }, + ).toList(), + ], + ), + ); + }, + ); + } +} diff --git a/lib/screens/order/checkout_screen.dart b/lib/screens/order/checkout_screen.dart index d8e58a0..4ecfe8f 100644 --- a/lib/screens/order/checkout_screen.dart +++ b/lib/screens/order/checkout_screen.dart @@ -204,7 +204,7 @@ class _CheckoutScreenState extends State { ], title: const Text("Checkout"), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/order/order_confermation_screen.dart b/lib/screens/order/order_confermation_screen.dart index 2e84da5..538e137 100644 --- a/lib/screens/order/order_confermation_screen.dart +++ b/lib/screens/order/order_confermation_screen.dart @@ -80,7 +80,7 @@ class _OrderConfermationScreenState extends State { "Order Confirmation", ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/order/order_detail_screen.dart b/lib/screens/order/order_detail_screen.dart index aad3a0e..f0d44a2 100644 --- a/lib/screens/order/order_detail_screen.dart +++ b/lib/screens/order/order_detail_screen.dart @@ -61,7 +61,7 @@ class _OrderDetailScreenState extends State { "Order Detail", ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/order/order_tracking_screen.dart b/lib/screens/order/order_tracking_screen.dart index 6cb03c9..82dd100 100644 --- a/lib/screens/order/order_tracking_screen.dart +++ b/lib/screens/order/order_tracking_screen.dart @@ -56,7 +56,7 @@ class _OrderTrackingScreenState extends State { "Order Tracking", ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/order/shipment_tracking_screen.dart b/lib/screens/order/shipment_tracking_screen.dart index a933a1a..f307b92 100644 --- a/lib/screens/order/shipment_tracking_screen.dart +++ b/lib/screens/order/shipment_tracking_screen.dart @@ -48,7 +48,7 @@ class _ShipmentTrackingScreenState extends State { "Shipment Tracking", ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/order_management/order_management_screen.dart b/lib/screens/order_management/order_management_screen.dart index d0fc0e7..69fb4b3 100644 --- a/lib/screens/order_management/order_management_screen.dart +++ b/lib/screens/order_management/order_management_screen.dart @@ -87,7 +87,7 @@ class _OrderManagementScreenState extends State { ], title: const Text("Order Management"), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/product/cart_screen.dart b/lib/screens/product/cart_screen.dart index 0e1581f..26c2b5d 100644 --- a/lib/screens/product/cart_screen.dart +++ b/lib/screens/product/cart_screen.dart @@ -90,7 +90,7 @@ class _CartScreenState extends State { ), ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/product/product_catalog_screen.dart b/lib/screens/product/product_catalog_screen.dart index 4090e9b..4f3a217 100644 --- a/lib/screens/product/product_catalog_screen.dart +++ b/lib/screens/product/product_catalog_screen.dart @@ -175,7 +175,7 @@ class _ProductCatalogScreenState extends State { ), ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/product/product_detail_screen.dart b/lib/screens/product/product_detail_screen.dart index d58c752..623cd42 100644 --- a/lib/screens/product/product_detail_screen.dart +++ b/lib/screens/product/product_detail_screen.dart @@ -64,7 +64,7 @@ class _ProductDetailScreenState extends State { "Product Detail", ), ), - drawer: const MyDrawer(), + drawer: MyDrawer(), body: Stack( fit: StackFit.expand, children: [ diff --git a/lib/screens/product/product_mannual.dart b/lib/screens/product/product_mannual.dart index efbe0fb..3d81da9 100644 --- a/lib/screens/product/product_mannual.dart +++ b/lib/screens/product/product_mannual.dart @@ -46,6 +46,7 @@ class _ProductsManualScreenState extends State { return AppBar( backgroundColor: Colors.transparent, elevation: 0, + title: Center(child: Text("Product Manual")), leading: GestureDetector( onTap: () => Get.back(), child: Padding( diff --git a/lib/utils/common_api_service.dart b/lib/utils/common_api_service.dart index caa8abe..4e3e923 100644 --- a/lib/utils/common_api_service.dart +++ b/lib/utils/common_api_service.dart @@ -50,6 +50,7 @@ Future commonApiService({ if (method == "POST") { response = await dio.post("$baseUrl$url", data: isformData ? formData : body, options: options); + } else if (method == "PUT") { response = await dio.put("$baseUrl$url", data: isformData ? formData : body, options: options); @@ -69,13 +70,14 @@ Future commonApiService({ prefs.setString('token', response.data['token']); } - if (url == "/api/territorymanager/my-profile") { - return fromJson(response.data['myData']); - } + // if (url == "/api/territorymanager/my-profile") { + // return fromJson(response.data['myData']); + // } return fromJson(response.data); } on DioException catch (e) { print("dio exception $url ${e.response?.data}}"); + print("dio exception details: ${e.message} ${e.response?.statusCode}"); String errorMessage = "An error occurred"; diff --git a/lib/utils/secure__storage_service.dart b/lib/utils/secure__storage_service.dart new file mode 100644 index 0000000..dade42d --- /dev/null +++ b/lib/utils/secure__storage_service.dart @@ -0,0 +1,37 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; + +class SecureStorageService { + // Create a private constructor + SecureStorageService._privateConstructor(); + + // The single instance of the class + static final SecureStorageService _instance = SecureStorageService._privateConstructor(); + + // The single instance of FlutterSecureStorage + final FlutterSecureStorage _storage = const FlutterSecureStorage(); + + // Factory constructor to return the same instance + factory SecureStorageService() { + return _instance; + } + + // Method to write data to secure storage + Future write({required String key, required String value}) async { + await _storage.write(key: key, value: value); + } + + // Method to read data from secure storage + Future read({required String key}) async { + return await _storage.read(key: key); + } + + // Method to delete data from secure storage + Future delete({required String key}) async { + await _storage.delete(key: key); + } + + // Method to clear all data from secure storage + Future clear() async { + await _storage.deleteAll(); + } +} diff --git a/lib/widgets/common_appbar.dart b/lib/widgets/common_appbar.dart index af77655..a7895eb 100644 --- a/lib/widgets/common_appbar.dart +++ b/lib/widgets/common_appbar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; class CommonAppBar extends StatelessWidget implements PreferredSizeWidget { final Widget title; @@ -14,7 +15,9 @@ class CommonAppBar extends StatelessWidget implements PreferredSizeWidget { leading: Builder(builder: (context) { return IconButton( onPressed: () => Scaffold.of(context).openDrawer(), - icon: const Icon(Icons.menu), + icon: SvgPicture.asset( + 'assets/svg/menu.svg', + ), color: Colors.white); }), backgroundColor: Colors.transparent,