Files
hub/frontend/lib/login_screen.dart
T

150 lines
5.7 KiB
Dart

import 'package:flutter/material.dart';
import 'backend.dart';
class LoginScreen extends StatelessWidget {
final Function(String, String) onLogin;
final bool isSignupMode; // Changed to a boolean
LoginScreen({required this.onLogin, this.isSignupMode = false}); // Default to false (login mode)
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController confirmPasswordController = TextEditingController();
final FocusNode usernameFocusNode = FocusNode();
final FocusNode passwordFocusNode = FocusNode();
final FocusNode emailFocusNode = FocusNode();
final FocusNode confirmPasswordFocusNode = FocusNode();
void _handleLogin() {
onLogin(usernameController.text, passwordController.text);
}
void _handleSignup(BuildContext context) async {
final username = usernameController.text;
final password = passwordController.text;
final email = emailController.text;
if (password != confirmPasswordController.text) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Passwords don't match")),
);
return;
}
try {
await Backend.signup(username, email, password);
_handleLogin();
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Could not signup: $e')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(isSignupMode ? 'Signup' : 'Login')), // Dynamic title
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: usernameController,
focusNode: usernameFocusNode,
decoration: InputDecoration(labelText: 'Username'),
textInputAction: TextInputAction.next,
onSubmitted: (_) {
if (!isSignupMode) { // If not in signup mode, move to password
FocusScope.of(context).requestFocus(passwordFocusNode);
} else { // In signup mode, move to email
FocusScope.of(context).requestFocus(emailFocusNode);
}
},
),
SizedBox(height: 20),
if (isSignupMode) ...[ // Conditionally show email field
TextField(
controller: emailController,
focusNode: emailFocusNode,
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
onSubmitted: (_) {
FocusScope.of(context).requestFocus(passwordFocusNode);
},
),
SizedBox(height: 20),
],
TextField(
controller: passwordController,
focusNode: passwordFocusNode,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
textInputAction: isSignupMode ? TextInputAction.next : TextInputAction.done, // Adjust text action
onSubmitted: (_) {
if (!isSignupMode) { // If not in signup mode, handle login
_handleLogin();
} else { // In signup mode, move to confirm password
FocusScope.of(context).requestFocus(confirmPasswordFocusNode);
}
},
),
SizedBox(height: 20),
if (isSignupMode) ...[ // Conditionally show confirm password field
TextField(
controller: confirmPasswordController,
focusNode: confirmPasswordFocusNode,
decoration: InputDecoration(labelText: 'Confirm Password'),
obscureText: true,
textInputAction: TextInputAction.done,
onSubmitted: (_) {
_handleSignup(context);
},
),
SizedBox(height: 20),
],
ElevatedButton(
onPressed: () {
if (!isSignupMode) { // If not in signup mode, handle login
_handleLogin();
} else { // In signup mode, handle signup
_handleSignup(context);
}
},
child: Text(isSignupMode ? 'Signup' : 'Login'), // Dynamic button text
),
SizedBox(height: 20),
TextButton(
onPressed: () {
if (!isSignupMode) { // If in login mode, navigate to signup
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => LoginScreen(
onLogin: onLogin,
isSignupMode: true, // Push with signup mode
),
),
);
} else { // If in signup mode, pop back to login
Navigator.of(context).pop();
}
},
child: Text(
isSignupMode
? 'Already have an account? Login' // Text for signup mode
: 'Don\'t have an account? Sign Up', // Text for login mode
style: TextStyle(color: Colors.blue),
),
),
],
),
),
),
);
}
}