Adapt base login page
This commit is contained in:
		
							
								
								
									
										36
									
								
								moneymgr_mobile/lib/routes/login/base_auth_page.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								moneymgr_mobile/lib/routes/login/base_auth_page.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					import 'package:flextras/flextras.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_gutter/flutter_gutter.dart';
 | 
				
			||||||
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../../services/router/routes_list.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseAuthPage extends StatelessWidget {
 | 
				
			||||||
 | 
					  final List<Widget> children;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const BaseAuthPage({super.key, required this.children});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    void onSettingsPressed() => context.push(settingsPage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Scaffold(
 | 
				
			||||||
 | 
					      appBar: AppBar(
 | 
				
			||||||
 | 
					        title: const Text('MoneyMgr'),
 | 
				
			||||||
 | 
					        actions: [
 | 
				
			||||||
 | 
					          IconButton(
 | 
				
			||||||
 | 
					            onPressed: onSettingsPressed,
 | 
				
			||||||
 | 
					            icon: const Icon(Icons.settings),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      body: SeparatedColumn(
 | 
				
			||||||
 | 
					        padding: EdgeInsets.all(context.gutter),
 | 
				
			||||||
 | 
					        separatorBuilder: () => const Gutter(),
 | 
				
			||||||
 | 
					        mainAxisAlignment: MainAxisAlignment.center,
 | 
				
			||||||
 | 
					        crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
				
			||||||
 | 
					        children: children,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,86 +1,61 @@
 | 
				
			|||||||
import 'package:flextras/flextras.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter_gutter/flutter_gutter.dart';
 | 
					import 'package:flutter_gutter/flutter_gutter.dart';
 | 
				
			||||||
import 'package:flutter_hooks/flutter_hooks.dart';
 | 
					 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:moneymgr_mobile/routes/login/login_model.dart';
 | 
					import 'package:moneymgr_mobile/routes/login/base_auth_page.dart';
 | 
				
			||||||
import 'package:moneymgr_mobile/services/router/routes_list.dart';
 | 
					import 'package:moneymgr_mobile/services/router/routes_list.dart';
 | 
				
			||||||
import 'package:moneymgr_mobile/widgets/app_button.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import '../../../services/auth_state.dart';
 | 
					 | 
				
			||||||
import '../../../utils/extensions.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LoginScreen extends HookConsumerWidget {
 | 
					class LoginScreen extends HookConsumerWidget {
 | 
				
			||||||
  const LoginScreen({super.key});
 | 
					  const LoginScreen({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
    final isPasswordVisible = useState(false);
 | 
					    return BaseAuthPage(
 | 
				
			||||||
 | 
					 | 
				
			||||||
    final usernameController = useTextEditingController();
 | 
					 | 
				
			||||||
    final passwordController = useTextEditingController();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void onSettingsPressed() => context.push(settingsPage);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Future<void> onLoginPressed() async {
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        await ref.read(currentAuthStateProvider.notifier).login(LoginModel(
 | 
					 | 
				
			||||||
          username: usernameController.text,
 | 
					 | 
				
			||||||
          password: passwordController.text,
 | 
					 | 
				
			||||||
        ));
 | 
					 | 
				
			||||||
      } on Exception catch (e) {
 | 
					 | 
				
			||||||
        if (!context.mounted) return;
 | 
					 | 
				
			||||||
        context.showTextSnackBar(e.toString());
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return Scaffold(
 | 
					 | 
				
			||||||
      appBar: AppBar(
 | 
					 | 
				
			||||||
        title: const Text('MoneyMgr'),
 | 
					 | 
				
			||||||
        actions: [
 | 
					 | 
				
			||||||
          IconButton(
 | 
					 | 
				
			||||||
            onPressed: onSettingsPressed,
 | 
					 | 
				
			||||||
            icon: const Icon(Icons.settings),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
      body: SeparatedColumn(
 | 
					 | 
				
			||||||
        padding: EdgeInsets.all(context.gutter),
 | 
					 | 
				
			||||||
        separatorBuilder: () => const Gutter(),
 | 
					 | 
				
			||||||
        mainAxisAlignment: MainAxisAlignment.center,
 | 
					 | 
				
			||||||
        crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
					 | 
				
			||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
          TextField(
 | 
					        Gutter(scaleFactor: 3),
 | 
				
			||||||
            controller: usernameController,
 | 
					        Text(
 | 
				
			||||||
            decoration: const InputDecoration(labelText: 'Username'),
 | 
					          "This application requires a token from MoneyMgr to be used.\n\nPlease create a token  on your Money Manager instance and make sure to click on \"For mobile app\" button. You can then enter here generated credentials.",
 | 
				
			||||||
            textInputAction: TextInputAction.next,
 | 
					          textAlign: TextAlign.justify,
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
          TextField(
 | 
					        Expanded(child: Container()),
 | 
				
			||||||
            controller: passwordController,
 | 
					        _LoginChoice(
 | 
				
			||||||
            decoration: InputDecoration(
 | 
					          route: manualAuthPage,
 | 
				
			||||||
              labelText: 'Password',
 | 
					          icon: Icons.edit_document,
 | 
				
			||||||
              suffixIcon: IconButton(
 | 
					          label: "Enter manually authentication information",
 | 
				
			||||||
                icon: Icon(
 | 
					 | 
				
			||||||
                  isPasswordVisible.value
 | 
					 | 
				
			||||||
                      ? Icons.visibility_off
 | 
					 | 
				
			||||||
                      : Icons.visibility,
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
                onPressed: () =>
 | 
					        _LoginChoice(
 | 
				
			||||||
                isPasswordVisible.value = !isPasswordVisible.value,
 | 
					          route: manualAuthPage,
 | 
				
			||||||
              ),
 | 
					          icon: Icons.qr_code_2,
 | 
				
			||||||
            ),
 | 
					          label: "Scan authentication Qr Code",
 | 
				
			||||||
            obscureText: !isPasswordVisible.value,
 | 
					 | 
				
			||||||
            keyboardType: TextInputType.visiblePassword,
 | 
					 | 
				
			||||||
            textInputAction: TextInputAction.done,
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
          const SizedBox.shrink(),
 | 
					 | 
				
			||||||
          AppButton(
 | 
					 | 
				
			||||||
            onPressed: onLoginPressed,
 | 
					 | 
				
			||||||
            label: 'Login',
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					        Gutter(scaleFactor: 3),
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
      ),
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _LoginChoice extends StatelessWidget {
 | 
				
			||||||
 | 
					  const _LoginChoice({
 | 
				
			||||||
 | 
					    super.key,
 | 
				
			||||||
 | 
					    required this.route,
 | 
				
			||||||
 | 
					    required this.label,
 | 
				
			||||||
 | 
					    required this.icon,
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final String route;
 | 
				
			||||||
 | 
					  final String label;
 | 
				
			||||||
 | 
					  final IconData icon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return FilledButton(
 | 
				
			||||||
 | 
					      onPressed: () => context.push(route),
 | 
				
			||||||
 | 
					      style: ButtonStyle(
 | 
				
			||||||
 | 
					        padding: WidgetStatePropertyAll(
 | 
				
			||||||
 | 
					          EdgeInsetsGeometry.symmetric(vertical: 20.0, horizontal: 30.0),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      child: Row(children: [Icon(icon, size: 25.0), Gutter(), Text(label)]),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,11 @@
 | 
				
			|||||||
 | 
					/// Base home page
 | 
				
			||||||
const homePage = "/";
 | 
					const homePage = "/";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Authentication path
 | 
					/// Authentication path
 | 
				
			||||||
const authPage = "/login";
 | 
					const authPage = "/login";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Manual authentication
 | 
				
			||||||
 | 
					const manualAuthPage = "/login/manual";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Settings path
 | 
					/// Settings path
 | 
				
			||||||
const settingsPage = "/settings";
 | 
					const settingsPage = "/settings";
 | 
				
			||||||
		Reference in New Issue
	
	Block a user