Make invite form always visible in Organization Settings dialog, with send button enabled only if user has manage permission; reposition copy link button next to invite link text for sleeker layout

This commit is contained in:
Leon Bösche
2026-01-24 03:49:58 +01:00
parent c1c8f837a8
commit 1f7f4f33cc

View File

@@ -449,88 +449,83 @@ class _OrganizationSettingsDialogState
], ],
// Invite form // Invite form
if (_canManage) ...[ const Divider(),
const Divider(), Text(
Text( 'Invite New User',
'Invite New User', style: TextStyle(
style: TextStyle( color: AppTheme.primaryText,
color: AppTheme.primaryText, fontWeight: FontWeight.bold,
fontWeight: FontWeight.bold,
),
), ),
const SizedBox(height: 16), ),
TextField( const SizedBox(height: 16),
controller: usernameController, TextField(
decoration: InputDecoration( controller: usernameController,
labelText: 'Username', decoration: InputDecoration(
border: OutlineInputBorder(), labelText: 'Username',
), border: OutlineInputBorder(),
style: TextStyle(color: AppTheme.primaryText), ),
onChanged: (value) async { style: TextStyle(color: AppTheme.primaryText),
if (value.length > 2) { onChanged: (value) async {
try { if (value.length > 2) {
_userSuggestions = await widget.orgApi.searchUsers( try {
widget.organization.id, _userSuggestions = await widget.orgApi.searchUsers(
value, widget.organization.id,
); value,
} catch (e) { );
_userSuggestions = []; } catch (e) {
}
setState(() {});
} else {
_userSuggestions = []; _userSuggestions = [];
setState(() {});
} }
}, setState(() {});
), } else {
const SizedBox(height: 8), _userSuggestions = [];
if (_userSuggestions.isNotEmpty) ...[ setState(() {});
SizedBox( }
height: 100, },
child: ListView.builder( ),
itemCount: _userSuggestions.length, const SizedBox(height: 8),
itemBuilder: (context, index) { if (_userSuggestions.isNotEmpty) ...[
final user = _userSuggestions[index]; SizedBox(
return ListTile( height: 100,
title: Text( child: ListView.builder(
user.displayName ?? user.username, itemCount: _userSuggestions.length,
style: TextStyle(color: AppTheme.primaryText), itemBuilder: (context, index) {
), final user = _userSuggestions[index];
onTap: () { return ListTile(
usernameController.text = user.username; title: Text(
setState(() => _userSuggestions = []); user.displayName ?? user.username,
}, style: TextStyle(color: AppTheme.primaryText),
); ),
}, onTap: () {
), usernameController.text = user.username;
setState(() => _userSuggestions = []);
},
);
},
), ),
],
DropdownButtonFormField<String>(
initialValue: selectedRole,
items: ['admin', 'member'].map((role) {
return DropdownMenuItem(value: role, child: Text(role));
}).toList(),
onChanged: (value) => selectedRole = value ?? 'member',
decoration: const InputDecoration(
labelText: 'Role',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
ModernGlassButton(
onPressed: () {
final username = usernameController.text.trim();
if (username.isNotEmpty) {
_inviteUser(username, selectedRole);
usernameController.clear();
}
},
child: const Text('Send Invitation'),
), ),
], ],
DropdownButtonFormField<String>(
// Invite link section initialValue: selectedRole,
if (_inviteLink != null) ...[ items: ['admin', 'member'].map((role) {
return DropdownMenuItem(value: role, child: Text(role));
}).toList(),
onChanged: (value) => selectedRole = value ?? 'member',
decoration: const InputDecoration(
labelText: 'Role',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
ModernGlassButton(
onPressed: _canManage ? () {
final username = usernameController.text.trim();
if (username.isNotEmpty) {
_inviteUser(username, selectedRole);
usernameController.clear();
}
} : null,
child: const Text('Send Invitation'),
),
const Divider(), const Divider(),
Text( Text(
'Invite Link', 'Invite Link',
@@ -540,25 +535,27 @@ class _OrganizationSettingsDialogState
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text(
'https://b0esche.cloud/join?token=${_inviteLink ?? ''}',
style: TextStyle(color: AppTheme.secondaryText),
),
const SizedBox(height: 16),
Row( Row(
children: [ children: [
Expanded(
child: Text(
'https://b0esche.cloud/join?token=${_inviteLink ?? ''}',
style: TextStyle(color: AppTheme.secondaryText),
),
),
const SizedBox(width: 16),
ModernGlassButton( ModernGlassButton(
onPressed: _copyInviteLink, onPressed: _copyInviteLink,
child: const Text('Copy Link'), child: const Text('Copy Link'),
), ),
const SizedBox(width: 16),
if (_canManage)
ModernGlassButton(
onPressed: _regenerateInviteLink,
child: const Text('Regenerate'),
),
], ],
), ),
const SizedBox(height: 16),
if (_canManage)
ModernGlassButton(
onPressed: _regenerateInviteLink,
child: const Text('Regenerate'),
),
] else if (_canManage) ...[ ] else if (_canManage) ...[
const Divider(), const Divider(),
const Text('No invite link available'), const Text('No invite link available'),