import "package:flutter/material.dart"; import "package:flutter_secure_storage/flutter_secure_storage.dart"; import "package:openbills/models/login.dart"; import "package:openbills/widgets/input_box.dart"; import "package:openbills/widgets/snackbar.dart"; import "package:openbills/screens/signup.dart"; class LoginScreen extends StatelessWidget { const LoginScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Image( height: 50, image: AssetImage("assets/images/logo.png"), ), ), body: const Center( child: SizedBox( width: 500, child: Body(), ) ), ); } } class Body extends StatefulWidget { const Body({super.key}); @override State createState() => _BodyState(); } class _BodyState extends State { final accountNameController = TextEditingController(); final passwordController = TextEditingController(); LoginMethod? _method = LoginMethod.username; final _storage = const FlutterSecureStorage(); @override void dispose() { accountNameController.dispose(); passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { Size size = MediaQuery.sizeOf(context); MainAxisAlignment alignment = MainAxisAlignment.center; if (size.width < 700) { alignment = MainAxisAlignment.spaceBetween; } if (size.height < 700) { alignment = MainAxisAlignment.center; } return Column ( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: alignment, children: [ const Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: Text( "OpenBills Log In", textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 30, ), ), ), Column( children: [ FormInputBox( controller: accountNameController, hintText: _method == LoginMethod.email ? "E-Mail" : "Username", ), Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: Column( children: [ const Text( "Log in with:", textAlign: TextAlign.left, style: TextStyle( fontSize: 18, ), ), Row( children: [ Flexible( child: RadioListTile( title: const Text("username"), value: LoginMethod.username, groupValue: _method, onChanged: (LoginMethod? value) { setState(() { _method = value; }); }, ), ), Flexible( child: RadioListTile( title: const Text("email"), value: LoginMethod.email, groupValue: _method, onChanged: (LoginMethod? value) { setState(() { _method = value; }); }, ), ), ], ), ], ) ), FormInputBox( controller: passwordController, hintText: "Password", obscureText: true, ), ], ), Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const SignupScreen()) ); }, child: const Text("Don't have an account? Sign up.") ), ElevatedButton( onPressed: () async { String name = accountNameController.text; String? method = _method?.value; String password = passwordController.text; try { LoginRes res = await userSignIn(name, method, password); String? username = res.user.username; await _storage.write( key: "auth_token", value: res.authToken, aOptions: const AndroidOptions( encryptedSharedPreferences: true, ), ); await _storage.write( key: "refresh_token", value: res.refreshToken, aOptions: const AndroidOptions( encryptedSharedPreferences: true, ), ); if (context.mounted) { MySnackBar.show(context, "Hello, $username! Please restart the app to see the homepage."); } } on String catch(e) { if (context.mounted) { MySnackBar.show(context, "Error: $e"); } } }, child: const Text("Log In") ), ], ), ), ], ); } }