From 98e7bbdb9e86f972ad51d98c7eef27d0a344b4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Fri, 23 Jan 2026 23:21:46 +0100 Subject: [PATCH] Refactor code for improved readability and consistency in multiple files --- .../lib/blocs/permission/permission_bloc.dart | 4 +- b0esche_cloud/lib/models/organization.dart | 6 +- b0esche_cloud/lib/pages/home_page.dart | 26 +- b0esche_cloud/lib/services/api_client.dart | 5 +- b0esche_cloud/lib/services/org_api.dart | 23 +- .../widgets/organization_settings_dialog.dart | 231 ++++++++++-------- go_cloud/internal/database/db.go | 24 +- go_cloud/internal/http/routes.go | 32 +-- 8 files changed, 206 insertions(+), 145 deletions(-) diff --git a/b0esche_cloud/lib/blocs/permission/permission_bloc.dart b/b0esche_cloud/lib/blocs/permission/permission_bloc.dart index fae3936..3181385 100644 --- a/b0esche_cloud/lib/blocs/permission/permission_bloc.dart +++ b/b0esche_cloud/lib/blocs/permission/permission_bloc.dart @@ -18,7 +18,9 @@ class PermissionBloc extends Bloc { ) async { emit(PermissionLoading()); try { - final response = await apiClient.getRaw('/orgs/${event.orgId}/permissions'); + final response = await apiClient.getRaw( + '/orgs/${event.orgId}/permissions', + ); final capabilities = Capabilities( canRead: response['canRead'] ?? false, canWrite: response['canWrite'] ?? false, diff --git a/b0esche_cloud/lib/models/organization.dart b/b0esche_cloud/lib/models/organization.dart index 96ae350..72dffdc 100644 --- a/b0esche_cloud/lib/models/organization.dart +++ b/b0esche_cloud/lib/models/organization.dart @@ -56,7 +56,9 @@ class Invitation { role: json['role'], createdAt: DateTime.parse(json['createdAt']), expiresAt: DateTime.parse(json['expiresAt']), - acceptedAt: json['acceptedAt'] != null ? DateTime.parse(json['acceptedAt']) : null, + acceptedAt: json['acceptedAt'] != null + ? DateTime.parse(json['acceptedAt']) + : null, ); } } @@ -91,4 +93,4 @@ class JoinRequest { user: User.fromJson(json['User'] ?? json), ); } -} \ No newline at end of file +} diff --git a/b0esche_cloud/lib/pages/home_page.dart b/b0esche_cloud/lib/pages/home_page.dart index 31716cb..17e851d 100644 --- a/b0esche_cloud/lib/pages/home_page.dart +++ b/b0esche_cloud/lib/pages/home_page.dart @@ -370,17 +370,24 @@ class _HomePageState extends State with TickerProviderStateMixin { ); } - Widget _buildNavButton(String label, IconData icon, {bool isAvatar = false, VoidCallback? onTap}) { + Widget _buildNavButton( + String label, + IconData icon, { + bool isAvatar = false, + VoidCallback? onTap, + }) { final isSelected = _selectedTab == label; final highlightColor = const Color.fromARGB(255, 100, 200, 255); final defaultColor = AppTheme.secondaryText; return GestureDetector( - onTap: onTap ?? () { - setState(() { - _selectedTab = label; - }); - }, + onTap: + onTap ?? + () { + setState(() { + _selectedTab = label; + }); + }, child: isAvatar ? CircleAvatar( backgroundColor: isSelected ? highlightColor : defaultColor, @@ -495,7 +502,12 @@ class _HomePageState extends State with TickerProviderStateMixin { const SizedBox(width: 16), _buildNavButton('Add', Icons.add), const SizedBox(width: 16), - _buildNavButton('Settings', Icons.settings, onTap: () => _showOrganizationSettings(context)), + _buildNavButton( + 'Settings', + Icons.settings, + onTap: () => + _showOrganizationSettings(context), + ), const SizedBox(width: 16), _buildNavButton( 'Profile', diff --git a/b0esche_cloud/lib/services/api_client.dart b/b0esche_cloud/lib/services/api_client.dart index 53a8fe3..08a276b 100644 --- a/b0esche_cloud/lib/services/api_client.dart +++ b/b0esche_cloud/lib/services/api_client.dart @@ -71,7 +71,10 @@ class ApiClient { } } - Future> getRaw(String path, {Map? queryParameters}) async { + Future> getRaw( + String path, { + Map? queryParameters, + }) async { try { final response = await _dio.get(path, queryParameters: queryParameters); return response.data; diff --git a/b0esche_cloud/lib/services/org_api.dart b/b0esche_cloud/lib/services/org_api.dart index 81a4caa..5d106a0 100644 --- a/b0esche_cloud/lib/services/org_api.dart +++ b/b0esche_cloud/lib/services/org_api.dart @@ -39,7 +39,11 @@ class OrgApi { ); } - Future updateMemberRole(String orgId, String userId, String role) async { + Future updateMemberRole( + String orgId, + String userId, + String role, + ) async { await _apiClient.patch( '/orgs/$orgId/members/$userId', data: {'role': role}, @@ -58,7 +62,11 @@ class OrgApi { ); } - Future createInvitation(String orgId, String username, String role) async { + Future createInvitation( + String orgId, + String username, + String role, + ) async { final result = await _apiClient.post( '/orgs/$orgId/invitations', data: {'username': username, 'role': role}, @@ -78,7 +86,10 @@ class OrgApi { await _apiClient.delete('/orgs/$orgId/invitations/$invitationId'); } - Future createJoinRequest(String orgId, {String? inviteToken}) async { + Future createJoinRequest( + String orgId, { + String? inviteToken, + }) async { final data = {'orgId': orgId}; if (inviteToken != null) { data['inviteToken'] = inviteToken; @@ -98,7 +109,11 @@ class OrgApi { ); } - Future acceptJoinRequest(String orgId, String requestId, String role) async { + Future acceptJoinRequest( + String orgId, + String requestId, + String role, + ) async { await _apiClient.post( '/orgs/$orgId/join-requests/$requestId/accept', data: {'role': role}, diff --git a/b0esche_cloud/lib/widgets/organization_settings_dialog.dart b/b0esche_cloud/lib/widgets/organization_settings_dialog.dart index b6ee71b..3460548 100644 --- a/b0esche_cloud/lib/widgets/organization_settings_dialog.dart +++ b/b0esche_cloud/lib/widgets/organization_settings_dialog.dart @@ -20,10 +20,12 @@ class OrganizationSettingsDialog extends StatefulWidget { }); @override - State createState() => _OrganizationSettingsDialogState(); + State createState() => + _OrganizationSettingsDialogState(); } -class _OrganizationSettingsDialogState extends State with TickerProviderStateMixin { +class _OrganizationSettingsDialogState extends State + with TickerProviderStateMixin { late TabController _tabController; List _members = []; List _invitations = []; @@ -77,46 +79,54 @@ class _OrganizationSettingsDialogState extends State Future _updateMemberRole(String userId, String newRole) async { try { - await widget.orgApi.updateMemberRole(widget.organization.id, userId, newRole); + await widget.orgApi.updateMemberRole( + widget.organization.id, + userId, + newRole, + ); await _loadData(); // Refresh } catch (e) { if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to update role: $e')), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Failed to update role: $e'))); } } Future _removeMember(String userId) async { try { - await widget.orgApi.removeMember(widget.organization.id, userId); await _loadData(); // Refresh } catch (e) { if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to remove member: $e')), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Failed to remove member: $e'))); } } Future _inviteUser(String username, String role) async { try { - - await widget.orgApi.createInvitation(widget.organization.id, username, role); + await widget.orgApi.createInvitation( + widget.organization.id, + username, + role, + ); await _loadData(); // Refresh } catch (e) { if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to send invitation: $e')), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Failed to send invitation: $e'))); } } Future _cancelInvitation(String invitationId) async { try { - - await widget.orgApi.cancelInvitation(widget.organization.id, invitationId); + await widget.orgApi.cancelInvitation( + widget.organization.id, + invitationId, + ); await _loadData(); // Refresh } catch (e) { if (!mounted) return; @@ -128,40 +138,43 @@ class _OrganizationSettingsDialogState extends State Future _acceptJoinRequest(String requestId, String role) async { try { - - await widget.orgApi.acceptJoinRequest(widget.organization.id, requestId, role); + await widget.orgApi.acceptJoinRequest( + widget.organization.id, + requestId, + role, + ); await _loadData(); // Refresh } catch (e) { if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to accept request: $e')), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Failed to accept request: $e'))); } } Future _rejectJoinRequest(String requestId) async { try { - await widget.orgApi.rejectJoinRequest(widget.organization.id, requestId); await _loadData(); // Refresh } catch (e) { if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to reject request: $e')), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Failed to reject request: $e'))); } } Future _regenerateInviteLink() async { try { - - final newLink = await widget.orgApi.regenerateInviteLink(widget.organization.id); + final newLink = await widget.orgApi.regenerateInviteLink( + widget.organization.id, + ); setState(() => _inviteLink = newLink); } catch (e) { if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to regenerate link: $e')), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Failed to regenerate link: $e'))); } } @@ -174,7 +187,8 @@ class _OrganizationSettingsDialogState extends State } } - bool get _canManage => widget.permissionState is PermissionLoaded && + bool get _canManage => + widget.permissionState is PermissionLoaded && (widget.permissionState as PermissionLoaded).capabilities.canAdmin; @override @@ -228,28 +242,31 @@ class _OrganizationSettingsDialogState extends State child: _isLoading ? const Center(child: CircularProgressIndicator()) : _error != null - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(_error!, style: TextStyle(color: AppTheme.errorColor)), - const SizedBox(height: 16), - ModernGlassButton( - onPressed: _loadData, - child: const Text('Retry'), - ), - ], + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + _error!, + style: TextStyle(color: AppTheme.errorColor), ), - ) - : TabBarView( - controller: _tabController, - children: [ - _buildMembersTab(), - _buildInviteTab(), - _buildRequestsTab(), - _buildLinkTab(), - ], - ), + const SizedBox(height: 16), + ModernGlassButton( + onPressed: _loadData, + child: const Text('Retry'), + ), + ], + ), + ) + : TabBarView( + controller: _tabController, + children: [ + _buildMembersTab(), + _buildInviteTab(), + _buildRequestsTab(), + _buildLinkTab(), + ], + ), ), ], ), @@ -271,31 +288,36 @@ class _OrganizationSettingsDialogState extends State member.role, style: TextStyle(color: AppTheme.secondaryText), ), - trailing: _canManage ? Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (member.role != 'owner') - DropdownButton( - value: member.role, - items: ['admin', 'member'].map((role) { - return DropdownMenuItem( - value: role, - child: Text(role), - ); - }).toList(), - onChanged: (newRole) { - if (newRole != null && newRole != member.role) { - _updateMemberRole(member.userId, newRole); - } - }, - ), - if (member.role != 'owner') - IconButton( - icon: Icon(Icons.remove_circle, color: AppTheme.errorColor), - onPressed: () => _removeMember(member.userId), - ), - ], - ) : null, + trailing: _canManage + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (member.role != 'owner') + DropdownButton( + value: member.role, + items: ['admin', 'member'].map((role) { + return DropdownMenuItem( + value: role, + child: Text(role), + ); + }).toList(), + onChanged: (newRole) { + if (newRole != null && newRole != member.role) { + _updateMemberRole(member.userId, newRole); + } + }, + ), + if (member.role != 'owner') + IconButton( + icon: Icon( + Icons.remove_circle, + color: AppTheme.errorColor, + ), + onPressed: () => _removeMember(member.userId), + ), + ], + ) + : null, ); }, ); @@ -323,8 +345,14 @@ class _OrganizationSettingsDialogState extends State itemBuilder: (context, index) { final inv = _invitations[index]; return ListTile( - title: Text(inv.username, style: TextStyle(color: AppTheme.primaryText)), - subtitle: Text('Role: ${inv.role}', style: TextStyle(color: AppTheme.secondaryText)), + title: Text( + inv.username, + style: TextStyle(color: AppTheme.primaryText), + ), + subtitle: Text( + 'Role: ${inv.role}', + style: TextStyle(color: AppTheme.secondaryText), + ), trailing: IconButton( icon: Icon(Icons.cancel, color: AppTheme.errorColor), onPressed: () => _cancelInvitation(inv.id), @@ -358,10 +386,7 @@ class _OrganizationSettingsDialogState extends State DropdownButtonFormField( initialValue: selectedRole, items: ['admin', 'member'].map((role) { - return DropdownMenuItem( - value: role, - child: Text(role), - ); + return DropdownMenuItem(value: role, child: Text(role)); }).toList(), onChanged: (value) => selectedRole = value ?? 'member', decoration: const InputDecoration( @@ -399,19 +424,24 @@ class _OrganizationSettingsDialogState extends State 'Requested to join', style: TextStyle(color: AppTheme.secondaryText), ), - trailing: _canManage ? Row( - mainAxisSize: MainAxisSize.min, - children: [ - TextButton( - onPressed: () => _acceptJoinRequest(req.id, 'member'), - child: const Text('Accept'), - ), - TextButton( - onPressed: () => _rejectJoinRequest(req.id), - child: Text('Reject', style: TextStyle(color: AppTheme.errorColor)), - ), - ], - ) : null, + trailing: _canManage + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + TextButton( + onPressed: () => _acceptJoinRequest(req.id, 'member'), + child: const Text('Accept'), + ), + TextButton( + onPressed: () => _rejectJoinRequest(req.id), + child: Text( + 'Reject', + style: TextStyle(color: AppTheme.errorColor), + ), + ), + ], + ) + : null, ); }, ); @@ -429,10 +459,7 @@ class _OrganizationSettingsDialogState extends State ), ), const SizedBox(height: 8), - Text( - _inviteLink!, - style: TextStyle(color: AppTheme.secondaryText), - ), + Text(_inviteLink!, style: TextStyle(color: AppTheme.secondaryText)), const SizedBox(height: 16), Row( children: [ @@ -454,4 +481,4 @@ class _OrganizationSettingsDialogState extends State ], ); } -} \ No newline at end of file +} diff --git a/go_cloud/internal/database/db.go b/go_cloud/internal/database/db.go index dc51575..24a056e 100644 --- a/go_cloud/internal/database/db.go +++ b/go_cloud/internal/database/db.go @@ -101,12 +101,12 @@ type Session struct { } type Organization struct { - ID uuid.UUID `json:"id"` - OwnerID uuid.UUID `json:"ownerId"` - Name string `json:"name"` - Slug string `json:"slug"` - InviteLinkToken *string `json:"inviteLinkToken,omitempty"` - CreatedAt time.Time `json:"createdAt"` + ID uuid.UUID `json:"id"` + OwnerID uuid.UUID `json:"ownerId"` + Name string `json:"name"` + Slug string `json:"slug"` + InviteLinkToken *string `json:"inviteLinkToken,omitempty"` + CreatedAt time.Time `json:"createdAt"` } type Membership struct { @@ -128,12 +128,12 @@ type Invitation struct { } type JoinRequest struct { - ID uuid.UUID - OrgID uuid.UUID - UserID uuid.UUID - InviteToken *string - RequestedAt time.Time - Status string + ID uuid.UUID + OrgID uuid.UUID + UserID uuid.UUID + InviteToken *string + RequestedAt time.Time + Status string } type Activity struct { diff --git a/go_cloud/internal/http/routes.go b/go_cloud/internal/http/routes.go index fc181a1..089feea 100644 --- a/go_cloud/internal/http/routes.go +++ b/go_cloud/internal/http/routes.go @@ -930,10 +930,10 @@ func removeMemberHandler(w http.ResponseWriter, r *http.Request, db *database.DB resource := userID.String() auditLogger.Log(r.Context(), audit.Entry{ - OrgID: &orgID, - Action: "remove_member", + OrgID: &orgID, + Action: "remove_member", Resource: &resource, - Success: true, + Success: true, }) w.WriteHeader(http.StatusOK) @@ -993,11 +993,11 @@ func createInvitationHandler(w http.ResponseWriter, r *http.Request, db *databas } auditLogger.Log(r.Context(), audit.Entry{ - UserID: &invitedBy, - OrgID: &orgID, - Action: "create_invitation", + UserID: &invitedBy, + OrgID: &orgID, + Action: "create_invitation", Resource: &req.Username, - Success: true, + Success: true, }) w.Header().Set("Content-Type", "application/json") @@ -1035,10 +1035,10 @@ func cancelInvitationHandler(w http.ResponseWriter, r *http.Request, db *databas resource := invitationID.String() auditLogger.Log(r.Context(), audit.Entry{ - OrgID: &orgID, - Action: "cancel_invitation", + OrgID: &orgID, + Action: "cancel_invitation", Resource: &resource, - Success: true, + Success: true, }) w.WriteHeader(http.StatusOK) @@ -1142,10 +1142,10 @@ func acceptJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *databa resource := requestID.String() auditLogger.Log(r.Context(), audit.Entry{ - OrgID: &orgID, - Action: "accept_join_request", + OrgID: &orgID, + Action: "accept_join_request", Resource: &resource, - Success: true, + Success: true, }) w.WriteHeader(http.StatusOK) @@ -1169,10 +1169,10 @@ func rejectJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *databa resource := requestID.String() auditLogger.Log(r.Context(), audit.Entry{ - OrgID: &orgID, - Action: "reject_join_request", + OrgID: &orgID, + Action: "reject_join_request", Resource: &resource, - Success: true, + Success: true, }) w.WriteHeader(http.StatusOK)