Skip to content

Commit

Permalink
Add name display and editing to session widget
Browse files Browse the repository at this point in the history
This is overloaded probably but works for now.
  • Loading branch information
backspace committed Dec 17, 2024
1 parent 573cfc1 commit 9bc5918
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 32 deletions.
2 changes: 1 addition & 1 deletion registrations/lib/registrations_web/views/session_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule RegistrationsWeb.SessionView do
alias RegistrationsWeb.SessionView

def fields do
[:admin, :email]
[:admin, :email, :name]
end

def render("show.json", %{conn: conn, params: params}) do
Expand Down
17 changes: 15 additions & 2 deletions waydowntown_app/lib/services/user_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ class UserService {
static const String _userIsAdminKey = 'user_is_admin';
static const String _accessTokenKey = 'access_token';
static const String _renewalTokenKey = 'renewal_token';
static const String _userNameKey = 'user_name';

static Future<void> setUserData(
String userId, String email, bool isAdmin) async {
static Future<void> setUserData(String userId, String email, bool isAdmin,
{String? name}) async {
await _storage.write(key: _userIdKey, value: userId);
await _storage.write(key: _userEmailKey, value: email);
await _storage.write(key: _userIsAdminKey, value: isAdmin.toString());
if (name != null) {
await _storage.write(key: _userNameKey, value: name);
}
}

static Future<void> setTokens(String accessToken, String renewalToken) async {
Expand Down Expand Up @@ -42,9 +46,18 @@ class UserService {
return await _storage.read(key: _renewalTokenKey);
}

static Future<String?> getUserName() async {
return await _storage.read(key: _userNameKey);
}

static Future<void> setUserName(String name) async {
await _storage.write(key: _userNameKey, value: name);
}

static Future<void> clearUserData() async {
await _storage.delete(key: _userIdKey);
await _storage.delete(key: _userEmailKey);
await _storage.delete(key: _userNameKey);
await _storage.delete(key: _userIsAdminKey);
await _storage.delete(key: _accessTokenKey);
await _storage.delete(key: _renewalTokenKey);
Expand Down
151 changes: 129 additions & 22 deletions waydowntown_app/lib/widgets/session_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SessionWidget extends StatefulWidget {

class _SessionWidgetState extends State<SessionWidget> {
String? _email;
String? _name;
bool? _isAdmin;
bool _isLoading = true;

Expand All @@ -38,19 +39,23 @@ class _SessionWidgetState extends State<SessionWidget> {
final attributes = response.data['data']['attributes'];
setState(() {
_email = attributes['email'];
_name = attributes['name'];
_isAdmin = attributes['admin'] ?? false;
_isLoading = false;
});
await UserService.setUserData(
response.data['data']['id'], _email!, _isAdmin!);
response.data['data']['id'], _email!, _isAdmin!,
name: _name);
return;
}

final email = await UserService.getUserEmail();
final name = await UserService.getUserName();
final isAdmin = await UserService.getUserIsAdmin();

setState(() {
_email = email;
_name = name;
_isAdmin = isAdmin;
_isLoading = false;
});
Expand Down Expand Up @@ -85,6 +90,37 @@ class _SessionWidgetState extends State<SessionWidget> {
await _checkSession();
}

Future<void> _updateName(String newName) async {
try {
final userId = await UserService.getUserId();
final response = await widget.dio.post(
'${widget.apiBaseUrl}/fixme/me',
data: {
'data': {
'type': 'users',
'id': userId,
'attributes': {'name': newName}
}
},
options: Options(headers: {
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json',
}),
);

if (response.statusCode == 200) {
final attributes = response.data['data']['attributes'];
setState(() {
_name = attributes['name'];
});
await UserService.setUserName(_name!);
}
} catch (error) {
talker.error('Error updating name: $error');
rethrow;
}
}

void _openAuthForm() {
showDialog(
context: context,
Expand All @@ -104,36 +140,107 @@ class _SessionWidgetState extends State<SessionWidget> {
);
}

void _openNameEditDialog() {
final controller = TextEditingController(text: _name);
String? errorText;

showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: const Text('Edit Name'),
content: TextField(
controller: controller,
decoration: InputDecoration(
labelText: 'Name',
errorText: errorText,
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
TextButton(
onPressed: () async {
if (controller.text.isEmpty) {
setState(() {
errorText = "Name can't be blank";
});
return;
}
try {
await _updateName(controller.text);
Navigator.of(context).pop();
} catch (e) {
setState(() {
errorText = 'Failed to update name';
});
}
},
child: const Text('Save'),
),
],
);
},
);
},
);
}

@override
Widget build(BuildContext context) {
if (_isLoading) {
return const CircularProgressIndicator();
}

if (_email != null) {
return Wrap(
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 8, // Add some space between the email and the logout button
children: [
Text('$_email', style: const TextStyle(color: Colors.white)),
if (_isAdmin == true)
const Icon(Icons.admin_panel_settings, color: Colors.white),
IconButton(
icon: const Icon(Icons.logout, color: Colors.white),
onPressed: _logout,
tooltip: 'Log out',
),
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MySpecificationsTable(dio: widget.dio),
return Material(
type: MaterialType.transparency,
child: Wrap(
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 8,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: _openNameEditDialog,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(_name ?? _email!,
style: const TextStyle(color: Colors.white)),
const Icon(Icons.edit, color: Colors.white, size: 16),
],
),
),
Text(_email!,
style: const TextStyle(color: Colors.white, fontSize: 12)),
],
),
if (_isAdmin == true)
const Icon(Icons.admin_panel_settings, color: Colors.white),
IconButton(
icon: const Icon(Icons.logout, color: Colors.white),
onPressed: _logout,
tooltip: 'Log out',
),
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MySpecificationsTable(dio: widget.dio),
),
),
child: const Text('My specifications'),
),
child: const Text('My specifications'),
),
],
],
),
);
}

Expand Down
Loading

0 comments on commit 9bc5918

Please sign in to comment.