Add functional login page
This commit is contained in:
125
lib/login_page.dart
Normal file
125
lib/login_page.dart
Normal file
@@ -0,0 +1,125 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:jwt_decoder/jwt_decoder.dart';
|
||||
import 'package:sheetless/api.dart';
|
||||
import 'package:sheetless/home_page.dart';
|
||||
import 'package:sheetless/storage_helper.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({super.key});
|
||||
|
||||
@override
|
||||
_LoginPageState createState() => _LoginPageState();
|
||||
}
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
final TextEditingController _urlController = TextEditingController();
|
||||
final TextEditingController _emailController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
|
||||
final StorageHelper _storageHelper = StorageHelper();
|
||||
String? _error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkJwtValidity();
|
||||
}
|
||||
|
||||
Future<void> _checkJwtValidity() async {
|
||||
final jwt = await _storageHelper.read(StorageKey.jwt);
|
||||
if (jwt != null) {
|
||||
final isValid = await _validateJwt(jwt);
|
||||
if (isValid) {
|
||||
_navigateToMainPage();
|
||||
return;
|
||||
} else {
|
||||
final url = await _storageHelper.read(StorageKey.url);
|
||||
final email = await _storageHelper.read(StorageKey.email);
|
||||
final password = await _storageHelper.read(StorageKey.password);
|
||||
if (url != null && email != null && password != null) {
|
||||
_login(url, email, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _validateJwt(String jwt) async {
|
||||
try {
|
||||
bool expired = JwtDecoder.isExpired(jwt);
|
||||
return !expired;
|
||||
} on FormatException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _login(String serverUrl, String email, String password) async {
|
||||
setState(() {
|
||||
_error = null;
|
||||
});
|
||||
final apiClient = ApiClient(baseUrl: serverUrl);
|
||||
final loginSuccessful = await apiClient.login(email, password);
|
||||
if (loginSuccessful) {
|
||||
await _storageHelper.write(StorageKey.url, serverUrl);
|
||||
await _storageHelper.write(StorageKey.jwt, apiClient.token!);
|
||||
await _storageHelper.write(StorageKey.email, email);
|
||||
await _storageHelper.write(StorageKey.password, password);
|
||||
_navigateToMainPage();
|
||||
} else {
|
||||
// TODO: give more varied error messages
|
||||
setState(() {
|
||||
_error = "Login failed.";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _navigateToMainPage() {
|
||||
Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute(builder: (_) => MyHomePage()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Login')),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextField(
|
||||
controller: _urlController,
|
||||
decoration: InputDecoration(labelText: 'Url'),
|
||||
),
|
||||
TextField(
|
||||
controller: _emailController,
|
||||
decoration: InputDecoration(labelText: 'Email'),
|
||||
),
|
||||
TextField(
|
||||
controller: _passwordController,
|
||||
decoration: InputDecoration(labelText: 'Password'),
|
||||
obscureText: true,
|
||||
),
|
||||
if (_error != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(_error!, style: TextStyle(color: Colors.red)),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
_login(_urlController.text, _emailController.text,
|
||||
_passwordController.text);
|
||||
},
|
||||
child: Text('Login'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user