new auth page
This commit is contained in:
2025-08-02 12:19:25 +03:30
parent 6040ca9f86
commit fae6703d8d
7 changed files with 120 additions and 79 deletions

View File

@@ -49,6 +49,7 @@ class RTextField extends StatefulWidget {
final TextInputAction? textInputAction;
final double? height;
final Iterable<String>? autofillHints;
final InputBorder? focusedBorder;
const RTextField({
super.key,
@@ -84,6 +85,7 @@ class RTextField extends StatefulWidget {
this.hintStyle,
this.labelStyle,
this.errorStyle,
this.focusedBorder,
// 🎨 Decorations
this.suffixIcon,
@@ -243,7 +245,7 @@ class _RTextFieldState extends State<RTextField> {
counter: widget.showCounter ? null : const SizedBox(),
hintStyle: widget.hintStyle,
enabledBorder: widget._inputBorder,
focusedBorder: widget._inputBorder,
focusedBorder: widget.focusedBorder ?? widget._inputBorder,
border: widget._inputBorder,
),
),

View File

@@ -16,9 +16,13 @@ enum AuthStatus { init }
enum OtpStatus { init, sent, verified, reSend }
class AuthLogic extends GetxController {
class AuthLogic extends GetxController with GetTickerProviderStateMixin {
GlobalKey<FormState> formKey = GlobalKey<FormState>();
late AnimationController _textAnimationController;
late Animation<double> textAnimation;
RxBool showCard = false.obs;
Rx<GlobalKey<FormState>> formKeyOtp = GlobalKey<FormState>().obs;
Rx<GlobalKey<FormState>> formKeySentOtp = GlobalKey<FormState>().obs;
Rx<TextEditingController> usernameController = TextEditingController().obs;
@@ -44,6 +48,31 @@ class AuthLogic extends GetxController {
final Module _module = Get.arguments;
@override
void onInit() {
super.onInit();
_textAnimationController =
AnimationController(vsync: this, duration: const Duration(milliseconds: 1200))
..repeat(reverse: true, count: 2).whenComplete(() {
showCard.value = true;
});
textAnimation = CurvedAnimation(parent: _textAnimationController, curve: Curves.easeInOut);
}
@override
void onReady() {
super.onReady();
//_textAnimationController.forward();
}
@override
void onClose() {
_timer?.cancel();
super.onClose();
}
void startTimer() {
_timer?.cancel();
secondsRemaining.value = 120;
@@ -67,18 +96,6 @@ class AuthLogic extends GetxController {
return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
}
@override
void onReady() {
super.onReady();
iLog('module selected : ${_module.toString()}');
}
@override
void onClose() {
_timer?.cancel();
super.onClose();
}
bool _isFormValid() {
final isCaptchaValid = captchaController.formKey.currentState?.validate() ?? false;
final isFormValid = formKey.currentState?.validate() ?? false;

View File

@@ -13,86 +13,97 @@ class AuthPage extends GetView<AuthLogic> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 80),
LogoWidget(),
ObxValue((types) {
switch (types.value) {
case AuthType.otp:
//return otpForm();
case AuthType.useAndPass:
return useAndPassFrom();
}
}, controller.authType),
body: Stack(
alignment: Alignment.center,
SizedBox(height: 20),
RichText(
text: TextSpan(
children: [
Assets.vec.bgAuthSvg.svg(fit: BoxFit.fill),
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: [
TextSpan(
text: 'مطالعه بیانیه ',
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDark),
Text(
'به سامانه رصدیار خوش آمدید!',
textAlign: TextAlign.right,
style: AppFonts.yekan25Bold.copyWith(color: Colors.white),
),
TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
Get.bottomSheet(
privacyPolicyWidget(),
isScrollControlled: true,
enableDrag: true,
ignoreSafeArea: false,
);
},
text: 'حریم خصوصی',
style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal),
Text(
'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی',
textAlign: TextAlign.center,
style: AppFonts.yekan16.copyWith(color: Colors.white),
),
],
),
),
/* SizedBox(height: 18),
),
ObxValue((types) {
return RichText(
text: TextSpan(
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: [
TextSpan(
recognizer:
TapGestureRecognizer()
..onTap = () {
if (controller.authType.value == AuthType.otp) {
controller.authType.value = AuthType.useAndPass;
if (controller.otpStatus.value !=
OtpStatus.init) {
controller.otpStatus.value = OtpStatus.init;
}
} else {
controller.authType.value = AuthType.otp;
}
},
text:
controller.authType.value == AuthType.otp
? 'ورود با رمز ثابت'
: 'ورود با رمز یکبار مصرف',
style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal,
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),
),
],
),
),
],
),
);
}, controller.authType),*/
],
),
),
);
}),
],
),
);
}
Widget useAndPassFrom() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
padding: EdgeInsets.symmetric(horizontal: 30.r),
child: Form(
key: controller.formKey,
child: AutofillGroup(
@@ -106,6 +117,10 @@ class AuthPage extends GetView<AuthLogic> {
keyboardType: TextInputType.number,
initText: controller.usernameController.value.text,
autofillHints: [AutofillHints.username],
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1),
),
onChanged: (value) async {
controller.usernameController.value.text = value;
controller.usernameController.refresh();
@@ -144,6 +159,10 @@ class AuthPage extends GetView<AuthLogic> {
label: 'رمز عبور',
filled: false,
obscure: true,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1),
),
controller: passwordController.value,
autofillHints: [AutofillHints.password],
variant: RTextFieldVariant.password,

View File

@@ -177,7 +177,6 @@ class InspectionMapPage extends GetView<InspectionMapLogic> {
}
/*
Widget selectedLocationWidget2({
required bool showHint,
required SlidableController sliderController,

View File

@@ -97,7 +97,7 @@ class MapLogic extends GetxController with GetTickerProviderStateMixin {
isLoading.value = false;
}
/*
/*
void debouncedUpdateVisibleMarkers({required LatLng center, required double zoom}) {
_debounceTimer?.cancel();
_debounceTimer = Timer(const Duration(milliseconds: 300), () {

View File

@@ -50,6 +50,10 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
child: RTextField(
label: 'کد امنیتی',
controller: controller.textController,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1),
),
keyboardType: TextInputType.numberWithOptions(decimal: false, signed: false),
maxLines: 1,
maxLength: 6,

View File

@@ -10,8 +10,8 @@ class LogoWidget extends StatelessWidget {
children: [
Row(),
Assets.images.innerSplash.image(
width: 150,
height: 150,
width: 120.w,
height: 120.h,
),
Text(
'سامانه رصدیار',