import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:get/get.dart'; import 'package:marco/controller/auth/login_controller.dart'; import 'package:marco/helpers/theme/app_theme.dart'; import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; import 'package:marco/helpers/widgets/my_button.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_text_style.dart'; import 'package:marco/helpers/services/api_endpoints.dart'; class EmailLoginForm extends StatefulWidget { EmailLoginForm({super.key}); @override State createState() => _EmailLoginFormState(); } class _EmailLoginFormState extends State with UIMixin { late final LoginController controller; bool get isBetaEnvironment => ApiEndpoints.baseUrl.contains("stage"); @override void initState() { controller = Get.put(LoginController(), tag: 'login_controller'); super.initState(); } @override Widget build(BuildContext context) { return GetBuilder( tag: 'login_controller', builder: (_) { return Obx(() { if (controller.isLoading.value) { return const Center(child: CircularProgressIndicator()); } return Form( key: controller.basicValidator.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // MyText.titleMedium('Login With Username & Password', // fontWeight: 600), MySpacing.height(8), MyText.bodyMedium("User Name", fontWeight: 600), MySpacing.height(8), _buildInputField( controller.basicValidator.getController('username')!, controller.basicValidator.getValidation('username'), hintText: "Enter your email", icon: LucideIcons.mail, keyboardType: TextInputType.emailAddress, ), MySpacing.height(16), MyText.bodyMedium("Password", fontWeight: 600), MySpacing.height(8), Obx(() { return _buildInputField( controller.basicValidator.getController('password')!, controller.basicValidator.getValidation('password'), hintText: "Enter your password", icon: LucideIcons.lock, obscureText: !controller.showPassword.value, suffix: IconButton( icon: Icon( controller.showPassword.value ? LucideIcons.eye : LucideIcons.eye_off, size: 18, ), onPressed: controller.onChangeShowPassword, ), ); }), MySpacing.height(16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Obx(() { return InkWell( onTap: () => controller .onChangeCheckBox(!controller.isChecked.value), child: Row( children: [ Checkbox( value: controller.isChecked.value, onChanged: controller.onChangeCheckBox, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), fillColor: MaterialStateProperty.resolveWith( (states) => states.contains(WidgetState.selected) ? contentTheme.brandRed : Colors.white, ), checkColor: contentTheme.onPrimary, visualDensity: getCompactDensity, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ), MySpacing.width(8), MyText.bodySmall("Remember Me"), ], ), ); }), MyButton.text( onPressed: controller.goToForgotPassword, elevation: 0, padding: MySpacing.xy(8, 0), splashColor: contentTheme.secondary.withAlpha(36), child: MyText.bodySmall( 'Forgot password?', fontWeight: 600, color: contentTheme.secondary, ), ), ], ), MySpacing.height(28), Center( child: Obx(() { final isLoading = controller.isLoading.value; return MyButton.rounded( onPressed: isLoading ? null : controller.onLogin, elevation: 2, padding: MySpacing.xy(80, 16), borderRadiusAll: 10, backgroundColor: contentTheme.brandRed, child: MyText.labelLarge( isLoading ? 'Logging in...' : 'Login', fontWeight: 700, color: contentTheme.onPrimary, ), ); }), ), ], ), ); }); }, ); } Widget _buildInputField( TextEditingController controller, FormFieldValidator? validator, { required String hintText, required IconData icon, TextInputType keyboardType = TextInputType.text, bool obscureText = false, Widget? suffix, }) { return Material( elevation: 2, shadowColor: contentTheme.secondary.withAlpha(30), borderRadius: BorderRadius.circular(12), child: TextFormField( controller: controller, validator: validator, obscureText: obscureText, keyboardType: keyboardType, style: MyTextStyle.labelMedium(), decoration: InputDecoration( hintText: hintText, hintStyle: MyTextStyle.bodySmall(xMuted: true), filled: true, fillColor: theme.cardColor, border: OutlineInputBorder( borderRadius: BorderRadius.circular(2), borderSide: BorderSide.none, ), prefixIcon: Icon(icon, size: 18), suffixIcon: suffix, contentPadding: MySpacing.xy(12, 16), ), ), ); } }