From 9654497a2b5f3e0085d55da9a75466938b176537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Sat, 24 Jan 2026 04:04:29 +0100 Subject: [PATCH] Reorder invite tab: move invite link above user search fields; style TextField and Dropdown with app theme colors to avoid purple borders --- .../widgets/organization_settings_dialog.dart | 202 ++++++++++-------- 1 file changed, 113 insertions(+), 89 deletions(-) diff --git a/b0esche_cloud/lib/widgets/organization_settings_dialog.dart b/b0esche_cloud/lib/widgets/organization_settings_dialog.dart index 0280540..ea1b198 100644 --- a/b0esche_cloud/lib/widgets/organization_settings_dialog.dart +++ b/b0esche_cloud/lib/widgets/organization_settings_dialog.dart @@ -448,95 +448,6 @@ class _OrganizationSettingsDialogState ), ], - // Invite form - 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 { - _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( - 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: () { - if (_canManage) { - final username = usernameController.text.trim(); - if (username.isNotEmpty) { - _inviteUser(username, selectedRole); - usernameController.clear(); - } - } else { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text( - 'You do not have permission to send invitations', - ), - ), - ); - } - }, - child: const Text('Send Invitation'), - ), - // Invite link section if (_inviteLink != null) ...[ const Divider(), @@ -573,6 +484,119 @@ class _OrganizationSettingsDialogState const Divider(), const Text('No invite link available'), ], + + // Invite form + const Divider(), + Text( + 'Invite New User', + style: TextStyle( + color: AppTheme.primaryText, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + Container( + decoration: BoxDecoration( + border: Border.all( + color: AppTheme.accentColor.withValues(alpha: 0.3), + ), + borderRadius: BorderRadius.circular(8), + ), + child: TextField( + controller: usernameController, + cursorColor: AppTheme.accentColor, + decoration: InputDecoration( + hintText: 'Username', + hintStyle: TextStyle(color: AppTheme.secondaryText), + contentPadding: const EdgeInsets.all(12), + border: InputBorder.none, + ), + 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 { + _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( + initialValue: selectedRole, + items: ['admin', 'member'].map((role) { + return DropdownMenuItem(value: role, child: Text(role)); + }).toList(), + onChanged: (value) => selectedRole = value ?? 'member', + decoration: InputDecoration( + labelText: 'Role', + labelStyle: TextStyle(color: AppTheme.secondaryText), + border: OutlineInputBorder( + borderSide: BorderSide( + color: AppTheme.accentColor.withValues(alpha: 0.3), + ), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: AppTheme.accentColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: AppTheme.accentColor.withValues(alpha: 0.3), + ), + ), + ), + ), + const SizedBox(height: 16), + ModernGlassButton( + onPressed: () { + if (_canManage) { + final username = usernameController.text.trim(); + if (username.isNotEmpty) { + _inviteUser(username, selectedRole); + usernameController.clear(); + } + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'You do not have permission to send invitations', + ), + ), + ); + } + }, + child: const Text('Send Invitation'), + ), ], ); }