diff --git a/lib/Utils/Common/ImageUpload.dart b/lib/Utils/Common/ImageUpload.dart new file mode 100644 index 0000000..83d50ac --- /dev/null +++ b/lib/Utils/Common/ImageUpload.dart @@ -0,0 +1,158 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:traderscircuit/Utils/Common/sized_box.dart'; +import 'package:traderscircuit/controller/profile_image_controller.dart'; + +import 'ImagePicker.dart'; +import 'SingleFilePicker.dart'; + +class ImageUploadBottomSheet { + final ProfileImageController editProfileImage = + Get.put(ProfileImageController()); + showModal( + BuildContext context, + bool showFile, + Function(String) onImagePicked, + ) { + return showModalBottomSheet( + isScrollControlled: true, + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(26.r), + topRight: Radius.circular(26.r), + ), + ), + builder: (context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: 36.w, vertical: 26.h), + child: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + (showFile) ? 'Select Image/File' : 'Select Image', + style: TextStyle( + color: const Color(0xff444444), + fontSize: 22.sp, + ), + ), + sizedBoxHeight(40.h), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + GestureDetector( + onTap: () async { + // editProfileImage.getImage(ImageSource.camera); + var result = await ImagePickerMethod() + .getImage(ImageSource.camera); + onImagePicked(result); + + Get.back(); + }, + child: Column( + children: [ + CircleAvatar( + radius: 27.r, + backgroundColor: const Color(0xFFE8C69F80), + child: Icon( + Icons.camera_alt_outlined, + size: 30.sp, + color: Colors.white, + ), + ), + SizedBox( + height: 6.h, + ), + Text( + 'Camera', + style: TextStyle( + fontSize: 13.sp, + color: const Color(0xff444444), + ), + ) + ], + ), + ), + sizedBoxWidth(36.w), + GestureDetector( + onTap: () async { + var result = await ImagePickerMethod() + .getImage(ImageSource.gallery); + onImagePicked(result); + Get.back(); + }, + child: Column( + children: [ + CircleAvatar( + radius: 27.r, + backgroundColor: const Color(0xFFE8C69F80), + child: Icon( + Icons.image_outlined, + size: 30.sp, + color: Colors.white, + ), + ), + SizedBox( + height: 6.h, + ), + Text( + 'Gallery', + style: TextStyle( + fontSize: 13.sp, + color: const Color(0xff444444), + ), + ) + ], + ), + ), + Visibility(visible: showFile, child: sizedBoxWidth(36.w)), + Visibility( + visible: showFile, + child: GestureDetector( + onTap: () async { + var result = + await SingleFilePickerMethod().pickFile(); + onImagePicked(result?.path ?? ""); + Get.back(); + }, + child: Column( + children: [ + CircleAvatar( + radius: 27.r, + backgroundColor: const Color(0xFFE8C69F80), + child: Icon( + Icons.file_copy_outlined, + size: 30.sp, + color: Colors.white, + ), + ), + SizedBox( + height: 6.h, + ), + Text( + 'File', + style: TextStyle( + fontSize: 13.sp, + color: const Color(0xff444444), + fontFamily: 'Poppins'), + ) + ], + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/lib/Utils/Common/SingleFilePicker.dart b/lib/Utils/Common/SingleFilePicker.dart new file mode 100644 index 0000000..6eb0139 --- /dev/null +++ b/lib/Utils/Common/SingleFilePicker.dart @@ -0,0 +1,23 @@ +import 'dart:io'; + +import 'package:file_picker/file_picker.dart'; + +class SingleFilePickerMethod { + Future pickFile() async { + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: [ + 'jpg', + 'jpeg', + 'png', + 'pdf' + ], // Define the allowed file types + ); + + if (result != null) { + return File(result.files.single.path!); + } else { + return null; + } + } +} diff --git a/lib/controller/profile_image_controller.dart b/lib/controller/profile_image_controller.dart new file mode 100644 index 0000000..063a8d8 --- /dev/null +++ b/lib/controller/profile_image_controller.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:image_cropper/image_cropper.dart'; +import 'package:image_picker/image_picker.dart'; + +class ProfileImageController extends GetxController { + RxString profilePicPath = "".obs; + //RxString fileNameFromPath = "".obs; + + void getImage(ImageSource imgSource) async { + final ImagePicker picker = ImagePicker(); + print('profilePicPath $profilePicPath'); + final XFile? pickedImg = await picker.pickImage(source: imgSource); + if (pickedImg != null) { + final CroppedFile? croppedImg = await ImageCropper().cropImage( + sourcePath: pickedImg.path, + aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1), + compressFormat: ImageCompressFormat.jpg, + maxHeight: 512, + maxWidth: 512, + compressQuality: 100, + cropStyle: CropStyle.circle, + aspectRatioPresets: [ + CropAspectRatioPreset.square, + ], + uiSettings: [ + AndroidUiSettings( + toolbarTitle: "Crop Image", + toolbarColor: Get.theme.appBarTheme.backgroundColor, + // toolbarWidgetColor: ColorConstants.kWhite, + backgroundColor: Colors.black, + activeControlsWidgetColor: Colors.red, + // initAspectRatio: CropAspectRatioPreset.original, + cropFrameColor: Colors.white, + lockAspectRatio: false, + ), + IOSUiSettings( + title: 'Crop Image', + ), + ]); + if (croppedImg != null) { + // profilPic = croppedImg.path; + profilePicPath.value = croppedImg.path; + + // Get.back(); + // fileNameFromPath.value = extractFileName(croppedImg.path); + } + } + } +} diff --git a/lib/resources/routes/route_name.dart b/lib/resources/routes/route_name.dart index c84d058..8bcc989 100644 --- a/lib/resources/routes/route_name.dart +++ b/lib/resources/routes/route_name.dart @@ -44,4 +44,8 @@ class RouteName { //contact us static const String contactUsMain = '/contactUsMain'; static const String contactUsMainDetails = '/contactUsMainDetails'; + + //my Profile + + static const String myProfileScreen = '/myProfileScreen'; } diff --git a/lib/resources/routes/routes.dart b/lib/resources/routes/routes.dart index 8250322..c8be6fb 100644 --- a/lib/resources/routes/routes.dart +++ b/lib/resources/routes/routes.dart @@ -7,6 +7,7 @@ import 'package:traderscircuit/view/Sidemenu/FaqScreen.dart'; import 'package:traderscircuit/view/Sidemenu/PrivacyPolicy.dart'; import 'package:traderscircuit/view/Sidemenu/TermsAndCondition.dart'; import 'package:traderscircuit/view/Sidemenu/contactUs/contact_us_main.dart'; +import 'package:traderscircuit/view/Sidemenu/myProfile/my_profile_screen.dart'; import 'package:traderscircuit/view/login/AddDetails.dart'; import 'package:traderscircuit/view/login/Kyc.dart'; @@ -156,6 +157,11 @@ class AppRoutes { GetPage( name: RouteName.contactUsMainDetails, page: () => const ContactUsDetailsScreen(), + ), + //my profile + GetPage( + name: RouteName.myProfileScreen, + page: () => const MyProfileScreen(), ) ]; } diff --git a/lib/view/Sidemenu/Sidemenu.dart b/lib/view/Sidemenu/Sidemenu.dart index fdb9696..5ccafa4 100644 --- a/lib/view/Sidemenu/Sidemenu.dart +++ b/lib/view/Sidemenu/Sidemenu.dart @@ -98,7 +98,7 @@ class _SideMenuState extends State { InkWell( onTap: () { setState(() { - // Get.toNamed(RouteName.investorprofile); + Get.toNamed(RouteName.myProfileScreen); }); }, child: Padding( diff --git a/lib/view/Sidemenu/myProfile/my_profile_screen.dart b/lib/view/Sidemenu/myProfile/my_profile_screen.dart new file mode 100644 index 0000000..4c8e4c7 --- /dev/null +++ b/lib/view/Sidemenu/myProfile/my_profile_screen.dart @@ -0,0 +1,321 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:gap/gap.dart'; +import 'package:get/get.dart'; + +import '../../../Utils/Common/CommonAppbar.dart'; +import '../../../Utils/Common/CustomTextFormField.dart'; +import '../../../Utils/Common/ImageUpload.dart'; +import '../../../Utils/Common/commonBotton.dart'; +import '../../../Utils/text.dart'; +import '../../../controller/profile_image_controller.dart'; +import '../../onBoarding/splashScreen1.dart'; + +class MyProfileScreen extends StatefulWidget { + const MyProfileScreen({super.key}); + + @override + State createState() => _MyProfileScreenState(); +} + +class _MyProfileScreenState extends State { + final ProfileImageController editProfileImage = + Get.put(ProfileImageController()); + RxBool isEdit = false.obs; + final GlobalKey formK = GlobalKey(); + TextEditingController fullNameController = TextEditingController(); + TextEditingController emailController = TextEditingController(); + TextEditingController phoneNoController = TextEditingController(); + TextEditingController dobController = TextEditingController(); + TextEditingController cityController = TextEditingController(); + + DateTime timebackPressed = DateTime.now(); + + Future _selectDate(BuildContext context) async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(1900), + lastDate: DateTime.now(), + builder: (context, child) { + return Theme( + data: Theme.of(context).copyWith( + colorScheme: const ColorScheme.light( + surface: Colors.black, + onSurface: Colors.white, + primary: Color(0xff9A0000), + onPrimary: Colors.white, + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: Colors.white, + ), + ), + ), + child: child!); + }); + + if (picked != null && picked != DateTime.now()) { + setState(() { + dobController.text = "${picked.toLocal()}".split(' ')[0]; + final birthDate = DateTime( + picked.year, + picked.month, + picked.day, + ); + }); + } + } + + @override + Widget build(BuildContext context) { + return Obx( + () => Form( + key: formK, + child: Scaffold( + appBar: CommonAppbar( + height: 75, + titleTxt: "", + customActionWidget: text16W400(""), + ), + backgroundColor: Colors.black, + extendBody: true, + body: Stack( + children: [ + const CommonBlurLeft(), + const CommonBlurRight(), + Stack( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + child: ListView( + physics: const BouncingScrollPhysics(), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + text25W600("My Profile"), + isEdit.value + ? const SizedBox() + : InkWell( + onTap: () { + isEdit.value = true; + }, + child: CircleAvatar( + radius: 20.r, + backgroundColor: const Color(0xFF5A5A5A), + child: Icon( + Icons.edit, + size: 20.sp, + color: Colors.white, + ), + ), + ), + ], + ), + const Gap(20), + Center( + child: Stack( + children: [ + Obx( + () => + editProfileImage.profilePicPath.value != '' + ? ClipOval( + child: SizedBox.fromSize( + size: Size.fromRadius(60.r), + child: editProfileImage + .profilePicPath + .value != + '' + ? Image( + image: FileImage( + File( + editProfileImage + .profilePicPath + .value, + ), + ), + fit: BoxFit.cover, + width: 200.w, + height: 200.h, + ) + : Image.asset( + "assets/images/blank-profile-picture-973460_1280.png"), + ), + ) + : ClipOval( + child: SizedBox.fromSize( + size: Size.fromRadius(60.r), + child: + // ProfileObj?.user?.profileImage != + // null + // ? ClipOval( + // child: SizedBox.fromSize( + // size: Size.fromRadius(25.r), + // child: CircleAvatar( + // backgroundImage: + // NetworkImage(ProfileObj! + // .user! + // .profileImage!), + // radius: 25.r, + // ), + // ), + // ) + // : + Image.asset( + "assets/images/png/Ellipse 560 (1).png", + width: 130, + height: 130, + )), + ), + ), + Positioned( + right: 0, + bottom: 0, + child: GestureDetector( + onTap: () { + ImageUploadBottomSheet().showModal( + context, + false, + (result) { + print("File path is $result"); + editProfileImage.profilePicPath.value = + result; + }, + ); + }, + child: CircleAvatar( + radius: 20.r, + backgroundColor: const Color(0xFF5A5A5A), + child: Icon( + Icons.camera_alt_outlined, + size: 20.sp, + color: Colors.white, + ), + ), + ), + ), + ], + ), + ), + Row( + children: [ + text18W400("Full Name"), + ], + ), + SizedBox( + height: 15.h, + ), + CustomTextFormField( + textEditingController: fullNameController, + enabled: isEdit.value, + validator: (value) { + if (value == "") { + return "Name is Required"; + } + }, + ), + SizedBox( + height: 30.h, + ), + Row( + children: [ + text18W400("Email Address"), + ], + ), + SizedBox( + height: 15.h, + ), + CustomTextFormField( + textEditingController: emailController, + enabled: isEdit.value, + texttype: TextInputType.emailAddress, + ), + SizedBox( + height: 30.h, + ), + Row( + children: [ + text18W400("Phone Number"), + ], + ), + SizedBox( + height: 15.h, + ), + CustomTextFormField( + textEditingController: phoneNoController, + enabled: isEdit.value, + texttype: TextInputType.phone, + ), + SizedBox( + height: 30.h, + ), + Row( + children: [ + text18W400("Date Of Birth"), + ], + ), + SizedBox( + height: 15.h, + ), + CustomTextFormField( + textEditingController: dobController, + enabled: isEdit.value, + suffixIcon: const Icon( + Icons.calendar_month_outlined, + color: Colors.white, + ), + readonly: true, + onTap: () { + _selectDate(context); + }, + ), + SizedBox( + height: 30.h, + ), + Row( + children: [ + text18W400("City"), + ], + ), + SizedBox( + height: 15.h, + ), + CustomTextFormField( + textEditingController: cityController, + enabled: isEdit.value, + ), + SizedBox( + height: 40.h, + ), + !isEdit.value + ? const SizedBox() + : SizedBox( + width: Get.width, + child: kycBtn( + text: "Save", + onTap: () { + final isValid = + formK.currentState?.validate(); + + if (isValid!) {} + }, + bgClr: const Color(0xFF6C0000), + borderClr: const Color(0xFF990000), + ), + ), + ], + ), + ) + ], + ) + ], + ), + ), + ), + ); + } +}