Files
softplayer-web/lib/features/authorization/presentation/login_form.dart
Nikolai Rodionov e6a28d033a
All checks were successful
ci/woodpecker/push/build Pipeline was successful
A minor fix and break sign in
Signed-off-by: Nikolai Rodionov <allanger@posteo.com>
2026-05-29 16:49:01 +02:00

150 lines
5.5 KiB
Dart

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:softplayer_web/features/authorization/application/authorization_application.dart';
import 'package:softplayer_web/features/authorization/application/sign_in_data.dart';
import 'package:toastification/toastification.dart';
class LoginForm extends ConsumerStatefulWidget {
const LoginForm({super.key, required this.toggleAuth});
final VoidCallback toggleAuth;
@override
ConsumerState<LoginForm> createState() => _LoginForm();
}
class _LoginForm extends ConsumerState<LoginForm> {
final _formKey = GlobalKey<FormState>();
final TextEditingController emailCtrl = TextEditingController();
final TextEditingController passwordCtrl = TextEditingController();
Future<void> _submitForm() async {
if (_formKey.currentState!.validate()) {
// If valid, you can use the values
final email = emailCtrl.text;
final password = passwordCtrl.text;
final form = SignInData(email: email, password: password);
try {
await ref.read(authorizationControllerProvider.notifier).signin(form);
} catch (e) {
if (!mounted) {
return;
}
log(e.toString());
toastification.show(
context: context,
type: ToastificationType.error,
style: ToastificationStyle.flatColored,
alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4),
title: const Text('Authentication failed'),
description: Text(e.toString()),
showProgressBar: false,
);
}
}
}
@override
Widget build(BuildContext context) {
final state = ref.watch(authorizationControllerProvider);
return LayoutBuilder(
builder: ((context, constraints) {
return Stack(
children: [
SizedBox(
width: 400,
child: Form(
key: _formKey,
child: AutofillGroup(
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
child: SelectableText(
"Welcome back!",
style: Theme.of(context).textTheme.headlineLarge,
),
),
SizedBox(height: 12),
Container(
alignment: Alignment.topLeft,
child: Row(
children: [
Text(
"Don't have an account yet? ",
style: Theme.of(context).textTheme.bodyMedium,
),
TextButton(
onPressed: widget.toggleAuth,
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(0, 0),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: const Text(
"Sign up now",
style: TextStyle(
decoration: TextDecoration.underline,
),
),
),
],
),
),
SizedBox(height: 36),
TextFormField(
autofillHints: const [
AutofillHints.username,
AutofillHints.email,
],
onFieldSubmitted: (_) => _submitForm(),
controller: emailCtrl,
decoration: InputDecoration(hintText: "Email address"),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
onFieldSubmitted: (_) => _submitForm(),
autofillHints: const [AutofillHints.password],
controller: passwordCtrl,
obscureText: true,
decoration: InputDecoration(hintText: "Password"),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
return null;
},
),
SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: Text(
"Forgot password?",
textAlign: TextAlign.left,
),
),
ElevatedButton(
onPressed: _submitForm,
child: const Text('Log in'),
),
],
),
),
),
),
],
);
}),
);
}
}