Frontend first draft
This commit is contained in:
106
frontend/pweb/lib/pages/login/form.dart
Normal file
106
frontend/pweb/lib/pages/login/form.dart
Normal file
@@ -0,0 +1,106 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:pshared/provider/pfe/provider.dart';
|
||||
|
||||
import 'package:pweb/app/router/pages.dart';
|
||||
import 'package:pweb/pages/login/buttons.dart';
|
||||
import 'package:pweb/pages/login/header.dart';
|
||||
import 'package:pweb/widgets/constrained_form.dart';
|
||||
import 'package:pweb/widgets/password/hint/short.dart';
|
||||
import 'package:pweb/widgets/password/password.dart';
|
||||
import 'package:pweb/widgets/username.dart';
|
||||
import 'package:pweb/widgets/vspacer.dart';
|
||||
import 'package:pweb/widgets/error/snackbar.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
|
||||
class LoginForm extends StatefulWidget {
|
||||
const LoginForm({super.key});
|
||||
|
||||
@override
|
||||
State<LoginForm> createState() => _LoginFormState();
|
||||
}
|
||||
|
||||
class _LoginFormState extends State<LoginForm> {
|
||||
final TextEditingController _usernameController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
// ValueNotifiers for validation state
|
||||
final ValueNotifier<bool> _isUsernameAcceptable = ValueNotifier<bool>(false);
|
||||
final ValueNotifier<bool> _isPasswordAcceptable = ValueNotifier<bool>(false);
|
||||
|
||||
Future<String?> _login(BuildContext context, VoidCallback onLogin, void Function(Object e) onError) async {
|
||||
final pfeProvider = Provider.of<PfeProvider>(context, listen: false);
|
||||
|
||||
try {
|
||||
// final account = await pfeProvider.login(
|
||||
// email: _usernameController.text,
|
||||
// password: _passwordController.text,
|
||||
// );
|
||||
onLogin();
|
||||
return 'ok';
|
||||
} catch (e) {
|
||||
onError(pfeProvider.error == null ? e : pfeProvider.error!);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_usernameController.dispose();
|
||||
_passwordController.dispose();
|
||||
_isUsernameAcceptable.dispose();
|
||||
_isPasswordAcceptable.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Align(
|
||||
alignment: Alignment.center,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 400, maxHeight: 300),
|
||||
child: Card(
|
||||
child: ConstrainedForm(
|
||||
formKey: _formKey,
|
||||
children: [
|
||||
const LoginHeader(),
|
||||
const VSpacer(multiplier: 1.5),
|
||||
UsernameField(
|
||||
controller: _usernameController,
|
||||
onValid: (isValid) => _isUsernameAcceptable.value = isValid,
|
||||
),
|
||||
VSpacer(),
|
||||
defaulRulesPasswordField(
|
||||
context,
|
||||
controller: _passwordController,
|
||||
validationRuleBuilder: (rules, value) => shortValidation(context, rules, value),
|
||||
onValid: (isValid) => _isPasswordAcceptable.value = isValid,
|
||||
),
|
||||
VSpacer(multiplier: 2.0),
|
||||
ValueListenableBuilder<bool>(
|
||||
valueListenable: _isUsernameAcceptable,
|
||||
builder: (context, isUsernameValid, child) => ValueListenableBuilder<bool>(
|
||||
valueListenable: _isPasswordAcceptable,
|
||||
builder: (context, isPasswordValid, child) => ButtonsRow(
|
||||
onSignUp: () => navigate(context, Pages.signup),
|
||||
login: () => _login(
|
||||
context,
|
||||
() => navigateAndReplace(context, Pages.sfactor),
|
||||
(e) => postNotifyUserOfErrorX(
|
||||
context: context,
|
||||
errorSituation: AppLocalizations.of(context)!.errorLogin,
|
||||
exception: e,
|
||||
),
|
||||
),
|
||||
isEnabled: isUsernameValid && isPasswordValid,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)));
|
||||
}
|
||||
Reference in New Issue
Block a user