chore: clean up unused imports, update routing for authentication pages, and enhance UI components in the profile and captcha widgets

This commit is contained in:
2025-12-24 11:51:41 +03:30
parent 3eccf492ff
commit 60c58ef17e
17 changed files with 428 additions and 625 deletions

View File

@@ -11,98 +11,105 @@ class AuthPage extends GetView<AuthLogic> {
@override
Widget build(BuildContext context) {
return Scaffold(
body:PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
Get.back(result: -1);
},
child: Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: [
Assets.vec.bgAuthSvg.svg(fit: BoxFit.fill),
body: PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
Get.back(result: -1);
},
child: Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: [
Assets.icons.bgAuthDam.svg(fit: BoxFit.fill),
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10.r),
child: FadeTransition(
opacity: controller.textAnimation,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 12,
children: [
Text(
'به سامانه رصدیار خوش آمدید!',
textAlign: TextAlign.right,
style: AppFonts.yekan25Bold.copyWith(color: Colors.white),
),
Text(
'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی',
textAlign: TextAlign.center,
style: AppFonts.yekan16.copyWith(color: Colors.white),
),
],
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10.r),
child: FadeTransition(
opacity: controller.textAnimation,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 12,
children: [
Text(
'به سامانه رصدیار خوش آمدید!',
textAlign: TextAlign.right,
style: AppFonts.yekan25Bold.copyWith(
color: Colors.white,
),
),
Text(
'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی',
textAlign: TextAlign.center,
style: AppFonts.yekan16.copyWith(color: Colors.white),
),
],
),
),
),
),
),
Obx(() {
final screenHeight = MediaQuery.of(context).size.height;
final targetTop = (screenHeight - 676) / 2;
Obx(() {
final screenHeight = MediaQuery.of(context).size.height;
final targetTop = (screenHeight - 676) / 2;
return AnimatedPositioned(
duration: const Duration(milliseconds: 1200),
curve: Curves.linear,
top: controller.showCard.value ? targetTop : screenHeight,
left: 10.r,
right: 10.r,
child: Container(
width: 381.w,
height: 676.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(40),
),
child: Column(
children: [
SizedBox(height: 50.h),
LogoWidget(),
SizedBox(height: 20.h),
useAndPassFrom(),
SizedBox(height: 24.h),
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'مطالعه بیانیه ',
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDark),
),
TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
Get.bottomSheet(
privacyPolicyWidget(),
isScrollControlled: true,
enableDrag: true,
ignoreSafeArea: false,
);
},
text: 'حریم خصوصی',
style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal),
),
],
return AnimatedPositioned(
duration: const Duration(milliseconds: 1200),
curve: Curves.linear,
top: controller.showCard.value ? targetTop : screenHeight,
left: 10.r,
right: 10.r,
child: Container(
width: 381.w,
height: 676.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(40),
),
child: Column(
children: [
SizedBox(height: 50.h),
LogoWidget(),
SizedBox(height: 20.h),
useAndPassFrom(),
SizedBox(height: 24.h),
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'مطالعه بیانیه ',
style: AppFonts.yekan16.copyWith(
color: AppColor.darkGreyDark,
),
),
TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
Get.bottomSheet(
privacyPolicyWidget(),
isScrollControlled: true,
enableDrag: true,
ignoreSafeArea: false,
);
},
text: 'حریم خصوصی',
style: AppFonts.yekan16.copyWith(
color: AppColor.blueNormal,
),
),
],
),
),
),
],
],
),
),
),
);
}),
],
)),
);
}),
],
),
),
);
}
@@ -115,17 +122,15 @@ class AuthPage extends GetView<AuthLogic> {
child: Column(
children: [
RTextField(
height: 48.h,
isFullHeight: true,
label: 'نام کاربری',
maxLength: 11,
maxLines: 1,
controller: controller.usernameController.value,
keyboardType: TextInputType.number,
initText: controller.usernameController.value.text,
autofillHints: [AutofillHints.username],
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1),
),
borderColor: AppColor.textColor,
onChanged: (value) async {
controller.usernameController.value.text = value;
controller.usernameController.refresh();
@@ -134,14 +139,15 @@ class AuthPage extends GetView<AuthLogic> {
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
child: Assets.vec.callSvg.svg(width: 12, height: 12),
),
suffixIcon: controller.usernameController.value.text.trim().isNotEmpty
suffixIcon:
controller.usernameController.value.text.trim().isNotEmpty
? clearButton(() {
controller.usernameController.value.clear();
controller.usernameController.refresh();
})
: null,
validator: (value) {
/* if (value == null || value.isEmpty) {
/* if (value == null || value.isEmpty) {
return '⚠️ شماره موبایل را وارد کنید';
} else if (value.length < 10) {
return '⚠️ شماره موبایل باید 11 رقم باشد';
@@ -149,25 +155,20 @@ class AuthPage extends GetView<AuthLogic> {
return null;
},
style: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal),
labelStyle: AppFonts.yekan13,
boxConstraints: const BoxConstraints(
maxHeight: 40,
minHeight: 40,
maxWidth: 40,
minWidth: 40,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
labelStyle: AppFonts.yekan13,
),
const SizedBox(height: 26),
SizedBox(height: 16.h),
ObxValue(
(passwordController) => RTextField(
height: 48.h,
isFullHeight: true,
label: 'رمز عبور',
filled: false,
obscure: true,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1),
),
borderColor: AppColor.textColor,
controller: passwordController.value,
autofillHints: [AutofillHints.password],
variant: RTextFieldVariant.password,
@@ -182,18 +183,10 @@ class AuthPage extends GetView<AuthLogic> {
return null;
},
style: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal),
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
labelStyle: AppFonts.yekan13,
prefixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
child: Assets.vec.keySvg.svg(width: 12, height: 12),
),
boxConstraints: const BoxConstraints(
maxHeight: 34,
minHeight: 34,
maxWidth: 34,
minWidth: 34,
),
),
controller.passwordController,
),
@@ -208,36 +201,44 @@ class AuthPage extends GetView<AuthLogic> {
ObxValue((data) {
return Checkbox(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity(horizontal: -4, vertical: 4),
visualDensity: VisualDensity(
horizontal: -4,
vertical: 4,
),
tristate: true,
value: data.value,
onChanged: (value) {
data.value = value ?? false;
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
activeColor: AppColor.blueNormal,
);
}, controller.rememberMe),
Text(
'مرا به خاطر بسپار',
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark),
style: AppFonts.yekan14.copyWith(
color: AppColor.darkGreyDark,
),
),
],
),
),
Obx(() {
return RElevated(
text: 'ورود',
backgroundColor: AppColor.blueNormal,
isLoading: controller.isLoading.value,
onPressed: controller.isDisabled.value
? null
: () async {
await controller.submitLoginForm();
},
width: Get.width,
height: 48,
height: 48.h,
);
}),
],
@@ -266,11 +267,16 @@ class AuthPage extends GetView<AuthLogic> {
children: [
Text(
'بيانيه حريم خصوصی',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'اطلاعات مربوط به هر شخص، حریم خصوصی وی محسوب می‌شود. حفاظت و حراست از اطلاعات شخصی در سامانه رصد یار، نه تنها موجب حفظ امنیت کاربران می‌شود، بلکه باعث اعتماد بیشتر و مشارکت آنها در فعالیت‌های جاری می‌گردد. هدف از این بیانیه، آگاه ساختن شما درباره ی نوع و نحوه ی استفاده از اطلاعاتی است که در هنگام استفاده از سامانه رصد یار ، از جانب شما دریافت می‌گردد. شرکت هوشمند سازان خود را ملزم به رعایت حریم خصوصی همه شهروندان و کاربران سامانه دانسته و آن دسته از اطلاعات کاربران را که فقط به منظور ارائه خدمات کفایت می‌کند، دریافت کرده و از انتشار آن یا در اختیار قرار دادن آن به دیگران خودداری مینماید.',
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8),
style: AppFonts.yekan14.copyWith(
color: AppColor.bgDark,
height: 1.8,
),
),
],
),
@@ -290,7 +296,9 @@ class AuthPage extends GetView<AuthLogic> {
children: [
Text(
'چگونگی جمع آوری و استفاده از اطلاعات کاربران',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'''الف: اطلاعاتی که شما خود در اختيار این سامانه قرار می‌دهيد، شامل موارد زيرهستند:
@@ -302,7 +310,10 @@ class AuthPage extends GetView<AuthLogic> {
⦁ تعداد بازدیدهای روزانه در درگاه.
⦁ هدف ما از دریافت این اطلاعات استفاده از آنها در تحلیل عملکرد کاربران درگاه می باشد تا بتوانیم در خدمت رسانی بهتر عمل کنیم.
''',
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8),
style: AppFonts.yekan14.copyWith(
color: AppColor.bgDark,
height: 1.8,
),
),
],
),
@@ -322,11 +333,16 @@ class AuthPage extends GetView<AuthLogic> {
children: [
Text(
'امنیت اطلاعات',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'متعهدیم که امنیت اطلاعات شما را تضمین نماییم و برای جلوگیری از هر نوع دسترسی غیرمجاز و افشای اطلاعات شما از همه شیوه‌‌های لازم استفاده می‌کنیم تا امنیت اطلاعاتی را که به صورت آنلاین گردآوری می‌کنیم، حفظ شود. لازم به ذکر است در سامانه ما، ممکن است به سایت های دیگری لینک شوید، وقتی که شما از طریق این لینک‌ها از سامانه ما خارج می‌شوید، توجه داشته باشید که ما بر دیگر سایت ها کنترل نداریم و سازمان تعهدی بر حفظ حریم شخصی آنان در سایت مقصد نخواهد داشت و مراجعه کنندگان میبایست به بیانیه حریم شخصی آن سایت ها مراجعه نمایند.',
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8),
style: AppFonts.yekan14.copyWith(
color: AppColor.bgDark,
height: 1.8,
),
),
],
),
@@ -335,240 +351,4 @@ class AuthPage extends GetView<AuthLogic> {
),
);
}
/*
Widget sendCodeForm() {
return ObxValue((data) {
return Form(
key: data.value,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
child: Column(
children: [
SizedBox(height: 26),
ObxValue((phoneController) {
return TextFormField(
controller: phoneController.value,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
gapPadding: 11,
),
labelText: 'شماره موبایل',
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
prefixIconConstraints: BoxConstraints(
maxHeight: 40,
minHeight: 40,
maxWidth: 40,
minWidth: 40,
),
prefixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
child: vecWidget(Assets.vecCallSvg),
),
suffix:
phoneController.value.text.trim().isNotEmpty
? clearButton(() {
phoneController.value.clear();
phoneController.refresh();
})
: null,
counterText: '',
),
keyboardType: TextInputType.numberWithOptions(
decimal: false,
signed: false,
),
maxLines: 1,
maxLength: 11,
onChanged: (value) {
if (controller.isOnError.value) {
controller.isOnError.value = !controller.isOnError.value;
data.value.currentState?.reset();
data.refresh();
phoneController.value.text = value;
}
phoneController.refresh();
},
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null) {
return '⚠️ شماره موبایل را وارد کنید';
} else if (value.length < 11) {
return '⚠️ شماره موبایل باید 11 رقم باشد';
}
return null;
},
style: AppFonts.yekan13,
);
}, controller.phoneOtpNumberController),
SizedBox(height: 26),
CaptchaWidget(),
SizedBox(height: 23),
RElevated(
text: 'ارسال رمز یکبار مصرف',
onPressed: () {
if (data.value.currentState?.validate() == true) {
controller.otpStatus.value = OtpStatus.sent;
controller.startTimer();
}
},
width: Get.width,
height: 48,
),
],
),
),
);
}, controller.formKeyOtp);
}
Widget confirmCodeForm() {
return ObxValue((data) {
return Form(
key: data.value,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
child: Column(
children: [
SizedBox(height: 26),
ObxValue((passwordController) {
return TextFormField(
controller: passwordController.value,
obscureText: controller.hidePassword.value,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
gapPadding: 11,
),
labelText: 'رمز عبور',
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
prefixIconConstraints: BoxConstraints(
maxHeight: 34,
minHeight: 34,
maxWidth: 34,
minWidth: 34,
),
prefixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
child: vecWidget(Assets.vecKeySvg),
),
suffix:
passwordController.value.text.trim().isNotEmpty
? GestureDetector(
onTap: () {
controller.hidePassword.value =
!controller.hidePassword.value;
},
child: Icon(
controller.hidePassword.value
? CupertinoIcons.eye
: CupertinoIcons.eye_slash,
),
)
: null,
counterText: '',
),
textInputAction: TextInputAction.done,
keyboardType: TextInputType.visiblePassword,
maxLines: 1,
onChanged: (value) {
if (controller.isOnError.value) {
controller.isOnError.value = !controller.isOnError.value;
data.value.currentState?.reset();
passwordController.value.text = value;
}
passwordController.refresh();
},
validator: (value) {
if (value == null || value.isEmpty) {
return '⚠️ رمز عبور را وارد کنید'; // "Please enter the password"
}
return null;
},
style: AppFonts.yekan13,
);
}, controller.passwordController),
SizedBox(height: 23),
ObxValue((timer) {
if (timer.value == 0) {
return TextButton(
onPressed: () {
controller.otpStatus.value = OtpStatus.reSend;
controller.startTimer();
},
child: Text(
style: AppFonts.yekan13.copyWith(
color: AppColor.blueNormal,
),
'ارسال مجدد کد یکبار مصرف',
),
);
} else {
return Text(
'اعتبار رمز ارسال شده ${controller.timeFormatted}',
style: AppFonts.yekan13,
);
}
}, controller.secondsRemaining),
RichText(
text: TextSpan(
children: [
TextSpan(
text: ' کد ارسال شده به شماره ',
style: AppFonts.yekan14.copyWith(
color: AppColor.darkGreyDark,
),
),
TextSpan(
text: controller.phoneOtpNumberController.value.text,
style: AppFonts.yekan13Bold.copyWith(
color: AppColor.darkGreyDark,
),
),
TextSpan(
recognizer:
TapGestureRecognizer()
..onTap = () {
controller.otpStatus.value = OtpStatus.init;
},
text: ' ویرایش',
style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal,
),
),
],
),
),
SizedBox(height: 23),
RElevated(
text: 'ورود',
onPressed: () {
if (controller.formKeyOtp.value.currentState?.validate() ==
true) {}
},
width: Get.width,
height: 48,
),
],
),
),
);
}, controller.formKeySentOtp);
}*/
}

View File

@@ -1,72 +1,21 @@
import 'package:rasadyar_core/core.dart' hide BaseLogic;
import 'package:rasadyar_livestock/features/common/auth/presentation/pages/logic.dart';
import 'package:rasadyar_livestock/presentation/page/auth/view.dart';
import 'package:rasadyar_livestock/presentation/page/map/logic.dart';
import 'package:rasadyar_livestock/presentation/page/map/widget/map_widget/logic.dart';
import 'package:rasadyar_livestock/presentation/page/profile/logic.dart';
import 'package:rasadyar_livestock/presentation/page/request_tagging/logic.dart';
import 'package:rasadyar_livestock/presentation/page/request_tagging/view.dart';
import 'package:rasadyar_livestock/presentation/page/requests/logic.dart';
import 'package:rasadyar_livestock/presentation/page/root/logic.dart';
import 'package:rasadyar_livestock/presentation/page/root/view.dart';
import 'package:rasadyar_livestock/presentation/page/tagging/logic.dart';
import 'package:rasadyar_livestock/presentation/page/tagging/view.dart';
import 'package:rasadyar_livestock/presentation/widgets/base_page/logic.dart';
import 'package:rasadyar_livestock/features/auth/presentation/pages/logic.dart';
import 'package:rasadyar_livestock/features/auth/presentation/pages/view.dart';
import 'package:rasadyar_livestock/presentation/widgets/captcha/logic.dart';
part 'routes.dart';
part 'app_routes.dart';
sealed class LiveStockPages {
LiveStockPages._();
sealed class AuthLiveStockPages {
AuthLiveStockPages._();
static final pages = [
GetPage(
name: LiveStockRoutes.auth,
name: AuthLiveStockRoutes.auth,
page: () => AuthPage(),
binding: BindingsBuilder(() {
Get.lazyPut(() => AuthLogic());
Get.lazyPut(() => CaptchaWidgetLogic());
}),
),
GetPage(
name: LiveStockRoutes.init,
page: () => RootPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.put(RootLogic());
Get.lazyPut(() => RequestsLogic());
Get.lazyPut(() => MapLogic());
Get.lazyPut(() => ProfileLogic());
Get.lazyPut(() => MapWidgetLogic());
Get.lazyPut(() => BaseLogic());
}),
children: [
/*GetPage(
name: LiveStockRoutes.requestTagging,
page: () => RequestTaggingPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => RequestTaggingLogic());
}),
),*/
],
),
GetPage(
name: LiveStockRoutes.requestTagging,
page: () => RequestTaggingPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => RequestTaggingLogic());
}),
),
GetPage(
name: LiveStockRoutes.tagging,
page: () => TaggingPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => TaggingLogic());
}),
),
];
}

View File

@@ -1,13 +1,8 @@
part of 'app_pages.dart';
part of 'pages.dart';
sealed class LiveStockRoutes {
LiveStockRoutes._();
sealed class AuthLiveStockRoutes {
AuthLiveStockRoutes._();
static const auth = '/AuthLiveStock';
static const init = '/liveStock';
static const requests = '/requests';
static const map = '/map';
static const profile = '/profile';
static const requestTagging = '$requests/tagging';
static const tagging = '/tagging';
}

View File

@@ -9,6 +9,7 @@ import 'package:rasadyar_livestock/data/repository/auth/auth_repository_imp.dart
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository.dart';
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository_imp.dart';
import 'package:rasadyar_livestock/data/service/live_stock_storage_service.dart';
import 'package:rasadyar_livestock/features/auth/presentation/routes/pages.dart';
import 'package:rasadyar_livestock/hive_registrar.g.dart';
import 'package:rasadyar_livestock/presentation/routes/app_pages.dart';
@@ -25,7 +26,10 @@ Future<void> setupLiveStockDI() async {
Get.lazyPut(() => LiveStockStorageService());
if (tokenService.baseurl.value == null) {
await tokenService.saveBaseUrl(Module.inspection, 'https://api.dam.rasadyar.net/');
await tokenService.saveBaseUrl(
Module.inspection,
'https://api.dam.rasadyar.net/',
);
}
// First register AppInterceptor with lazy callbacks
@@ -48,7 +52,7 @@ Future<void> setupLiveStockDI() async {
},
clearTokenCallback: () async {
await tokenService.deleteModuleTokens(Module.liveStocks);
Get.offAllNamed(LiveStockRoutes.auth, arguments: Module.liveStocks);
Get.offAllNamed(AuthLiveStockRoutes.auth, arguments: Module.liveStocks);
},
authArguments: Module.liveStocks,
),
@@ -73,7 +77,8 @@ Future<void> setupLiveStockDI() async {
);
diLiveStock.registerLazySingleton<AuthRepository>(
() => AuthRepositoryImp(authRemote: diLiveStock.get<AuthRemoteDataSource>()),
() =>
AuthRepositoryImp(authRemote: diLiveStock.get<AuthRemoteDataSource>()),
);
//endregion
@@ -82,7 +87,9 @@ Future<void> setupLiveStockDI() async {
() => LivestockRemoteDataSourceImp(),
);
diLiveStock.registerLazySingleton<TmpLocalDataSource>(() => TmpLocalDataSource());
diLiveStock.registerLazySingleton<TmpLocalDataSource>(
() => TmpLocalDataSource(),
);
diLiveStock.registerLazySingleton<LivestockRepository>(
() => LivestockRepositoryImp(

View File

@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_livestock/features/auth/presentation/routes/pages.dart';
import 'package:rasadyar_livestock/presentation/routes/app_pages.dart';
import 'logic.dart';
@@ -84,7 +85,10 @@ class ProfilePage extends GetView<ProfileLogic> {
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10),
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 10,
),
child: userProfileInformation(),
),
),
@@ -99,18 +103,27 @@ class ProfilePage extends GetView<ProfileLogic> {
title: 'تغییر رمز عبور',
selected: true,
onPressed: () {
Get.bottomSheet(changePasswordBottomSheet(), isScrollControlled: true);
Get.bottomSheet(
changePasswordBottomSheet(),
isScrollControlled: true,
);
},
icon: Assets.vec.lockSvg.path,
),
cardActionWidget(
title: 'خروج',
selected: true,
color: ColorFilter.mode(Colors.redAccent, BlendMode.srcIn),
color: ColorFilter.mode(
Colors.redAccent,
BlendMode.srcIn,
),
cardColor: Color(0xFFEFEFEF),
textColor: AppColor.redDarkerText,
onPressed: () {
Get.bottomSheet(exitBottomSheet(), isScrollControlled: true);
Get.bottomSheet(
exitBottomSheet(),
isScrollControlled: true,
);
},
icon: Assets.vec.logoutSvg.path,
),
@@ -157,7 +170,9 @@ class ProfilePage extends GetView<ProfileLogic> {
children: [
Text(
'اطلاعات هویتی',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
),
Container(width: 37.w, height: 1.h, color: AppColor.greenNormal),
],
@@ -199,7 +214,11 @@ class ProfilePage extends GetView<ProfileLogic> {
content: /*item.province ??*/ 'نامشخص',
icon: Assets.vec.pictureFrameSvg.path,
),
itemList(title: 'شهر', content: /* item.city ?? */ 'نامشخص', icon: Assets.vec.mapSvg.path),
itemList(
title: 'شهر',
content: /* item.city ?? */ 'نامشخص',
icon: Assets.vec.mapSvg.path,
),
],
);
/* return ObxValue((data) {
@@ -300,12 +319,25 @@ class ProfilePage extends GetView<ProfileLogic> {
child: SvgGenImage.vec(icon).svg(
width: 20.w,
height: 20.h,
colorFilter: ColorFilter.mode(AppColor.mediumGreyNormalActive, BlendMode.srcIn),
colorFilter: ColorFilter.mode(
AppColor.mediumGreyNormalActive,
BlendMode.srcIn,
),
),
),
Text(title, style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyNormalActive)),
Text(
title,
style: AppFonts.yekan12.copyWith(
color: AppColor.mediumGreyNormalActive,
),
),
Spacer(),
Text(content, style: AppFonts.yekan13.copyWith(color: AppColor.mediumGreyNormalHover)),
Text(
content,
style: AppFonts.yekan13.copyWith(
color: AppColor.mediumGreyNormalHover,
),
),
],
),
);
@@ -330,7 +362,9 @@ class ProfilePage extends GetView<ProfileLogic> {
padding: EdgeInsets.all(8),
decoration: ShapeDecoration(
color: cardColor ?? AppColor.blueLight,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: SvgGenImage.vec(icon).svg(
width: 40,
@@ -347,7 +381,9 @@ class ProfilePage extends GetView<ProfileLogic> {
Text(
title,
style: AppFonts.yekan10.copyWith(
color: textColor ?? (selected ? AppColor.blueNormal : AppColor.blueLightActive),
color:
textColor ??
(selected ? AppColor.blueNormal : AppColor.blueLightActive),
),
textAlign: TextAlign.center,
),
@@ -365,7 +401,9 @@ class ProfilePage extends GetView<ProfileLogic> {
children: [
Text(
'ویرایش اطلاعات هویتی',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
Container(
@@ -437,7 +475,9 @@ class ProfilePage extends GetView<ProfileLogic> {
children: [
Text(
'عکس پروفایل',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
),
ObxValue((data) {
return Container(
@@ -446,15 +486,26 @@ class ProfilePage extends GetView<ProfileLogic> {
decoration: BoxDecoration(
color: AppColor.lightGreyNormal,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1, color: AppColor.blackLight),
border: Border.all(
width: 1,
color: AppColor.blackLight,
),
),
child: Center(
child: data.value == null
? Padding(
padding: const EdgeInsets.fromLTRB(30, 10, 10, 30),
padding: const EdgeInsets.fromLTRB(
30,
10,
10,
30,
),
child: Image.network(''),
)
: Image.file(File(data.value!.path), fit: BoxFit.cover),
: Image.file(
File(data.value!.path),
fit: BoxFit.cover,
),
),
);
}, controller.selectedImage),
@@ -467,14 +518,18 @@ class ProfilePage extends GetView<ProfileLogic> {
text: 'گالری',
width: 150.w,
height: 40.h,
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
textStyle: AppFonts.yekan20.copyWith(
color: Colors.white,
),
onPressed: () async {
controller.selectedImage.value = await controller.imagePicker.pickImage(
source: ImageSource.gallery,
imageQuality: 60,
maxWidth: 1080,
maxHeight: 720,
);
controller.selectedImage.value = await controller
.imagePicker
.pickImage(
source: ImageSource.gallery,
imageQuality: 60,
maxWidth: 1080,
maxHeight: 720,
);
},
),
SizedBox(width: 16),
@@ -482,14 +537,18 @@ class ProfilePage extends GetView<ProfileLogic> {
text: 'دوربین',
width: 150.w,
height: 40.h,
textStyle: AppFonts.yekan20.copyWith(color: AppColor.blueNormal),
textStyle: AppFonts.yekan20.copyWith(
color: AppColor.blueNormal,
),
onPressed: () async {
controller.selectedImage.value = await controller.imagePicker.pickImage(
source: ImageSource.camera,
imageQuality: 60,
maxWidth: 1080,
maxHeight: 720,
);
controller.selectedImage.value = await controller
.imagePicker
.pickImage(
source: ImageSource.camera,
imageQuality: 60,
maxWidth: 1080,
maxHeight: 720,
);
},
),
],
@@ -568,7 +627,9 @@ class ProfilePage extends GetView<ProfileLogic> {
children: [
Text(
'تغییر رمز عبور',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover),
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
SizedBox(),
RTextField(
@@ -664,7 +725,10 @@ class ProfilePage extends GetView<ProfileLogic> {
child: Column(
spacing: 8,
children: [
Text('خروج', style: AppFonts.yekan16Bold.copyWith(color: AppColor.error)),
Text(
'خروج',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.error),
),
SizedBox(),
Text(
'آیا مطمئن هستید که می‌خواهید از حساب کاربری خود خارج شوید؟',
@@ -687,7 +751,10 @@ class ProfilePage extends GetView<ProfileLogic> {
.deleteModuleTokens(Module.liveStocks)
.then((value) {
Get.back();
Get.offAllNamed(LiveStockRoutes.auth, arguments: Module.chicken);
Get.offAllNamed(
AuthLiveStockRoutes.auth,
arguments: Module.liveStocks,
);
});
},
),

View File

@@ -1,19 +1,4 @@
import 'package:rasadyar_core/core.dart' hide BaseLogic;
import 'package:rasadyar_livestock/presentation/page/auth/logic.dart';
import 'package:rasadyar_livestock/presentation/page/auth/view.dart';
import 'package:rasadyar_livestock/presentation/page/map/logic.dart';
import 'package:rasadyar_livestock/presentation/page/map/widget/map_widget/logic.dart';
import 'package:rasadyar_livestock/presentation/page/profile/logic.dart';
import 'package:rasadyar_livestock/presentation/page/request_tagging/logic.dart';
import 'package:rasadyar_livestock/presentation/page/request_tagging/view.dart';
import 'package:rasadyar_livestock/presentation/page/requests/logic.dart';
import 'package:rasadyar_livestock/presentation/page/root/logic.dart';
import 'package:rasadyar_livestock/presentation/page/root/view.dart';
import 'package:rasadyar_livestock/presentation/page/tagging/logic.dart';
import 'package:rasadyar_livestock/presentation/page/tagging/view.dart';
import 'package:rasadyar_livestock/presentation/widgets/base_page/logic.dart';
import 'package:rasadyar_livestock/presentation/widgets/captcha/logic.dart';
import 'package:rasadyar_livestock/features/auth/presentation/routes/pages.dart';
part 'app_routes.dart';
@@ -21,7 +6,13 @@ sealed class LiveStockPages {
LiveStockPages._();
static final pages = [
GetPage(
//region Auth Pages
...AuthLiveStockPages.pages,
//endregion
/* GetPage(
name: LiveStockRoutes.auth,
page: () => AuthPage(),
binding: BindingsBuilder(() {
@@ -67,6 +58,6 @@ sealed class LiveStockPages {
binding: BindingsBuilder(() {
Get.lazyPut(() => TaggingLogic());
}),
),
), */
];
}

View File

@@ -3,7 +3,8 @@ part of 'app_pages.dart';
sealed class LiveStockRoutes {
LiveStockRoutes._();
static const auth = '/AuthLiveStock';
static const auth = AuthLiveStockRoutes.auth;
static const init = '/liveStock';
static const requests = '/requests';
static const map = '/map';

View File

@@ -1,10 +1,9 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_livestock/presentation/page/auth/logic.dart';
import 'package:rasadyar_livestock/features/auth/presentation/pages/logic.dart';
import 'logic.dart';
@@ -14,13 +13,13 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: controller.getCaptcha,
child: Container(
width: 135,
height: 50,
height: 50.h,
clipBehavior: Clip.antiAliasWithSaveLayer,
decoration: BoxDecoration(
color: AppColor.whiteNormalHover,
@@ -28,38 +27,50 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
borderRadius: BorderRadius.circular(8),
),
child: controller.obx(
(state) => Image.memory(base64Decode(state?.captchaImage ?? ''), fit: BoxFit.cover),
(state) => Image.memory(
base64Decode(state?.captchaImage ?? ''),
fit: BoxFit.cover,
),
onLoading: const Center(
child: CupertinoActivityIndicator(color: AppColor.blueNormal),
),
onError: (error) {
return Center(
child: Text('خطا ', style: AppFonts.yekan13.copyWith(color: Colors.red)),
child: Text(
'خطا ',
style: AppFonts.yekan13.copyWith(color: Colors.red),
),
);
},
),
),
),
const SizedBox(width: 8),
SizedBox(width: 2.w),
IconButton(
onPressed: controller.getCaptcha,
icon: Icon(Icons.refresh, color: AppColor.textColor),
),
SizedBox(width: 2.w),
Expanded(
child: Form(
key: controller.formKey,
autovalidateMode: AutovalidateMode.disabled,
child: RTextField(
height: 50.h,
isFullHeight: true,
label: 'کد امنیتی',
controller: controller.textController,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1),
borderColor: AppColor.textColor,
keyboardType: TextInputType.numberWithOptions(
decimal: false,
signed: false,
),
keyboardType: TextInputType.numberWithOptions(decimal: false, signed: false),
maxLines: 1,
maxLength: 6,
suffixIcon: (controller.textController.text.trim().isNotEmpty ?? false)
? clearButton(() => controller.textController.clear())
: null,
suffix: clearButton(() => controller.textController.clear()),
validator: (value) {
if (value == null || value.isEmpty) {
return 'کد امنیتی را وارد کنید';
@@ -67,10 +78,8 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
return null;
},
onChanged: (pass) {
if (pass.length == 6) {
if (controller.formKey.currentState?.validate() ?? false) {
Get.find<AuthLogic>().isDisabled.value = false;
}
if (controller.formKey.currentState?.validate() ?? false) {
Get.find<AuthLogic>().isDisabled.value = false;
}
},
style: AppFonts.yekan13,