1)Profile ui and api integration done

This commit is contained in:
saritabirare 2024-09-20 14:22:45 +05:30
parent a4160498e1
commit e40371ad6a
16 changed files with 660 additions and 69 deletions

View File

@ -1,5 +1,9 @@
plugins { plugins {
id "com.android.application" id "com.android.application"
// START: FlutterFire Configuration
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
// END: FlutterFire Configuration
id "kotlin-android" id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin" id "dev.flutter.flutter-gradle-plugin"

View File

@ -24,6 +24,12 @@
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme"
/> />
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="false" />
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

View File

@ -3,21 +3,113 @@ import 'package:cheminova/models/user_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../notification_service.dart';
class HomeController extends GetxController { class HomeController extends GetxController {
final HomeService homeService = HomeService(); final HomeService homeService = HomeService();
NotificationServices notificationServices = NotificationServices();
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() {
getUser(); getUser();
super.onInit(); super.onInit();
notificationServices.requestNotificationPermission();
notificationServices.getDeviceToken().then((value) {
print('Device Token: $value');
fcmToken();
});
} }
Future<void> getUser() async Future<void> fcmToken() async {
{
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? ; 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');
HomeService homeService = HomeService();
user = await homeService.getUser(token: token);
if (user != null) {
print(user); // For debugging, prints the user details
} else {
print('Failed to fetch user data');
} }
} }
}
// 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,58 @@
import 'package:cheminova/models/user_model.dart'; import 'package:cheminova/models/user_model.dart';
import 'package:cheminova/utils/api_urls.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';
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>>( final response = await commonApiService<UserModel>(
method: "GET", method: "GET",
url: "api/v1/user/details", url: ApiUrls.profileUrl,
fromJson: (json) => json, additionalHeaders: { // Pass the token here
'Authorization': 'Bearer $token',
},
fromJson: (json) {
if (json['user'] != null) {
// Parse the user data from the API response
return UserModel.fromJson(json['user']);
}
return json as UserModel;
},
);
return response;
} catch (e) {
print(e.toString());
showSnackbar(e.toString()); // Optional: show error using a Snackbar
return null;
}
}
Future<Map<String, dynamic>?> fcmToken(Map<String, dynamic> data,
String? token) async {
try {
final response = await commonApiService<String>(
url: ApiUrls.fcmUrl,
method: 'POST',
body: data,
fromJson: (json) => json as String,
// Just return the string response
additionalHeaders: { // Pass the token here additionalHeaders: { // Pass the token here
'Authorization': 'Bearer $token', 'Authorization': 'Bearer $token',
}, },
); );
return response; if (response != null) {
} catch (e) { // Since the response is a string, wrap it in a Map to avoid type issues
showSnackbar(e.toString()); return {
'message': response
}; // Return the response in a map with 'message' as the key
} }
return null; return null;
} catch (e) {
showSnackbar(e.toString()); // Handle any errors
return null;
}
} }
} }

View File

@ -1,43 +1,99 @@
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 phone;
final String role;
final String sbu;
final String createdAt;
final String updatedAt;
final String? fcmToken;
final Avatar? avatar;
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.phone,
required this.role,
required this.sbu,
required this.createdAt,
required this.updatedAt,
this.fcmToken,
this.avatar,
}); });
// Factory constructor to create an instance of UserModel from a JSON map // Factory constructor for converting JSON to UserModel
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, phone: json['phone'],
role: json['role'],
sbu: json['SBU'],
createdAt: json['createdAt'],
updatedAt: json['updatedAt'],
fcmToken: json['fcm_token'],
avatar: json['avatar'] != null ? Avatar.fromJson(json['avatar']) : null,
); );
} }
// Method to convert an instance of UserModel to a JSON map // Method to convert UserModel to JSON
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, 'phone': phone,
'role': role,
'SBU': sbu,
'createdAt': createdAt,
'updatedAt': updatedAt,
'fcm_token': fcmToken,
'avatar': avatar?.toJson(),
}; };
} }
// Override toString() to provide a readable output // Overriding toString to get a readable output for debugging
@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, phone: $phone, role: $role, sbu: $sbu, createdAt: $createdAt, updatedAt: $updatedAt, fcmToken: $fcmToken, avatar: $avatar}';
}
}
// Avatar model to handle avatar data
class Avatar {
final String publicId;
final String url;
Avatar({
required this.publicId,
required this.url,
});
// Factory constructor for converting JSON to Avatar
factory Avatar.fromJson(Map<String, dynamic> json) {
return Avatar(
publicId: json['public_id'] ?? '',
url: json['url'] ?? '',
);
}
// Method to convert Avatar to JSON
Map<String, dynamic> toJson() {
return {
'public_id': publicId,
'url': url,
};
}
@override
String toString() {
return 'Avatar{publicId: $publicId, url: $url}';
} }
} }

