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 { 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 _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 _validateJwt(String jwt) async { try { bool expired = JwtDecoder.isExpired(jwt); return !expired; } on FormatException { return false; } } Future _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'), ), ], ), ), ); } }