-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from ProductsWay/feature/show-wallet-on-accoun…
…t-screen
- Loading branch information
Showing
4 changed files
with
173 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:supabase/supabase.dart'; | ||
import 'package:conce_app/components/auth_required_state.dart'; | ||
import 'package:conce_app/components/avatar.dart'; | ||
import 'package:conce_app/utils/constants.dart'; | ||
|
||
class UserProfilePage extends StatefulWidget { | ||
const UserProfilePage({Key? key}) : super(key: key); | ||
|
||
@override | ||
_UserProfilePageState createState() => _UserProfilePageState(); | ||
} | ||
|
||
class _UserProfilePageState extends AuthRequiredState<UserProfilePage> { | ||
final _usernameController = TextEditingController(); | ||
final _websiteController = TextEditingController(); | ||
String? _userId; | ||
String? _avatarUrl; | ||
var _loading = false; | ||
|
||
/// Called once a user id is received within `onAuthenticated()` | ||
Future<void> _getProfile(String userId) async { | ||
setState(() { | ||
_loading = true; | ||
}); | ||
final response = await supabase | ||
.from('profiles') | ||
.select() | ||
.eq('id', userId) | ||
.single() | ||
.execute(); | ||
final error = response.error; | ||
if (error != null && response.status != 406) { | ||
context.showErrorSnackBar(message: error.message); | ||
} | ||
final data = response.data; | ||
if (data != null) { | ||
_usernameController.text = (data['username'] ?? '') as String; | ||
_websiteController.text = (data['website'] ?? '') as String; | ||
_avatarUrl = (data['avatar_url'] ?? '') as String; | ||
} | ||
setState(() { | ||
_loading = false; | ||
}); | ||
} | ||
|
||
/// Called when user taps `Update` button | ||
Future<void> _updateProfile() async { | ||
setState(() { | ||
_loading = true; | ||
}); | ||
final userName = _usernameController.text; | ||
final website = _websiteController.text; | ||
final user = supabase.auth.currentUser; | ||
final updates = { | ||
'id': user!.id, | ||
'username': userName, | ||
'website': website, | ||
'updated_at': DateTime.now().toIso8601String(), | ||
}; | ||
final response = await supabase.from('profiles').upsert(updates).execute(); | ||
final error = response.error; | ||
if (error != null) { | ||
context.showErrorSnackBar(message: error.message); | ||
} else { | ||
context.showSnackBar(message: 'Successfully updated profile!'); | ||
} | ||
setState(() { | ||
_loading = false; | ||
}); | ||
} | ||
|
||
Future<void> _signOut() async { | ||
final response = await supabase.auth.signOut(); | ||
final error = response.error; | ||
if (error != null) { | ||
context.showErrorSnackBar(message: error.message); | ||
} | ||
Navigator.of(context).pushReplacementNamed('/login'); | ||
} | ||
|
||
/// Called when image has been uploaded to Supabase storage from within Avatar widget | ||
Future<void> _onUpload(String imageUrl) async { | ||
final response = await supabase.from('profiles').upsert({ | ||
'id': _userId, | ||
'avatar_url': imageUrl, | ||
}).execute(); | ||
final error = response.error; | ||
if (error != null) { | ||
context.showErrorSnackBar(message: error.message); | ||
} | ||
setState(() { | ||
_avatarUrl = imageUrl; | ||
}); | ||
context.showSnackBar(message: 'Updated your profile image!'); | ||
} | ||
|
||
@override | ||
void onAuthenticated(Session session) { | ||
final user = session.user; | ||
if (user != null) { | ||
_userId = user.id; | ||
_getProfile(user.id); | ||
} | ||
} | ||
|
||
@override | ||
void onUnauthenticated() { | ||
Navigator.of(context).pushReplacementNamed('/login'); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
_usernameController.dispose(); | ||
_websiteController.dispose(); | ||
super.dispose(); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return ListView( | ||
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12), | ||
children: [ | ||
Avatar( | ||
imageUrl: _avatarUrl, | ||
onUpload: _onUpload, | ||
), | ||
const SizedBox(height: 18), | ||
TextFormField( | ||
controller: _usernameController, | ||
decoration: const InputDecoration(labelText: 'User Name'), | ||
), | ||
const SizedBox(height: 18), | ||
TextFormField( | ||
controller: _websiteController, | ||
decoration: const InputDecoration(labelText: 'Website'), | ||
), | ||
const SizedBox(height: 18), | ||
ElevatedButton( | ||
onPressed: _updateProfile, | ||
child: Text(_loading ? 'Saving...' : 'Update')), | ||
const SizedBox(height: 18), | ||
ElevatedButton(onPressed: _signOut, child: const Text('Sign Out')), | ||
], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters