Skip to content

Commit

Permalink
Add preliminary login form
Browse files Browse the repository at this point in the history
It seems maybe webview isn’t needed? This only works for
user/password for now, the whole thing is a mess, but
it’s starting to work…
  • Loading branch information
backspace committed Sep 26, 2024
1 parent f27dbdf commit 20e950e
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 18 deletions.
123 changes: 123 additions & 0 deletions waydowntown_app/lib/tools/auth_form.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';

class AuthFormWidget extends StatefulWidget {
final Dio dio;
final String apiBaseUrl;
final Function onAuthSuccess;

const AuthFormWidget({
Key? key,
required this.dio,
required this.apiBaseUrl,
required this.onAuthSuccess,
}) : super(key: key);

@override
_AuthFormWidgetState createState() => _AuthFormWidgetState();
}

class _AuthFormWidgetState extends State<AuthFormWidget> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
bool _isLoading = false;

Future<void> _submitForm() async {
if (_formKey.currentState!.validate()) {
setState(() {
_isLoading = true;
});

try {
final response = await widget.dio.post(
'${widget.apiBaseUrl}/powapi/session',
options: Options(headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}),
data: {
'user': {
'email': _emailController.text,
'password': _passwordController.text,
},
},
);

if (response.statusCode == 200) {
final accessToken = response.data['data']['access_token'];
final renewalToken = response.data['data']['renewal_token'];

final prefs = await SharedPreferences.getInstance();
await prefs.setString('access_token', accessToken);
await prefs.setString('renewal_token', renewalToken);

widget.onAuthSuccess();
} else {
// Handle error (e.g., show error message)
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Authentication failed')),
);
}
} catch (error) {
print('Error during authentication: $error');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('An error occurred')),
);
} finally {
setState(() {
_isLoading = false;
});
}
}
}

@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: _emailController,
decoration: const InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
return null;
},
),
TextFormField(
controller: _passwordController,
decoration: const InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
return null;
},
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _isLoading ? null : _submitForm,
child: _isLoading
? const CircularProgressIndicator()
: const Text('Log in'),
),
],
),
);
}

@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
}
46 changes: 28 additions & 18 deletions waydowntown_app/lib/widgets/session_widget.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:waydowntown/tools/auth_webview.dart';
import 'package:waydowntown/tools/auth_form.dart';

class SessionWidget extends StatefulWidget {
final Dio dio;
Expand All @@ -24,18 +24,22 @@ class _SessionWidgetState extends State<SessionWidget> {
}

Future<void> _checkSession() async {
final otherDio = Dio();

setState(() {
_isLoading = true;
});

final prefs = await SharedPreferences.getInstance();
final cookieString = prefs.getString('auth_cookie');
final authToken = prefs.getString('access_token');

if (cookieString != null) {
if (authToken != null) {
try {
final response = await widget.dio.get(
'/fixme/session',
options: Options(headers: {'Cookie': cookieString}),
final response = await otherDio.get(
'${widget.apiBaseUrl}/fixme/session',
options: Options(headers: {
'Authorization': authToken,
}),
);

if (response.statusCode == 200) {
Expand All @@ -58,21 +62,27 @@ class _SessionWidgetState extends State<SessionWidget> {

Future<void> _logout() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('auth_cookie');
await prefs.remove('access_token');
_checkSession();
}

void _openAuthWebView() async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AuthWebView(
apiBaseUrl: widget.apiBaseUrl,
dio: widget.dio,
),
),
void _openAuthForm() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Log in'),
content: AuthFormWidget(
dio: widget.dio,
apiBaseUrl: widget.apiBaseUrl,
onAuthSuccess: () {
Navigator.of(context).pop();
_checkSession();
},
),
);
},
);
_checkSession();
}

@override
Expand All @@ -98,7 +108,7 @@ class _SessionWidgetState extends State<SessionWidget> {
}

return ElevatedButton(
onPressed: _openAuthWebView,
onPressed: _openAuthForm,
child: const Text('Log in'),
);
}
Expand Down

0 comments on commit 20e950e

Please sign in to comment.