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