Initial commit
This commit is contained in:
215
lib/components/login/login.dart
Normal file
215
lib/components/login/login.dart
Normal file
@@ -0,0 +1,215 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mileograph_flutter/services/authservice.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class LoginPage extends StatelessWidget {
|
||||
const LoginPage({super.key});
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [LoginPanel()],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LoginPanel extends StatefulWidget {
|
||||
const LoginPanel({super.key});
|
||||
|
||||
@override
|
||||
State<LoginPanel> createState() => _LoginPanelState();
|
||||
}
|
||||
|
||||
class _LoginPanelState extends State<LoginPanel> {
|
||||
bool registerMode = false;
|
||||
|
||||
void toggleMode() {
|
||||
setState(() {
|
||||
registerMode = !registerMode;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final authService = context.read<AuthService>();
|
||||
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 400,
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: registerMode
|
||||
? RegisterPanelContent(
|
||||
onBack: toggleMode,
|
||||
authService: authService,
|
||||
)
|
||||
: LoginPanelContent(
|
||||
registerCb: toggleMode,
|
||||
authService: authService,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LoginPanelContent extends StatefulWidget {
|
||||
const LoginPanelContent({
|
||||
required this.registerCb,
|
||||
required this.authService,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final VoidCallback registerCb;
|
||||
final AuthService authService;
|
||||
|
||||
@override
|
||||
State<LoginPanelContent> createState() => _LoginPanelContentState();
|
||||
}
|
||||
|
||||
class _LoginPanelContentState extends State<LoginPanelContent> {
|
||||
final _usernameController = TextEditingController();
|
||||
final _passwordController = TextEditingController();
|
||||
|
||||
void login() async {
|
||||
final username = _usernameController.text;
|
||||
final password = _passwordController.text;
|
||||
|
||||
final auth = context.read<AuthService>();
|
||||
|
||||
try {
|
||||
auth.login(username, password);
|
||||
print('Login successful');
|
||||
} catch (e) {
|
||||
// Handle error
|
||||
print('Login failed: $e');
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('Login failed')));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 50),
|
||||
child: Text(
|
||||
"Login",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
controller: _usernameController,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Username",
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Password",
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 10,
|
||||
children: [
|
||||
FilledButton(onPressed: login, child: Text("Login")),
|
||||
ElevatedButton(
|
||||
onPressed: widget.registerCb,
|
||||
child: Text("Register"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterPanelContent extends StatelessWidget {
|
||||
const RegisterPanelContent({required this.onBack, required this.authService});
|
||||
final VoidCallback onBack;
|
||||
final AuthService authService;
|
||||
void register() {}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: onBack,
|
||||
tooltip: 'Back to login',
|
||||
),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Register",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Spacer to balance the row visually
|
||||
SizedBox(width: 48), // matches IconButton size
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Username",
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Display Name",
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Email",
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Password",
|
||||
),
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Invite Code",
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 10,
|
||||
children: [
|
||||
FilledButton(onPressed: register, child: Text("Register")),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user