initial codex commit
This commit is contained in:
@@ -13,7 +13,6 @@ class LoginScreen extends StatelessWidget {
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 50,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text.rich(
|
||||
@@ -39,14 +38,15 @@ class LoginScreen extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white,
|
||||
fontFamily: "Tomatoes",
|
||||
fontSize: 50,
|
||||
),
|
||||
fontFamily: "Tomatoes",
|
||||
fontSize: 50,
|
||||
),
|
||||
),
|
||||
LoginPanel(),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 50),
|
||||
LoginPanel(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -115,7 +115,7 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
|
||||
bool _loggingIn = false;
|
||||
|
||||
void login() async {
|
||||
Future<void> login() async {
|
||||
final username = _usernameController.text;
|
||||
final password = _passwordController.text;
|
||||
|
||||
@@ -126,19 +126,18 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
});
|
||||
try {
|
||||
await auth.login(username, password);
|
||||
print('Login successful');
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_loggingIn = false;
|
||||
});
|
||||
} catch (e) {
|
||||
// Handle error
|
||||
print('Login failed: $e');
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_loggingIn = false;
|
||||
});
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('Login failed')));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Login failed: $e')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +162,6 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 50),
|
||||
@@ -172,6 +170,7 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextFormField(
|
||||
controller: _usernameController,
|
||||
decoration: InputDecoration(
|
||||
@@ -180,6 +179,7 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
),
|
||||
onFieldSubmitted: (_) => login(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextFormField(
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
@@ -189,11 +189,12 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
),
|
||||
onFieldSubmitted: (_) => login(),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 10,
|
||||
children: [
|
||||
FilledButton(onPressed: login, child: loginButtonContent),
|
||||
const SizedBox(width: 10),
|
||||
ElevatedButton(
|
||||
onPressed: widget.registerCb,
|
||||
child: Text("Register"),
|
||||
@@ -205,7 +206,7 @@ class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterPanelContent extends StatelessWidget {
|
||||
class RegisterPanelContent extends StatefulWidget {
|
||||
const RegisterPanelContent({
|
||||
super.key,
|
||||
required this.onBack,
|
||||
@@ -213,20 +214,64 @@ class RegisterPanelContent extends StatelessWidget {
|
||||
});
|
||||
final VoidCallback onBack;
|
||||
final AuthService authService;
|
||||
void register() {}
|
||||
@override
|
||||
State<RegisterPanelContent> createState() => _RegisterPanelContentState();
|
||||
}
|
||||
|
||||
class _RegisterPanelContentState extends State<RegisterPanelContent> {
|
||||
final _usernameController = TextEditingController();
|
||||
final _displayNameController = TextEditingController();
|
||||
final _emailController = TextEditingController();
|
||||
final _passwordController = TextEditingController();
|
||||
final _inviteController = TextEditingController();
|
||||
bool _registering = false;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_usernameController.dispose();
|
||||
_displayNameController.dispose();
|
||||
_emailController.dispose();
|
||||
_passwordController.dispose();
|
||||
_inviteController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _register() async {
|
||||
setState(() => _registering = true);
|
||||
try {
|
||||
await widget.authService.register(
|
||||
username: _usernameController.text.trim(),
|
||||
email: _emailController.text.trim(),
|
||||
fullName: _displayNameController.text.trim(),
|
||||
password: _passwordController.text,
|
||||
inviteCode: _inviteController.text.trim(),
|
||||
);
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Registration successful. Please log in.')),
|
||||
);
|
||||
widget.onBack();
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Registration failed: $e')),
|
||||
);
|
||||
} finally {
|
||||
if (mounted) setState(() => _registering = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: onBack,
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: widget.onBack,
|
||||
tooltip: 'Back to login',
|
||||
),
|
||||
Expanded(
|
||||
@@ -237,47 +282,64 @@ class RegisterPanelContent extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Spacer to balance the row visually
|
||||
SizedBox(width: 48), // matches IconButton size
|
||||
const SizedBox(width: 48),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
controller: _usernameController,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Username",
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
controller: _displayNameController,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Display Name",
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
controller: _emailController,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Email",
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Password",
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
controller: _inviteController,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Invite Code",
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 10,
|
||||
children: [
|
||||
FilledButton(onPressed: register, child: Text("Register")),
|
||||
FilledButton(
|
||||
onPressed: _registering ? null : _register,
|
||||
child: _registering
|
||||
? const SizedBox(
|
||||
height: 14,
|
||||
width: 14,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Text("Register"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user