View File

@ -1,3 +1,6 @@
import 'dart:convert';
import 'package:cheminova/controller/home_controller.dart';
import 'package:cheminova/screens/authentication/controller/auth_service.dart'; import 'package:cheminova/screens/authentication/controller/auth_service.dart';
import 'package:cheminova/screens/home_screen.dart'; import 'package:cheminova/screens/home_screen.dart';
import 'package:cheminova/utils/show_snackbar.dart'; import 'package:cheminova/utils/show_snackbar.dart';
@ -5,18 +8,31 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../../../notification_service.dart';
import '../../../utils/api_client.dart';
import '../../../utils/api_urls.dart';
import '../../../utils/secure__storage_service.dart';
class AuthController extends GetxController { class AuthController extends GetxController {
final authService = AuthService(); final authService = AuthService();
final _apiClient = ApiClient();
final _storageService = SecureStorageService();
TextEditingController emailController = TextEditingController(); TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController(); TextEditingController passwordController = TextEditingController();
TextEditingController phoneController = TextEditingController(); //TextEditingController phoneController = TextEditingController();
TextEditingController currentpassController = TextEditingController(); TextEditingController currentpassController = TextEditingController();
TextEditingController newpassController = TextEditingController(); TextEditingController newpassController = TextEditingController();
TextEditingController confirmpassController = TextEditingController(); TextEditingController confirmpassController = TextEditingController();
final HomeController _homeController = Get.put(HomeController());
RxBool isLoading = false.obs; RxBool isLoading = false.obs;
@override
void onInit(){
super.onInit();
NotificationServices().requestNotificationPermission();
}
Future<void> login() async { Future<void> login() async {
isLoading.value = true; isLoading.value = true;
final response = await authService.login({ final response = await authService.login({
@ -26,7 +42,9 @@ class AuthController extends GetxController {
isLoading.value = false; isLoading.value = false;
update(); update();
if (response != null) { if (response != null) {
_homeController.fcmToken();
showSnackbar("Your Successfully logged In!"); showSnackbar("Your Successfully logged In!");
Get.offAll(() => const HomeScreen()); Get.offAll(() => const HomeScreen());
} }
else if(response == null){ else if(response == null){
@ -34,6 +52,53 @@ class AuthController extends GetxController {
} }
} }
// Future<(bool, String)> login() async {
// isLoading(true);
// try {
// Response response = (await _apiClient.post(
// ApiUrls.loginUrl,
// data: {
// 'email': emailController.text,
// 'password': passwordController.text
// },
// )) as Response;
//
// isLoading(false);
//
// // Check if the response status code is 200
// if (response.statusCode == 200) {
// // Access the data field from the response
// final responseData = jsonDecode(response.body) as Map<String, dynamic>;
// final token = responseData['token'];
// final message = responseData['message'];
//
// await _storageService.write(
// key: 'access_token',
// value: token,
// );
//
// final fcmToken = await NotificationServices().getDeviceToken();
// print('fcmToken: $fcmToken');
//
// await _apiClient.post(
// ApiUrls.fcmUrl,
// data: {'fcmToken': fcmToken},
// );
//
// return (true, message.toString());
// } else {
// // Handle the error based on status code
// final responseData = jsonDecode(response.body) as Map<String, dynamic>;
// return (false, responseData['message'].toString());
// }
// } catch (e) {
// isLoading(false);
// return (false, 'Something went wrong');
// }
// }
Future<void> forgotpass() async{ Future<void> forgotpass() async{
isLoading.value = true; isLoading.value = true;
final response = await authService.forgotPassword( final response = await authService.forgotPassword(

View File

@ -1,11 +1,15 @@
import 'package:cheminova/utils/api_urls.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_client.dart';
class AuthService { 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: ApiUrls.loginUrl,
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 +25,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: ApiUrls.forgetPasswordUrl,
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 +41,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: ApiUrls.changePasswordUrl,
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

@ -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),
],
),
);
}
}

60
lib/utils/api_client.dart Normal file
View File

@ -0,0 +1,60 @@
import 'package:cheminova/utils/secure__storage_service.dart';
import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'api_urls.dart';
class ApiClient {
final Dio _dio;
final SecureStorageService _storageService = SecureStorageService();
ApiClient({String? baseUrl})
: _dio = Dio(BaseOptions(
baseUrl: baseUrl ?? ApiUrls.baseUrl,
connectTimeout: const Duration(seconds: 120),
receiveTimeout: const Duration(seconds: 120))) {
_dio.interceptors
.add(LogInterceptor(responseBody: true, requestBody: true));
_dio.interceptors
.add(InterceptorsWrapper(onRequest: (options, handler) async {
String? token = await _storageService.read(key: 'access_token');
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
_dio.interceptors
.add(LogInterceptor(responseBody: true, requestBody: true));
_dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseBody: true,
responseHeader: false,
error: true,
compact: true,
maxWidth: 90,
));
return handler.next(options);
}, onResponse: (response, handler) {
return handler.next(response);
}, onError: (DioException e, handler) {
return handler.next(e);
}));
}
Future<dynamic> get(String path, {Map<String, dynamic>? queryParameters}) {
return _dio.get(path, queryParameters: queryParameters);
}
Future<Response> post(String path, {dynamic data}) {
return _dio.post(path, data: data);
}
Future<Response> put(String path, {Map<String, dynamic>? data}) {
return _dio.put(path, data: data);
}
Future<Response> delete(String path, {Map<String, dynamic>? data}) {
return _dio.delete(path, data: data);
}
}

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/v1/user/details';
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

@ -0,0 +1,11 @@
import 'package:flutter/services.dart';
class UpperCaseTextFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
return newValue.copyWith(
text: newValue.text.toUpperCase(),
selection: newValue.selection,
);
}
}

View File

@ -1,30 +1,33 @@
import 'package:cheminova/controller/home_controller.dart'; import 'package:cheminova/controller/home_controller.dart';
import 'package:cheminova/models/user_model.dart';
import 'package:cheminova/screens/authentication/change_password_screen.dart'; import 'package:cheminova/screens/authentication/change_password_screen.dart';
import 'package:cheminova/screens/authentication/login_screen.dart'; import 'package:cheminova/screens/authentication/login_screen.dart';
import 'package:cheminova/screens/authentication/profile_screen.dart';
import 'package:cheminova/screens/home_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';
class MyDrawer extends StatefulWidget { class MyDrawer extends StatefulWidget {
const MyDrawer({super.key}); final UserModel? userModel;
MyDrawer({super.key, this.userModel});
@override @override
State<MyDrawer> createState() => _MyDrawerState(); State<MyDrawer> createState() => _MyDrawerState();
} }
class _MyDrawerState extends State<MyDrawer> { class _MyDrawerState extends State<MyDrawer> {
final homeController = Get.put(HomeController()); final homecontroller = Get.put(HomeController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final user = homecontroller.user;
return Drawer( return Drawer(
child: ListView( child: ListView(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
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,
), ),
@ -33,14 +36,14 @@ class _MyDrawerState extends State<MyDrawer> {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text( Text(
homeController.user.value?.name?? "username", 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', user!.uniqueId ?? 'Employee ID',
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 20, fontSize: 20,
@ -48,36 +51,135 @@ class _MyDrawerState extends State<MyDrawer> {
), ),
], ],
), ),
);
},
), ),
), ),
ListTile( ListTile(
leading: const Icon(Icons.home), leading: const Icon(Icons.home),
title: const Text('Home'), title: const Text('Home'),
onTap: () => Get.offAll(() => const HomeScreen()), onTap: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const HomeScreen()),
(route) => false,
);
},
), ),
ListTile( ListTile(
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); Navigator.push(
context,
MaterialPageRoute(builder: (context) => ProfileScreen()),
);
}, },
), ),
ListTile( ListTile(
leading: const Icon(Icons.settings), leading: const Icon(Icons.settings),
title: const Text('Change Password'), title: const Text('Change Password'),
onTap: () { onTap: () {
Get.to(ChangePasswordScreen()); Navigator.push(
context,
MaterialPageRoute(builder: (context) => ChangePasswordScreen()),
);
}, },
), ),
ListTile( ListTile(
leading: const Icon(Icons.exit_to_app), leading: const Icon(Icons.exit_to_app),
title: const Text('Logout'), title: const Text('Logout'),
onTap: () => Get.offAll(() => const LoginScreen()), onTap: () {
logoutBox(context);
},
), ),
], ],
), ),
); );
} }
} }
Future logoutBox(BuildContext context) {
Size size = MediaQuery.of(context).size;
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
),
backgroundColor: Colors.white,
alignment: Alignment.center,
title: const Text('Are you sure you want to log out?'),
titleTextStyle: const TextStyle(
fontSize: 20, fontWeight: FontWeight.w400, color: Colors.black),
actionsAlignment: MainAxisAlignment.center,
actionsPadding: const EdgeInsets.only(left: 10, right: 10, bottom: 20),
actions: [
Row(
children: [
Expanded(
child: SizedBox(
height: (size.height / 50.52) * 2,
child: ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.all(0),
backgroundColor: MaterialStateProperty.all<Color>(
Colors.black),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
)),
),
onPressed: () async {
Navigator.pop(context);
},
child: const Text(
"No",
style: TextStyle(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w500),
),
),
),
),
const SizedBox(width: 5),
Expanded(
child: SizedBox(
height: (size.height / 50.52) * 2,
child: ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.all(0),
backgroundColor:
MaterialStateProperty.all<Color>(Colors.white),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
side: const BorderSide(
color: Colors.purple, width: 1))),
),
onPressed: () async {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => LoginScreen()),
(route) => false,
);
},
child: const Text(
"Yes",
style: TextStyle(
fontSize: 17,
color: Colors.purple,
fontWeight: FontWeight.w500),
),
),
),
),
],
)
],
);
},
);
}

View File

@ -7,12 +7,16 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <flutter_secure_storage/flutter_secure_storage_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar); file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) flutter_secure_storage_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStoragePlugin");
flutter_secure_storage_plugin_register_with_registrar(flutter_secure_storage_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux file_selector_linux
flutter_secure_storage
url_launcher_linux url_launcher_linux
) )

View File

@ -342,6 +342,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.22" version: "2.0.22"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: "9f3dd2ac3b6875b0fde5b04734789c3ef35ba3965c18e99dd564a7a2f8056df6"
url: "https://pub.dev"
source: hosted
version: "4.2.1"
flutter_svg: flutter_svg:
dependency: "direct main" dependency: "direct main"
description: description:
@ -664,6 +672,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:

View File

@ -54,6 +54,8 @@ 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
flutter_secure_storage: ^4.2.1
pretty_dio_logger: ^1.4.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: