import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'package:tm_app/core/theme/colors.dart'; import '../../../core/constants/assets.dart'; import '../../../core/routes/app_routes.dart'; import '../../../core/utils/app_toast.dart'; import '../../../core/utils/size_config.dart'; import '../../../view_models/auth_view_model.dart'; import '../strings/login_strings.dart'; import '../widgets/widgets.dart'; class LoginDesktopPage extends StatefulWidget { const LoginDesktopPage({super.key}); @override State createState() => _LoginDesktopPageState(); } class _LoginDesktopPageState extends State { late final AuthViewModel viewModel; @override void initState() { super.initState(); viewModel = context.read(); viewModel.addListener(_viewModelListener); } void _viewModelListener() { if (viewModel.loggedInUser != null) { Router.neglect(context, () => const HomeRouteData().go(context)); } else if (viewModel.errorMessage != null) { AppToast.error(context, viewModel.errorMessage!); } } @override void dispose() { viewModel.removeListener(_viewModelListener); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.backgroundColor, body: Center( child: Row( mainAxisAlignment: kIsWeb ? MainAxisAlignment.spaceAround : MainAxisAlignment.center, children: [ Expanded( child: Center( child: SizedBox( width: 364, child: Column( mainAxisSize: MainAxisSize.min, children: [ SvgPicture.asset( AssetsManager.logoBig, width: 320, height: 50, fit: BoxFit.cover, ), SizedBox(height: 72.0.h()), const LoginTitle(), SizedBox(height: 32.0.h()), LoginTextField( controller: viewModel.usernameController, focusNode: viewModel.usernameFocus, label: LoginStrings.usernameLabel, iconPath: AssetsManager.userIcon, fieldHeight: 60.0.h(), borderRedus: 12, prefixIconPadding: 7.0.w(), ), SizedBox(height: 16.0.h()), Selector( selector: (_, vm) => vm.obscurePassword, builder: (_, obscurePassword, __) { return LoginTextField( controller: viewModel.passwordController, focusNode: viewModel.passwordFocus, label: LoginStrings.passwordLabel, iconPath: AssetsManager.passwordIcon, isPassword: true, obscureText: obscurePassword, onToggleVisibility: viewModel.togglePasswordVisibility, ); }, ), SizedBox(height: 32.0.h()), /// ✅ Only this part rebuilds now Selector( selector: (_, vm) => vm.isLoading, builder: (_, isLoading, __) { return Selector( selector: (_, vm) => vm.isLoginEnabled, builder: (_, isEnabled, __) { if (isLoading) { return BaseButton( isEnabled: false, onPressed: null, isLoading: true, textColor: AppColors.white, ); } return BaseButton( isEnabled: isEnabled, onPressed: isEnabled ? () async { await viewModel.login(); } : null, ); }, ); }, ), const SizedBox(height: 32.0), TextButton( onPressed: () { const ForgotPasswordRouteData().push(context); }, child: Text( LoginStrings.forgotPassword, style: TextStyle( fontSize: 14.0.sp(), fontWeight: FontWeight.w500, color: AppColors.mainBlue, ), ), ), ], ), ), ), ), Padding( padding: EdgeInsets.symmetric( vertical: 20.0.h(), horizontal: 25.0.w(), ), child: ClipRRect( borderRadius: BorderRadius.circular(32), child: Image.asset( AssetsManager.webLoginImage, width: 796.0, height: 944.0, fit: BoxFit.fitWidth, ), ), ), ], ), ), ); } }