Houshan-Basa/lib/ui/screens/setting/edit_profile_page.dart

765 lines
45 KiB
Dart

// ignore_for_file: deprecated_member_use_from_same_package, use_build_context_synchronously
import 'package:cross_file/cross_file.dart';
import 'package:dio/dio.dart';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hoshan/core/gen/assets.gen.dart';
import 'package:hoshan/core/services/api/dio_service.dart';
import 'package:hoshan/data/model/ai/credit_model.dart';
import 'package:hoshan/data/repository/auth_repository.dart';
import 'package:hoshan/ui/screens/setting/cubit/check_username_cubit.dart';
import 'package:hoshan/ui/screens/splash/cubit/user_info_cubit.dart';
import 'package:hoshan/ui/theme/colors.dart';
import 'package:hoshan/ui/theme/responsive.dart';
import 'package:hoshan/ui/theme/text.dart';
import 'package:hoshan/ui/widgets/components/animations/animated_visibility.dart';
import 'package:hoshan/ui/widgets/components/button/circle_icon_btn.dart';
import 'package:hoshan/ui/widgets/components/button/loading_button.dart';
import 'package:hoshan/ui/widgets/components/dialog/bottom_sheets.dart';
import 'package:hoshan/ui/widgets/components/dialog/dialog_handler.dart';
import 'package:hoshan/ui/widgets/components/image/custome_image.dart';
import 'package:hoshan/ui/widgets/components/image/network_image.dart';
import 'package:hoshan/ui/widgets/components/snackbar/snackbar_manager.dart';
import 'package:hoshan/ui/widgets/components/text/auth_text_field.dart';
import 'package:hoshan/ui/widgets/components/text/card_number_input.dart';
import 'package:hoshan/ui/widgets/sections/header/reversible_appbar.dart';
class EditProfilePage extends StatefulWidget {
const EditProfilePage({super.key});
@override
State<EditProfilePage> createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
TextEditingController username = TextEditingController();
TextEditingController mobile = TextEditingController();
TextEditingController email = TextEditingController();
TextEditingController pasword = TextEditingController();
TextEditingController rePassword = TextEditingController();
String? imageUrl;
String cardNumber = '';
final ValueNotifier<XFile?> image = ValueNotifier(null);
final ValueNotifier<bool> loading = ValueNotifier(false);
final ValueNotifier<bool> showCard = ValueNotifier(false);
@override
void initState() {
imageUrl = UserInfoCubit.userInfoModel.image;
if (UserInfoCubit.userInfoModel.cardNumber != null) {
cardNumber = UserInfoCubit.userInfoModel.cardNumber!;
showCard.value = true;
}
if (UserInfoCubit.userInfoModel.username != null) {
username.text = UserInfoCubit.userInfoModel.username!;
}
if (UserInfoCubit.userInfoModel.mobileNumber != null) {
mobile.text = UserInfoCubit.userInfoModel.mobileNumber!;
}
if (UserInfoCubit.userInfoModel.email != null) {
email.text = UserInfoCubit.userInfoModel.email!;
}
super.initState();
}
@override
dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: ReversibleAppbar(
context,
titleText: 'ویرایش پروفایل',
),
body: Responsive(context).maxWidthInDesktop(
child: (contxet, maxWidth) => Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: BlocConsumer<UserInfoCubit, UserInfoState>(
listener: (context, state) {},
builder: (context, state) {
return Column(
children: [
Center(
child: Stack(
children: [
ValueListenableBuilder(
valueListenable: image,
builder: (context, date, _) {
return Container(
width: 140,
height: 140,
margin: const EdgeInsets.only(
top: 24, bottom: 40),
decoration: BoxDecoration(
color: AppColors.gray[300],
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
blurRadius: 6,
color: const Color(0xff4d4d4d)
.withValues(alpha: 0.4))
]),
child: ClipOval(
child: date != null
? GestureDetector(
onTap: () => DialogHandler(
context: context)
.showImageHero(
image: date.path),
child: CustomeImage(
src: date.path,
fit: BoxFit.cover,
),
)
: imageUrl != null &&
imageUrl!.isNotEmpty
? ImageNetwork(
url: DioService.baseURL +
imageUrl!,
showHero: true,
)
: Padding(
padding:
const EdgeInsets.all(
32),
child: Assets
.icon.bold.profile
.svg(),
),
),
);
}),
Positioned(
bottom: 0 + 40,
left: 0,
child: CircleIconBtn(
icon: Assets.icon.outline.galleryAdd,
color: AppColors.secondryColor.defaultShade,
iconColor: Colors.white,
size: 48,
iconPadding: const EdgeInsets.all(10),
onTap: () =>
BottomSheetHandler(context).showPickImage(
withAvatar: true,
profile: true,
onSelect: (file) {
image.value = file;
},
),
),
)
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: [
BlocBuilder<CheckUsernameCubit,
CheckUsernameState>(
builder: (context, state) {
return Column(
children: [
AuthTextField(
justEnglish: true,
success: state is CheckUsernameSuccess
? Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Icon(
Icons.check_circle,
color: AppColors
.green.defaultShade,
size: 16,
),
const SizedBox(
width: 8,
),
Expanded(
child: Text(
'نام کاربری در دسترس است',
style: AppTextStyles
.body5
.copyWith(
color: AppColors
.green
.defaultShade),
),
),
],
)
: null,
error: state is CheckUsernameFail ||
state is CheckUsernameEmpty
? Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Icon(
Icons
.warning_amber_rounded,
color: AppColors
.red.defaultShade,
size: 16,
),
const SizedBox(
width: 8,
),
Expanded(
child: Text(
state is CheckUsernameFail
? 'نام کاربری قبلا انتخاب شده است'
: 'نام کاربری کوتاه است',
style: AppTextStyles
.body5
.copyWith(
color: AppColors
.red
.defaultShade),
),
),
],
)
: null,
label: 'نام کاربری',
suffix: Padding(
padding: const EdgeInsets.all(8.0),
child: Assets
.icon.outline.profileTick
.svg(
color: state
is CheckUsernameFail
? AppColors
.red.defaultShade
: state
is CheckUsernameSuccess
? AppColors.green
.defaultShade
: Theme.of(context)
.colorScheme
.primary),
),
controller: username,
onChange: (usernameText) {
context
.read<CheckUsernameCubit>()
.loading();
EasyDebounce.debounce('my-username',
const Duration(seconds: 1), () {
context
.read<CheckUsernameCubit>()
.check(usernameText);
});
},
),
if (state is CheckUsernameLoading)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 18, vertical: 4),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
SizedBox(
width: 16,
height: 16,
child:
CircularProgressIndicator(
color: Theme.of(context)
.colorScheme
.primary,
),
),
const SizedBox(
width: 8,
),
Expanded(
child: Text(
'درحال بررسی',
style: AppTextStyles.body5
.copyWith(
color: Theme.of(
context)
.colorScheme
.primary),
),
),
],
),
)
],
);
},
),
if (mobile.text.isNotEmpty)
Column(
children: [
const SizedBox(
height: 24,
),
AuthTextField(
label: 'تلفن همراه',
enabled: false,
suffix: Padding(
padding: const EdgeInsets.all(10.0),
child: Assets.icon.outline.call.svg(
color: Theme.of(context)
.colorScheme
.primary),
),
controller: mobile,
),
],
),
if (email.text.isNotEmpty)
Column(
children: [
const SizedBox(
height: 24,
),
AuthTextField(
label: 'ایمیل',
enabled: false,
suffix: Padding(
padding: const EdgeInsets.all(10.0),
child: Icon(Icons.email_rounded,
color: Theme.of(context)
.colorScheme
.primary)),
controller: email,
),
],
),
// const SizedBox(
// height: 24,
// ),
// AuthTextField(
// label: 'آدرس ایمیل',
// suffix: Padding(
// padding: const EdgeInsets.all(10.0),
// child: Assets.icon.outline.smsTracking.svg(),
// ),
// controller: email,
// ),
const SizedBox(
height: 24,
),
ValueListenableBuilder(
valueListenable: rePassword,
builder: (context, rePass, child) {
return ValueListenableBuilder(
valueListenable: pasword,
builder: (context, pass, child) {
return Column(
children: [
// AuthTextField(
// label: 'رمز عبور',
// textInputAction:
// TextInputAction.next,
// suffix: Padding(
// padding: const EdgeInsets.all(
// 10.0),
// child: Assets
// .icon.outline.lock
// .svg(
// color: pass.text !=
// rePass.text
// ? AppColors.red
// .defaultShade
// : Theme.of(
// context)
// .colorScheme
// .primary),
// ),
// controller: pasword,
// error: pass.text.length < 8 &&
// pass.text.isNotEmpty
// ? Row(
// crossAxisAlignment:
// CrossAxisAlignment
// .start,
// children: [
// Icon(
// Icons
// .warning_amber_rounded,
// color: AppColors.red
// .defaultShade,
// size: 16,
// ),
// const SizedBox(
// width: 8,
// ),
// Expanded(
// child: Text(
// 'رمز عبور حداقل باید ۸ کارکتر باشد',
// style: AppTextStyles
// .body5
// .copyWith(
// color: AppColors
// .red
// .defaultShade),
// ),
// ),
// ],
// )
// : pass.text != rePass.text
// ? const SizedBox()
// : null,
// ),
// const SizedBox(
// height: 24,
// ),
// ValueListenableBuilder(
// valueListenable: rePassword,
// builder:
// (context, pass, child) {
// return AuthTextField(
// label: 'تکرار رمز عبور',
// suffix: Padding(
// padding:
// const EdgeInsets.all(
// 10.0),
// child: Assets
// .icon.outline.lock
// .svg(
// color: pasword
// .text !=
// pass.text
// ? AppColors
// .red
// .defaultShade
// : Theme.of(
// context)
// .colorScheme
// .primary),
// ),
// controller: rePassword,
// error:
// pasword.text !=
// pass.text
// ? Row(
// crossAxisAlignment:
// CrossAxisAlignment
// .start,
// children: [
// Icon(
// Icons
// .warning_amber_rounded,
// color: AppColors
// .red
// .defaultShade,
// size: 16,
// ),
// const SizedBox(
// width: 8,
// ),
// Expanded(
// child: Text(
// 'رمز عبور با تکرار آن مطابقت ندارد',
// style: AppTextStyles
// .body5
// .copyWith(
// color: AppColors.red.defaultShade),
// ),
// ),
// ],
// )
// : null,
// );
// },
// ),
],
);
},
);
}),
const SizedBox(
height: 24,
),
ValueListenableBuilder(
valueListenable: showCard,
builder: (context, show, child) {
return Column(
children: [
// GestureDetector(
// onTap: () => showCard.value = !show,
// child: Row(
// children: [
// Transform.scale(
// scale: 1.4,
// child: Checkbox(
// value: show,
// activeColor: AppColors
// .secondryColor
// .defaultShade,
// side: BorderSide(
// width: 1,
// color: Theme.of(context)
// .colorScheme
// .onSurface),
// onChanged: (value) {
// showCard.value =
// value ?? false;
// },
// materialTapTargetSize:
// MaterialTapTargetSize
// .shrinkWrap,
// shape:
// RoundedRectangleBorder(
// borderRadius:
// BorderRadius
// .circular(
// 6)),
// ),
// ),
// // Expanded(
// // child: Text(
// // 'تمایل به کسب درآمد از طریق ساخت دستیار دارم.',
// // style: AppTextStyles.body4
// // .copyWith(
// // color: Theme.of(
// // context)
// // .colorScheme
// // .onSurface),
// // ),
// // ),
// ],
// ),
// ),
AnimatedVisibility(
isVisible: show,
duration: const Duration(
milliseconds: 300),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const SizedBox(
height: 24,
),
Text(
'وارد کردن شماره کارت برای دریافت درآمد:',
style: AppTextStyles.body4
.copyWith(
color: Theme.of(
context)
.colorScheme
.onSurface),
),
Padding(
padding: const EdgeInsets
.symmetric(
vertical: 8.0),
child: CardNumberInput(
initialValue: cardNumber,
onChange: (value) {
cardNumber = value;
},
),
),
Row(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Icon(
Icons
.warning_amber_rounded,
color: AppColors
.red.defaultShade,
size: 32,
),
const SizedBox(
width: 4,
),
Expanded(
child: Text(
'شماره کارت شما برای انتقال درآمد ماهانه استفاده می‌شود. حریم خصوصی شما تضمین شده است و اطلاعات شما کاملا محرمانه خواهد بود.',
textAlign:
TextAlign.justify,
style: AppTextStyles
.body5
.copyWith(
color: AppColors
.black[
300]),
),
)
],
)
],
))
],
);
}),
const SizedBox(
height: 40,
),
],
),
),
)
],
);
},
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 24),
color: Theme.of(context).scaffoldBackgroundColor,
child: ValueListenableBuilder(
valueListenable: loading,
builder: (context, data, _) {
return LoadingButton(
width: MediaQuery.sizeOf(context).width,
height: 40,
color: AppColors.primaryColor.defaultShade,
loading: data,
radius: 24,
onPressed: data
? null
: () async {
try {
loading.value = true;
if (username.text !=
UserInfoCubit.userInfoModel.username &&
(context.read<CheckUsernameCubit>().state
is CheckUsernameSuccess)) {
try {
await AuthRepository.editUsername(
username.text);
} on DioException catch (e) {
SnackBarManager(context,
id: 'changeUsername')
.show(
status: SnackBarStatus.error,
message:
'خطا در تغییر نام کاربری دوباره سعی کنید');
Future.delayed(const Duration(seconds: 3));
if (kDebugMode) {
print('Error is: $e');
}
}
}
if (pasword.text.isNotEmpty) {
if (pasword.text == rePassword.text) {
try {
await AuthRepository.editPasswordProfile(
pasword.text);
} on DioException catch (e) {
SnackBarManager(context,
id: 'changePassword')
.show(
status: SnackBarStatus.error,
message:
'خطا در تغییر رمز دوباره سعی کنید');
Future.delayed(
const Duration(seconds: 3));
if (kDebugMode) {
print('Error is: $e');
}
}
}
}
if (image.value != null) {
try {
await AuthRepository.editImageProfile(
image.value!);
} on DioException catch (e) {
SnackBarManager(context, id: 'changeImage')
.show(
status: SnackBarStatus.error,
message:
'خطا در آپلود فایل دوباره سعی کنید');
Future.delayed(const Duration(seconds: 3));
if (kDebugMode) {
print('Error is: $e');
}
}
}
// if (cardNumber !=
// UserInfoCubit.userInfoModel.cardNumber) {
// if (cardNumber.length == 16 ||
// cardNumber.isEmpty) {
try {
await AuthRepository.editCardNumber(
showCard.value ? cardNumber : '');
} on DioException catch (e) {
SnackBarManager(context, id: 'changeCard')
.show(
status: SnackBarStatus.error,
message:
'خطا در ثبت شماره کارت دوباره سعی کنید',
);
Future.delayed(const Duration(seconds: 3));
if (kDebugMode) {
print('Error is: $e');
}
}
// }
// }
try {
await context
.read<UserInfoCubit>()
.getUserInfo()
.then(
(value) {
SnackBarManager(context).show(
status: SnackBarStatus.success,
message:
'اطلاعات با موفقیت بروزرسانی شد');
},
);
context.read<UserInfoCubit>().changeCredit(
CreditModel(
credit: UserInfoCubit
.userInfoModel.credit,
freeCredit: UserInfoCubit
.userInfoModel.freeCredit));
} catch (e) {
if (kDebugMode) {
print('Error is: $e');
}
}
} catch (e) {
if (kDebugMode) {
print('Error is: $e');
}
}
loading.value = false;
},
child: Text(
'تایید',
style:
AppTextStyles.body4.copyWith(color: Colors.white),
),
);
}),
)
],
),
),
);
}
}