fix: resolve invite overflow and member removal lookup
This commit is contained in:
parent
d566621033
commit
bd177cedcc
2 changed files with 47 additions and 41 deletions
|
|
@ -146,45 +146,50 @@ class _ManageCollectionScreenState extends State<ManageCollectionScreen> {
|
||||||
child: const Icon(Icons.person_add, color: Colors.white, size: 28),
|
child: const Icon(Icons.person_add, color: Colors.white, size: 28),
|
||||||
),
|
),
|
||||||
title: const Text('Invite Member'),
|
title: const Text('Invite Member'),
|
||||||
content: Column(
|
content: SingleChildScrollView(
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: ConstrainedBox(
|
||||||
children: [
|
constraints: const BoxConstraints(maxWidth: 420),
|
||||||
const Text(
|
child: Column(
|
||||||
'Enter the email address of the person you want to invite. '
|
mainAxisSize: MainAxisSize.min,
|
||||||
'They must already have an account.',
|
children: [
|
||||||
style: TextStyle(
|
const Text(
|
||||||
fontSize: 13,
|
'Enter the email address of the person you want to invite. '
|
||||||
color: AppColors.textSecondary,
|
'They must already have an account.',
|
||||||
),
|
style: TextStyle(
|
||||||
),
|
fontSize: 13,
|
||||||
const SizedBox(height: 16),
|
color: AppColors.textSecondary,
|
||||||
TextField(
|
),
|
||||||
controller: emailCtrl,
|
),
|
||||||
autofocus: true,
|
const SizedBox(height: 16),
|
||||||
keyboardType: TextInputType.emailAddress,
|
TextField(
|
||||||
decoration: const InputDecoration(
|
controller: emailCtrl,
|
||||||
labelText: 'Email address',
|
autofocus: true,
|
||||||
hintText: 'user@example.com',
|
keyboardType: TextInputType.emailAddress,
|
||||||
prefixIcon: Icon(Icons.email_outlined),
|
decoration: const InputDecoration(
|
||||||
),
|
labelText: 'Email address',
|
||||||
),
|
hintText: 'user@example.com',
|
||||||
const SizedBox(height: 12),
|
prefixIcon: Icon(Icons.email_outlined),
|
||||||
DropdownButtonFormField<String>(
|
),
|
||||||
initialValue: inviteRole,
|
),
|
||||||
decoration: const InputDecoration(
|
const SizedBox(height: 12),
|
||||||
labelText: 'Role',
|
DropdownButtonFormField<String>(
|
||||||
prefixIcon: Icon(Icons.security_outlined),
|
initialValue: inviteRole,
|
||||||
),
|
decoration: const InputDecoration(
|
||||||
items: const [
|
labelText: 'Role',
|
||||||
DropdownMenuItem(value: 'member', child: Text('Member (can add/copy/edit)')),
|
prefixIcon: Icon(Icons.security_outlined),
|
||||||
DropdownMenuItem(value: 'viewer', child: Text('Viewer (read-only)')),
|
),
|
||||||
|
items: const [
|
||||||
|
DropdownMenuItem(value: 'member', child: Text('Member (can add/copy/edit)')),
|
||||||
|
DropdownMenuItem(value: 'viewer', child: Text('Viewer (read-only)')),
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value == null) return;
|
||||||
|
setSheetState(() => inviteRole = value);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onChanged: (value) {
|
|
||||||
if (value == null) return;
|
|
||||||
setSheetState(() => inviteRole = value);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
|
|
@ -256,7 +261,7 @@ class _ManageCollectionScreenState extends State<ManageCollectionScreen> {
|
||||||
try {
|
try {
|
||||||
await CollectionService.removeMember(
|
await CollectionService.removeMember(
|
||||||
collectionId: _collection.id,
|
collectionId: _collection.id,
|
||||||
membershipId: member.id,
|
memberUserId: member.userId,
|
||||||
);
|
);
|
||||||
showGlobalSnackBar('Member removed.');
|
showGlobalSnackBar('Member removed.');
|
||||||
await _loadMembers();
|
await _loadMembers();
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ class CollectionService {
|
||||||
/// Remove a member from a collection.
|
/// Remove a member from a collection.
|
||||||
static Future<void> removeMember({
|
static Future<void> removeMember({
|
||||||
required String collectionId,
|
required String collectionId,
|
||||||
required String membershipId,
|
required String memberUserId,
|
||||||
}) async {
|
}) async {
|
||||||
final currentUserId = supabase.auth.currentUser!.id;
|
final currentUserId = supabase.auth.currentUser!.id;
|
||||||
|
|
||||||
|
|
@ -346,7 +346,7 @@ class CollectionService {
|
||||||
final target = await supabase
|
final target = await supabase
|
||||||
.from('collection_members')
|
.from('collection_members')
|
||||||
.select('role, user_id')
|
.select('role, user_id')
|
||||||
.eq('id', membershipId)
|
.eq('user_id', memberUserId)
|
||||||
.eq('collection_id', collectionId)
|
.eq('collection_id', collectionId)
|
||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
|
|
@ -360,7 +360,8 @@ class CollectionService {
|
||||||
await supabase
|
await supabase
|
||||||
.from('collection_members')
|
.from('collection_members')
|
||||||
.delete()
|
.delete()
|
||||||
.eq('id', membershipId);
|
.eq('user_id', memberUserId)
|
||||||
|
.eq('collection_id', collectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Leave a collection (for non-owners).
|
/// Leave a collection (for non-owners).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue