First commmit of RD App

This commit is contained in:
Vaibhav 2024-09-20 15:50:11 +05:30
parent a4160498e1
commit c246d1cbeb
18 changed files with 552 additions and 231 deletions

View File

@ -13,7 +13,7 @@ class GetOrderPlacedService {
try { try {
while (_hasMoreOrders) { while (_hasMoreOrders) {
// Construct the API URL with pagination parameters // Construct the API URL with pagination parameters
String url = "/api/get-placed-order-pd?page=$_currentPage"; String url = "api/rd-place-order?page=$_currentPage";
final response = await commonApiService<List<PlacedOrderList>>( final response = await commonApiService<List<PlacedOrderList>>(
method: "GET", method: "GET",

View File

@ -6,7 +6,19 @@ import 'package:shared_preferences/shared_preferences.dart';
class HomeController extends GetxController { class HomeController extends GetxController {
final HomeService homeService = HomeService(); final HomeService homeService = HomeService();
var user = Rxn<UserModel>(); UserModel? user;
// var userModel = UserModel(
// id: '',
// uniqueId: '',
// name: '',
// email: '',
// phone: '',
// role: '',
// sbu: '',
// createdAt: '',
// updatedAt: '',
// ).obs; // Observable for UserModel
@override @override
void onInit() { void onInit() {
@ -14,10 +26,85 @@ class HomeController extends GetxController {
super.onInit(); super.onInit();
} }
Future<void> getUser() async Future<void> getUser() async {
{ try {
print("Starting getUser function in controller");
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token'); String? token = prefs.getString('token');
user.value = (await homeService.getUser(token: token)) as UserModel? ;
print("Token from SharedPreferences: $token");
HomeService homeService = HomeService();
print("Calling homeService.getUser");
user = await homeService.getUser(token: token);
print("homeService.getUser completed. User: $user");
update();
if (user != null) {
print("User fetched successfully: $user");
} else {
print('Failed to fetch user data');
}
} catch (e) {
print("Error in getUser controller function: ${e.toString()}");
}
} }
} }
// import 'package:cheminova/controller/home_service.dart';
// import 'package:cheminova/models/user_model.dart';
// import 'package:get/get.dart';
// import 'package:shared_preferences/shared_preferences.dart';
//
// import '../notification_service.dart';
//
// class HomeController extends GetxController {
// final HomeService homeService = HomeService();
// NotificationServices notificationServices = NotificationServices();
//
//
//
// var userModel = UserModel(id: '', uniqueId: '', name: '', email: '', phone: '', role: '', sbu: '', createdAt: '', updatedAt: ''
//
// ).obs; // Observable for UserModel
//
// @override
// void onInit() {
// getUser();
// super.onInit();
// notificationServices.requestNotificationPermission();
// notificationServices.getDeviceToken().then((value) {
// print('Device Token: $value');
// fcmToken();
// });
// }
//
// Future<void> fcmToken() async {
// SharedPreferences prefs = await SharedPreferences.getInstance();
// String? token = prefs.getString('token');
// final fcmToken = await NotificationServices().getDeviceToken();
// print('fcmToken: $fcmToken');
// homeService.fcmToken({"fcmToken": fcmToken}, token!);
// }
//
// Future<void> getUser() async {
// SharedPreferences prefs = await SharedPreferences.getInstance();
//
// String? token = prefs.getString('token');
//
// userModel = (await homeService.getUser(token: token)) as dynamic;
//
//
// // if (userModel != null) {
// // if (userModel != null) {ddddd
// // userModel.value = userResponse as UserModel; // Update the userModel with API response
// // update(); // Notify GetX to rebuild widgets using GetBuilder/Obx
// // }
// }
// }
//

View File

@ -1,25 +1,54 @@
import 'package:cheminova/models/user_model.dart'; import 'package:cheminova/models/user_model.dart';
import 'package:cheminova/utils/common_api_service.dart'; import 'package:cheminova/utils/common_api_service.dart';
import 'package:cheminova/utils/show_snackbar.dart'; import 'package:cheminova/utils/show_snackbar.dart';
import '../utils/api_urls.dart';
class HomeService { class HomeService {
Future<Map<String, dynamic>?> getUser({String? token}) async { Future<UserModel?> getUser({String? token}) async {
try { try {
final response = await commonApiService<Map<String,dynamic>>( print("Starting getUser method in HomeService");
print("Token: $token");
print("URL: ${ApiUrls.profileUrl}");
final response = await commonApiService<Map<String, dynamic>>(
method: "GET", method: "GET",
url: "api/v1/user/details", url: ApiUrls.profileUrl,
fromJson: (json) => json, additionalHeaders: {
additionalHeaders: { // Pass the token here
'Authorization': 'Bearer $token', 'Authorization': 'Bearer $token',
}, },
fromJson: (json) => json as Map<String, dynamic>,
); );
return response; print("Raw API response: $response");
} catch (e) {
showSnackbar(e.toString()); if (response == null) {
} print("API response is null");
showSnackbar("Failed to get a response from the server");
return null; return null;
} }
if (response['success'] != true) {
print("API call was not successful");
showSnackbar(response['message'] ?? "API call was not successful");
return null;
}
if (response['myData'] == null) {
print("myData is null in the response");
showSnackbar("User data not found in the response");
return null;
}
print("Attempting to create UserModel from myData");
final userModel = UserModel.fromJson(response['myData']);
print("UserModel created successfully: $userModel");
return userModel;
} catch (e) {
print("Error in getUser: ${e.toString()}");
showSnackbar("Error fetching user data: ${e.toString()}");
return null;
}
}
// ... keep the fcmToken method as it was
} }

View File

@ -43,87 +43,3 @@ class OrderPlacedController extends GetxController {
// isLoading.value = false; // isLoading.value = false;
// } // }
} }
// import 'package:cheminova/controller/place_order_service.dart';
// import 'package:cheminova/models/category_model.dart';
// import 'package:get/get.dart';
// import 'package:shared_preferences/shared_preferences.dart';
// import '../models/oder_place_model.dart';
// import 'cart_controller.dart';
//
//
// class OrderPlacedController extends GetxController {
// final OrderPlacedService _orderPlacedService = OrderPlacedService();
// final CartController _cartController = Get.find();
// Rx<PlacedOrderModel?> placedOrder1 = Rx<PlacedOrderModel?>(null);
// RxBool isLoading = false.obs;
//
// // Method to place an order with provided details
// Future<void> placeOrder() async {
// SharedPreferences prefs = await SharedPreferences.getInstance();
// String? token = prefs.getString('token');
//
// // Prepare order details
// final order = PlacedOrderModel(
// paymentMode: 'cheque',
// shipTo: '456, Park Street, Kolkata, West Bengal - 700016',
// billTo: '456, Park Street, Kolkata, West Bengal - 700016',
// subtotal: 4000,
// gstTotal: 18,
// grandTotal: 4720,
// orderItems: [
// OrderItem(
// id: "66cc7869f02b935094127a27",
// sku: "BJD",
// name: "Zycor 60m.l",
// price: 4000,
// gst: 18,
// hsnCode: 200,
// description: "",
// productStatus: "Active",
// addedBy: "ChemiNova",
// image: [],
// createdAt: DateTime.parse("2024-08-26T12:43:21.103Z"),
// updatedAt: DateTime.parse("2024-08-26T12:43:21.103Z"),
// count: 1, category:Category(id: "66cc7868f02b935094127a21", categoryName: "Insectiside") ,
// brand: Brand(id: "66cc77fbf02b9350941279f5", brandName: "Old"), v: 0,
// ),
// ],
// );
//
// try {
// isLoading.value = true;
// PlacedOrderModel? result = await _orderPlacedService.placeOrder(order, token);
// if (result != null) {
// placedOrder1.value = result;
// Get.snackbar('Success', 'Order placed successfully.');
// // _cartController.clearCart(); // Clear cart items after order
// } else {
// Get.snackbar('Error', 'Failed to place order.');
// }
// } catch (e) {
// Get.snackbar('Error', e.toString());
// } finally {
// isLoading.value = false;
// }
// }
//
// String getShippingAddress() {
// return placedOrder1.value?.shipTo ?? 'No shipping address';
// }
//
// String getBillingAddress() {
// return placedOrder1.value?.billTo ?? 'No billing address';
// }
//
// String getPaymentMode() {
// return placedOrder1.value?.paymentMode ?? 'No payment mode';
// }
// }

View File

@ -14,7 +14,8 @@ class OrderPlacedService {
//try { //try {
// logger.w("orderjson ${jsonEncode(orderDetails.toJson())}"); // logger.w("orderjson ${jsonEncode(orderDetails.toJson())}");
final response = await dio.post( final response = await dio.post(
'https://api.cnapp.co.in/api/order-place', // Ensure this is your correct endpoint 'https://api.cnapp.co.in/api/rd-place-order',
// Ensure this is your correct endpoint
data: jsonEncode(orderDetails.toJson()), data: jsonEncode(orderDetails.toJson()),
options: Options( options: Options(
headers: { headers: {
@ -23,19 +24,10 @@ class OrderPlacedService {
}, },
), ),
); );
//logger.w("Status code,${response.statusCode}");
if (response.statusCode != 201) { if (response.statusCode != 201) {
throw Exception('Failed to place order'); throw Exception('Failed to place order');
} }
} }
// on DioException catch (e) {
// print("DioException: ${e.message}");
// throw Exception('Failed to place order: ${e.message}');
// }
// catch (e) {
// print("General Exception: ${e.toString()}");
// throw Exception('Failed to place order: ${e.toString()}');
// }
} }

View File

@ -7,9 +7,9 @@ class ProductService {
try { try {
String url; String url;
if (category != null && category.isNotEmpty) { if (category != null && category.isNotEmpty) {
url = "/api/product/getAll/user?page=$page&category=$category"; url = "/api/product/getAll/user/?page=$page&category=$category";
} else { } else {
url = "/api/product/getAll/user?page=$page"; // URL without category filter url = "/api/product/getAll/user/?page=$page"; // URL without category filter
} }
final response = await commonApiService<List<Product>>( final response = await commonApiService<List<Product>>(

View File

@ -1,43 +1,76 @@
class UserModel { class UserModel {
String id; final String id;
String name; final String uniqueId;
String uniqueId; final String name;
String email; final String email;
bool isVerified; final String mobileNumber;
final String designation;
final String userType;
final String? principalDistributer;
final String? addedBy;
final String? kyc;
final String? fcmToken;
final String createdAt;
final String updatedAt;
final String? mappedSC;
UserModel({ UserModel({
required this.id, required this.id,
required this.name,
required this.uniqueId, required this.uniqueId,
required this.name,
required this.email, required this.email,
required this.isVerified, required this.mobileNumber,
required this.designation,
required this.userType,
this.principalDistributer,
this.addedBy,
this.kyc,
this.fcmToken,
required this.createdAt,
required this.updatedAt,
this.mappedSC,
}); });
// Factory constructor to create an instance of UserModel from a JSON map
factory UserModel.fromJson(Map<String, dynamic> json) { factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel( return UserModel(
id: json['_id'] ??"", id: json['_id'],
name: json['name'] ??"Sarita", uniqueId: json['uniqueId'],
uniqueId: json['uniqueId'] ??"1234", name: json['name'],
email: json['email'] ??"", email: json['email'],
isVerified: json['isVerified'] as bool? ??false, mobileNumber: json['mobile_number'],
designation: json['designation'],
userType: json['userType'],
principalDistributer: json['principal_distributer'],
addedBy: json['addedBy'],
kyc: json['kyc'],
fcmToken: json['fcm_token'],
createdAt: json['createdAt'],
updatedAt: json['updatedAt'],
mappedSC: json['mappedSC'],
); );
} }
// Method to convert an instance of UserModel to a JSON map
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
'_id': id, '_id': id,
'name': name,
'uniqueId': uniqueId, 'uniqueId': uniqueId,
'name': name,
'email': email, 'email': email,
'isVerified': isVerified, 'mobile_number': mobileNumber,
'designation': designation,
'userType': userType,
'principal_distributer': principalDistributer,
'addedBy': addedBy,
'kyc': kyc,
'fcm_token': fcmToken,
'createdAt': createdAt,
'updatedAt': updatedAt,
'mappedSC': mappedSC,
}; };
} }
// Override toString() to provide a readable output
@override @override
String toString() { String toString() {
return 'UserModel{id: $id, name: $name, uniqueId: $uniqueId, email: $email, isVerified: $isVerified}'; return 'UserModel{id: $id, uniqueId: $uniqueId, name: $name, email: $email, mobileNumber: $mobileNumber, designation: $designation, userType: $userType, principalDistributer: $principalDistributer, addedBy: $addedBy, kyc: $kyc, fcmToken: $fcmToken, createdAt: $createdAt, updatedAt: $updatedAt, mappedSC: $mappedSC}';
} }
} }

View File

@ -0,0 +1,117 @@
import 'package:cheminova/controller/home_controller.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 '../../widgets/comman_background.dart';
import '../../widgets/common_appbar.dart';
class ProfileScreen extends StatefulWidget {
// String? name;
// final String uniqueId;
// final String email;
// final String mobileNumber;
// final String designation;
const ProfileScreen({
Key? key,
}) : super(key: key);
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
final homecontroller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
final user = homecontroller!.user;
return Stack(
children: [
CommonBackground(
isFullWidth: true,
child: Scaffold(
drawer: MyDrawer(),
backgroundColor: Colors.transparent,
appBar: CommonAppBar(
title: const Text('Profile'),
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: SvgPicture.asset(
'assets/svg/back_arrow.svg',
),
padding: const EdgeInsets.only(right: 20),
),
],
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
padding: const EdgeInsets.all(20.0)
.copyWith(top: 15, bottom: 30),
margin: const EdgeInsets.symmetric(
horizontal: 30.0, vertical: 20.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: const Color(0xffB4D1E5).withOpacity(0.9),
borderRadius: BorderRadius.circular(26.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
_buildProfileItem('Name', user!.name),
_buildProfileItem('ID', user.uniqueId),
_buildProfileItem('Email ID', user.email),
// _buildProfileItem('Mobile Number', user.phone),
// _buildProfileItem('Designation', user.role),
],
),
),
],
),
),
),
),
],
);
}
Widget _buildProfileItem(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xff004791),
),
),
const SizedBox(height: 5),
Text(
value,
style: const TextStyle(
fontSize: 18,
color: Colors.black,
),
),
const Divider(color: Colors.grey),
],
),
);
}
}

View File

@ -5,7 +5,7 @@ class AuthService {
Future<Map<String, dynamic>?> login(Map<String, dynamic> data) async { Future<Map<String, dynamic>?> login(Map<String, dynamic> data) async {
try { try {
final response = await commonApiService<Map<String, dynamic>>( final response = await commonApiService<Map<String, dynamic>>(
url: '/api/v1/user/login/', url: '/api/rd-login',
method: 'POST', method: 'POST',
body: data, body: data,
fromJson: (json) => json, // Simply return the JSON map as is fromJson: (json) => json, // Simply return the JSON map as is
@ -21,7 +21,7 @@ class AuthService {
Future<Map<String, dynamic>?> forgotPassword(Map<String, dynamic> data) async { Future<Map<String, dynamic>?> forgotPassword(Map<String, dynamic> data) async {
try { try {
final response = await commonApiService<Map<String, dynamic>>( final response = await commonApiService<Map<String, dynamic>>(
url: '/api/v1/user/password/forgot', url: '/api/forgot-password',
method: 'POST', method: 'POST',
body: data, body: data,
fromJson: (json) => json, // Simply return the JSON map as is fromJson: (json) => json, // Simply return the JSON map as is
@ -37,7 +37,7 @@ class AuthService {
Future<Map<String, dynamic>?> changePassword(Map<String, dynamic> data, {required String token}) async { Future<Map<String, dynamic>?> changePassword(Map<String, dynamic> data, {required String token}) async {
try { try {
final response = await commonApiService<Map<String, dynamic>>( final response = await commonApiService<Map<String, dynamic>>(
url: '/api/v1/user/password/update', url: '/api/rd-password/update',
method: 'PUT', method: 'PUT',
body: data, body: data,
fromJson: (json) => json, // Simply return the JSON map as is fromJson: (json) => json, // Simply return the JSON map as is

View File

@ -1,16 +1,13 @@
import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model.dart';
import 'package:cheminova/models/product_model1.dart'; import 'package:cheminova/models/product_model1.dart';
import 'package:cheminova/screens/order/checkout_screen.dart';
import 'package:cheminova/utils/show_snackbar.dart'; import 'package:cheminova/utils/show_snackbar.dart';
import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/widgets/my_drawer.dart';
import 'package:cheminova/widgets/product_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import '../../controller/cart_controller.dart'; import '../../controller/cart_controller.dart';
import 'cart_screen.dart';
class ProductDetailScreen extends StatefulWidget { class ProductDetailScreen extends StatefulWidget {
Product? productModel; Product? productModel;
@ -119,7 +116,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("Product Name ",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16),), const Text("Product Name ",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16),),
Text( Text(
capitalizeFirstLetter(widget.productModel!.name), capitalizeFirstLetter(widget.productModel!.name),
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
@ -136,7 +133,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("Price ",style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),), const Text("Price ",style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),),
Text( Text(
"${widget.productModel!.price.toString()}", "${widget.productModel!.price.toString()}",
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
@ -153,9 +150,9 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("Category ",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16),), const Text("Category ",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16),),
Text( Text(
capitalizeFirstLetter(widget.productModel!.category!.categoryName), capitalizeFirstLetter(widget.productModel!.category.categoryName),
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@ -170,7 +167,7 @@ class _ProductDetailScreenState extends State<ProductDetailScreen> {
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row( child: Row(
children: [ children: [
Text("Description",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), const Text("Description",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)),
Text( Text(
capitalizeFirstLetter(widget.productModel!.description), capitalizeFirstLetter(widget.productModel!.description),
style: GoogleFonts.roboto( style: GoogleFonts.roboto(

View File

@ -0,0 +1,99 @@
// import 'package:cheminova/controller/home_controller.dart';
// import 'package:cheminova/widgets/my_drawer.dart';
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
//
// import '../widgets/comman_background.dart';
// import '../widgets/common_appbar.dart';
//
// class ProfileScreen extends StatelessWidget {
// const ProfileScreen({Key? key}) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// return Stack(
// children: [
// CommonBackground(
// isFullWidth: true,
// child: Scaffold(
// drawer: const MyDrawer(),
// backgroundColor: Colors.transparent,
// appBar: CommonAppBar(
// title: const Text('Profile'),
// backgroundColor: Colors.transparent,
// elevation: 0,
// actions: [
// IconButton(
// onPressed: () {
// Navigator.pop(context);
// },
// icon: Image.asset('assets/Back_attendance.png'),
// padding: const EdgeInsets.only(right: 20),
// ),
// ],
// ),
// body: Consumer<HomeController>(
// builder: (context, profileProvider, child) {
// final profileData = profileProvider.profileResponse?.myData!;
// return SingleChildScrollView(
// child: Column(
// children: [
// Container(
// padding: const EdgeInsets.all(20.0).copyWith(top: 15, bottom: 30),
// margin: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 20.0),
// decoration: BoxDecoration(
// border: Border.all(color: Colors.white),
// color: const Color(0xffB4D1E5).withOpacity(0.9),
// borderRadius: BorderRadius.circular(26.0),
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// SizedBox(height: 20),
// _buildProfileItem('Name', profileData?.name ?? ''),
// _buildProfileItem('ID', profileData?.uniqueId ?? ''),
// _buildProfileItem('Email ID', profileData?.email ?? ''),
// _buildProfileItem('Mobile Number', profileData?.mobileNumber ?? ''),
// _buildProfileItem('Designation', profileData?.designation ?? ''),
// ],
// ),
// ),
// ],
// ),
// );
// },
// ),
// ),
// ),
// ],
// );
// }
//
// Widget _buildProfileItem(String label, String value) {
// return Padding(
// padding: const EdgeInsets.symmetric(vertical: 10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// label,
// style: const TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.bold,
// color: Color(0xff004791),
// ),
// ),
// const SizedBox(height: 5),
// Text(
// value,
// style: const TextStyle(
// fontSize: 18,
// color: Colors.black,
// ),
// ),
// const Divider(color: Colors.grey),
// ],
// ),
// );
// }
// }

View File

@ -1,9 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'package:cheminova/screens/authentication/login_screen.dart'; import 'package:cheminova/screens/authentication/login_screen.dart';
import 'package:cheminova/screens/home_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SplashScreen extends StatefulWidget { class SplashScreen extends StatefulWidget {
const SplashScreen({super.key}); const SplashScreen({super.key});
@ -15,12 +17,25 @@ class SplashScreen extends StatefulWidget {
class _SplashScreenState extends State<SplashScreen> { class _SplashScreenState extends State<SplashScreen> {
@override @override
void initState() { void initState() {
super.initState(); Timer(const Duration(seconds: 3), () {
Timer(const Duration(seconds: 2), () { checkLogin();
Get.offAll(() => const LoginScreen());
}); });
super.initState();
} }
checkLogin() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
if (token != null) {
Get.offAll(() => const HomeScreen());
} else {
Get.offAll(() => const LoginScreen());
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(

18
lib/utils/api_urls.dart Normal file
View File

@ -0,0 +1,18 @@
class ApiUrls {
// static const String baseUrl = 'https://cheminova-api-2.onrender.com/api/';
static const String baseUrl = 'https://api.cnapp.co.in';
static const String loginUrl = '/api/v1/user/login/';
static const String profileUrl = '/api/rd-get-me';
static const String forgetPasswordUrl = '/api/v1/user/password/forgot';
static const String changePasswordUrl = '/api/v1/user/password/update';
static const String fcmUrl = '/api/v1/user/fcm-token';
static const String getCategoryUrl = '/api/category/getCategories';
static const String getProductUrl = '/api/category/getCategories';
static const String getProductManualUrl = '/api/productmanual/getall';
static const String getKycUrl = '/api/kyc/getAll';
static const String getNotificationUrl = '/api/get-notification-pd';
static const String getPlacedOrderUrl ='/api/get-placed-order-pd';
static const String getSinglePlacedOrderUrl ='/api/get-single-placed-order-pd';
static const String placedOrderUrl ='${baseUrl}/api/order-place';
}

View File

@ -1,93 +1,97 @@
import 'dart:io'; import 'dart:io';
import 'package:cheminova/utils/constants.dart'; import 'package:cheminova/utils/constants.dart';
import 'package:cheminova/utils/show_snackbar.dart'; import 'package:cheminova/utils/show_snackbar.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
Future<BodyType?> commonApiService<BodyType>({ Future<BodyType?> commonApiService<BodyType>({
required String url, required String url,
required String method, required String method,
Map<String, dynamic> body = const {}, Map<String, dynamic> body = const {},
File? imageFile, File? imageFile,
bool isformData = true, bool isFormData = false,
Map<String, String>? additionalHeaders, Map<String, String>? additionalHeaders,
required BodyType Function(Map<String, dynamic>) fromJson, required BodyType Function(Map<String, dynamic>) fromJson,
}) async { }) async {
try { try {
Dio dio = Dio(); final dio = Dio();
final Response response;
print("body : $body"); // Add PrettyDioLogger
dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseBody: true,
responseHeader: false,
error: true,
compact: true,
maxWidth: 90,
));
// Fetch the token from SharedPreferences final prefs = await SharedPreferences.getInstance();
SharedPreferences prefs = await SharedPreferences.getInstance(); final token = prefs.getString('token');
String? token = prefs.getString('token');
Map<String, String> headers = { final headers = <String, String>{
'Content-Type': isformData ? 'multipart/form-data' : 'application/json', 'Content-Type': isFormData ? 'multipart/form-data' : 'application/json',
if (token != null) 'Authorization': 'Bearer $token',
...?additionalHeaders,
}; };
if (token != null) { final options = Options(headers: headers);
headers['Authorization'] = 'Bearer $token';
}
if (additionalHeaders != null) { dynamic requestData = isFormData ? FormData.fromMap(body) : body;
headers.addAll(additionalHeaders);
}
Options options = Options(headers: headers);
FormData formData = FormData.fromMap(body); if (imageFile != null && isFormData) {
final fileName = imageFile.path.split('/').last;
if (imageFile != null) { (requestData as FormData).files.add(MapEntry(
String fileName = imageFile.path.split('/').last;
formData.files.add(MapEntry(
"image", "image",
await MultipartFile.fromFile(imageFile.path, filename: fileName), await MultipartFile.fromFile(imageFile.path, filename: fileName),
)); ));
} }
if (method == "POST") { final Response response;
response = await dio.post("$baseUrl$url", switch (method.toUpperCase()) {
data: isformData ? formData : body, options: options); case "POST":
} else if (method == "PUT") { response = await dio.post("$baseUrl$url", data: requestData, options: options);
response = await dio.put("$baseUrl$url", break;
data: isformData ? formData : body, options: options); case "PUT":
} else if (method == "DELETE") { response = await dio.put("$baseUrl$url", data: requestData, options: options);
break;
case "DELETE":
response = await dio.delete("$baseUrl$url", options: options); response = await dio.delete("$baseUrl$url", options: options);
} else if (method == "PATCH") { break;
response = await dio.patch("$baseUrl$url", case "PATCH":
data: isformData ? formData : body, options: options); response = await dio.patch("$baseUrl$url", data: requestData, options: options);
} else { break;
case "GET":
response = await dio.get("$baseUrl$url", options: options); response = await dio.get("$baseUrl$url", options: options);
break;
default:
throw Exception("Unsupported HTTP method: $method");
} }
print("response of $url : $response"); if (url == "/api/rd-login" && response.data['token'] != null) {
await prefs.setString('token', response.data['token']);
if (url == "/api/v1/user/login/" &&
response.data['token'] != null) {
prefs.setString('token', response.data['token']);
} }
if (url == "/api/territorymanager/my-profile") { if (url == "/api/rd-get-me" && response.data['myData'] != null) {
return fromJson(response.data['myData']); return fromJson(response.data['myData']);
} }
return fromJson(response.data); return fromJson(response.data);
} on DioException catch (e) { } 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"; String errorMessage = "An error occurred";
if (e.response?.data is Map<String, dynamic>) { if (e.response?.data is Map<String, dynamic>) {
errorMessage = e.response?.data['message'] ?? errorMessage; errorMessage = e.response?.data['message'] ?? errorMessage;
} else if (e.response?.data is String) { } else if (e.response?.data is String) {
errorMessage = e.response?.data; errorMessage = e.response?.data;
} }
//showSnackbar(errorMessage); showSnackbar(errorMessage);
} catch (e) {
print("exception $url $e");
}
return null; return null;
} catch (e) {
print("Unexpected error for $url: $e");
showSnackbar("An unexpected error occurred");
return null;
}
} }

View File

@ -5,6 +5,8 @@ import 'package:cheminova/screens/home_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../screens/authentication/Profile.dart';
class MyDrawer extends StatefulWidget { class MyDrawer extends StatefulWidget {
const MyDrawer({super.key}); const MyDrawer({super.key});
@ -22,34 +24,37 @@ class _MyDrawerState extends State<MyDrawer> {
children: <Widget>[ children: <Widget>[
SizedBox( SizedBox(
height: 150, height: 150,
child: Obx( child:(
(){ DrawerHeader(
return DrawerHeader(
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.black87, color: Colors.black87,
), ),
child: Column( child: GetBuilder(
init: homeController,
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text( Text(
homeController.user.value?.name?? "username", controller.user?.name?? "username",
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 18, fontSize: 18,
), ),
), ),
Text( Text(
homeController.user.value?.uniqueId?? 'Employee ID', controller.user?.uniqueId?? 'Employee ID',
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 20, fontSize: 20,
), ),
), ),
], ],
),
); );
}, }
),
)
), ),
), ),
ListTile( ListTile(
@ -61,7 +66,7 @@ class _MyDrawerState extends State<MyDrawer> {
leading: const Icon(Icons.account_circle), leading: const Icon(Icons.account_circle),
title: const Text('Profile'), title: const Text('Profile'),
onTap: () { onTap: () {
Navigator.pop(context); Get.to(ProfileScreen());
}, },
), ),
ListTile( ListTile(

View File

@ -500,18 +500,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.4" version: "10.0.5"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.5"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@ -548,18 +548,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.0" version: "0.11.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.15.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -664,6 +664,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
pretty_dio_logger:
dependency: "direct main"
description:
name: pretty_dio_logger
sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -841,10 +849,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.2"
timezone: timezone:
dependency: transitive dependency: transitive
description: description:
@ -969,10 +977,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.1" version: "14.2.4"
web: web:
dependency: transitive dependency: transitive
description: description:

View File

@ -54,6 +54,7 @@ dependencies:
flutter_local_notifications: ^17.2.1+2 flutter_local_notifications: ^17.2.1+2
firebase_crashlytics: ^4.0.4 firebase_crashlytics: ^4.0.4
firebase_analytics: ^11.2.1 firebase_analytics: ^11.2.1
pretty_dio_logger: ^1.3.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: