feat : remember me for inspection module

This commit is contained in:
2025-08-31 11:09:07 +03:30
parent 9fab48aee1
commit 6a3bce3397
3 changed files with 107 additions and 71 deletions

View File

@@ -198,26 +198,31 @@ class AuthPage extends GetView<AuthLogic> {
SizedBox(height: 26), SizedBox(height: 26),
CaptchaWidget(), CaptchaWidget(),
Row( GestureDetector(
children: [ onTap: () {
ObxValue((data) { controller.rememberMe.value = !controller.rememberMe.value;
return Checkbox( },
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, child: Row(
visualDensity: VisualDensity(horizontal: -4, vertical: 4), children: [
tristate: true, ObxValue((data) {
value: data.value, return Checkbox(
onChanged: (value) { materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
data.value = value ?? false; visualDensity: VisualDensity(horizontal: -4, vertical: 4),
}, tristate: true,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), value: data.value,
activeColor: AppColor.blueNormal, onChanged: (value) {
); data.value = value ?? false;
}, controller.rememberMe), },
Text( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
'مرا به خاطر بسپار', activeColor: AppColor.blueNormal,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark), );
), }, controller.rememberMe),
], Text(
'مرا به خاطر بسپار',
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark),
),
],
),
), ),
Obx(() { Obx(() {

View File

@@ -22,7 +22,7 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin {
late AnimationController _textAnimationController; late AnimationController _textAnimationController;
late Animation<double> textAnimation; late Animation<double> textAnimation;
RxBool showCard = false.obs; RxBool showCard = false.obs;
RxBool rememberMe = false.obs;
Rx<GlobalKey<FormState>> formKeyOtp = GlobalKey<FormState>().obs; Rx<GlobalKey<FormState>> formKeyOtp = GlobalKey<FormState>().obs;
Rx<GlobalKey<FormState>> formKeySentOtp = GlobalKey<FormState>().obs; Rx<GlobalKey<FormState>> formKeySentOtp = GlobalKey<FormState>().obs;
Rx<TextEditingController> usernameController = TextEditingController().obs; Rx<TextEditingController> usernameController = TextEditingController().obs;
@@ -127,6 +127,16 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin {
await tokenStorageService.saveModule(_module); await tokenStorageService.saveModule(_module);
await tokenStorageService.saveRefreshToken(result?.refresh ?? ''); await tokenStorageService.saveRefreshToken(result?.refresh ?? '');
await tokenStorageService.saveAccessToken(result?.access ?? ''); await tokenStorageService.saveAccessToken(result?.access ?? '');
if (rememberMe.value) {
await tokenStorageService.saveUserPass(
UserLocalModel(
username: usernameController.value.text,
password: passwordController.value.text,
module: _module,
),
);
}
Get.offAllNamed(InspectionRoutes.init); Get.offAllNamed(InspectionRoutes.init);
}, },
onError: (error, stackTrace) { onError: (error, stackTrace) {

View File

@@ -2,6 +2,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_inspection/presentation/widget/captcha/view.dart'; import 'package:rasadyar_inspection/presentation/widget/captcha/view.dart';
import 'logic.dart'; import 'logic.dart';
class AuthPage extends GetView<AuthLogic> { class AuthPage extends GetView<AuthLogic> {
@@ -42,10 +43,7 @@ class AuthPage extends GetView<AuthLogic> {
), ),
Obx(() { Obx(() {
final screenHeight = MediaQuery final screenHeight = MediaQuery.of(context).size.height;
.of(context)
.size
.height;
final targetTop = (screenHeight - 676) / 2; final targetTop = (screenHeight - 676) / 2;
return AnimatedPositioned( return AnimatedPositioned(
@@ -129,13 +127,11 @@ class AuthPage extends GetView<AuthLogic> {
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8), padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
child: Assets.vec.callSvg.svg(width: 12, height: 12), child: Assets.vec.callSvg.svg(width: 12, height: 12),
), ),
suffixIcon: controller.usernameController.value.text suffixIcon: controller.usernameController.value.text.trim().isNotEmpty
.trim()
.isNotEmpty
? clearButton(() { ? clearButton(() {
controller.usernameController.value.clear(); controller.usernameController.value.clear();
controller.usernameController.refresh(); controller.usernameController.refresh();
}) })
: null, : null,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
@@ -157,47 +153,72 @@ class AuthPage extends GetView<AuthLogic> {
), ),
const SizedBox(height: 26), const SizedBox(height: 26),
ObxValue( ObxValue(
(passwordController) => (passwordController) => RTextField(
RTextField( label: 'رمز عبور',
label: 'رمز عبور', filled: false,
filled: false, obscure: true,
obscure: true, focusedBorder: OutlineInputBorder(
focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8),
borderRadius: BorderRadius.circular(8), borderSide: BorderSide(color: AppColor.textColor, width: 1),
borderSide: BorderSide(color: AppColor.textColor, width: 1), ),
), controller: passwordController.value,
controller: passwordController.value, autofillHints: [AutofillHints.password],
autofillHints: [AutofillHints.password], variant: RTextFieldVariant.password,
variant: RTextFieldVariant.password, initText: passwordController.value.text,
initText: passwordController.value.text, onChanged: (value) {
onChanged: (value) { passwordController.refresh();
passwordController.refresh(); },
}, validator: (value) {
validator: (value) { if (value == null || value.isEmpty) {
if (value == null || value.isEmpty) { return '⚠️ رمز عبور را وارد کنید';
return '⚠️ رمز عبور را وارد کنید'; }
} return null;
return null; },
}, style: AppFonts.yekan13,
style: AppFonts.yekan13, errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal),
errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal), labelStyle: AppFonts.yekan13,
labelStyle: AppFonts.yekan13, prefixIcon: Padding(
prefixIcon: Padding( padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8), child: Assets.vec.keySvg.svg(width: 12, height: 12),
child: Assets.vec.keySvg.svg(width: 12, height: 12), ),
), boxConstraints: const BoxConstraints(
boxConstraints: const BoxConstraints( maxHeight: 34,
maxHeight: 34, minHeight: 34,
minHeight: 34, maxWidth: 34,
maxWidth: 34, minWidth: 34,
minWidth: 34, ),
), ),
),
controller.passwordController, controller.passwordController,
), ),
SizedBox(height: 26), SizedBox(height: 26),
CaptchaWidget(), CaptchaWidget(),
SizedBox(height: 23),
GestureDetector(
onTap: () {
controller.rememberMe.value = !controller.rememberMe.value;
},
child: Row(
children: [
ObxValue((data) {
return Checkbox(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity(horizontal: -4, vertical: 4),
tristate: true,
value: data.value,
onChanged: (value) {
data.value = value ?? false;
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
activeColor: AppColor.blueNormal,
);
}, controller.rememberMe),
Text(
'مرا به خاطر بسپار',
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark),
),
],
),
),
Obx(() { Obx(() {
return RElevated( return RElevated(
@@ -206,8 +227,8 @@ class AuthPage extends GetView<AuthLogic> {
onPressed: controller.isDisabled.value onPressed: controller.isDisabled.value
? null ? null
: () async { : () async {
await controller.submitLoginForm(); await controller.submitLoginForm();
}, },
width: Get.width, width: Get.width,
height: 48, height: 48,
); );
@@ -308,7 +329,7 @@ class AuthPage extends GetView<AuthLogic> {
); );
} }
/* /*
Widget sendCodeForm() { Widget sendCodeForm() {
return ObxValue((data) { return ObxValue((data) {
return Form( return Form(