import 'package:flutter/material.dart'; class LoginPage extends StatelessWidget { const LoginPage({super.key}); @override Widget build(BuildContext context) { return Material( child: Center( child: Container( constraints: const BoxConstraints(maxWidth: 300.0), padding: const EdgeInsets.all(10), child: const LoginForm(), ), )); } } class LoginForm extends StatefulWidget { const LoginForm({super.key}); @override State<LoginForm> createState() => _LoginFormState(); } class _LoginFormState extends State<LoginForm> { final formKey = GlobalKey<FormState>(); final usernameTextController = TextEditingController(); final passwordTextController = TextEditingController(); var loginFailed = false; @override Widget build(BuildContext context) { return Form( key: formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Username'), TextFormField( controller: usernameTextController, decoration: const InputDecoration( hintText: 'Enter username', border: OutlineInputBorder()), validator: (value) { if (value == null || value.trim().length < 3) { return 'Please enter a valid username.'; } return null; }, ), const SizedBox(height: 10), const Text('Password'), TextFormField( controller: passwordTextController, obscureText: true, decoration: const InputDecoration( hintText: 'Enter password', border: OutlineInputBorder()), validator: (value) { if (value == null || value.length < 8) { return 'Please enter a valid password.'; } return null; }, ), const SizedBox(height: 10), TextButton( onPressed: () { if (formKey.currentState!.validate()) { print(usernameTextController.text); print(passwordTextController.text); } else { setState(() => loginFailed = true); Future.delayed(const Duration(seconds: 3), () => setState(() => loginFailed = false)); } }, child: const Text('Login')), if (loginFailed) TextButton( onPressed: () {}, child: const Text('Forgot password?')), TextButton(onPressed: () {}, child: const Text('Create an Account')) ], )); } @override void dispose() { usernameTextController.dispose(); passwordTextController.dispose(); super.dispose(); } }