Refactor code for improved readability and consistency in multiple files

This commit is contained in:
Leon Bösche
2026-01-23 23:21:46 +01:00
parent 20bc0ac757
commit 98e7bbdb9e
8 changed files with 206 additions and 145 deletions

View File

@@ -18,7 +18,9 @@ class PermissionBloc extends Bloc<PermissionEvent, PermissionState> {
) 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,

View File

@@ -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,
);
}
}

View File

@@ -370,13 +370,20 @@ class _HomePageState extends State<HomePage> 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 ?? () {
onTap:
onTap ??
() {
setState(() {
_selectedTab = label;
});
@@ -495,7 +502,12 @@ class _HomePageState extends State<HomePage> 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',

View File

@@ -71,7 +71,10 @@ class ApiClient {
}
}
Future<Map<String, dynamic>> getRaw(String path, {Map<String, dynamic>? queryParameters}) async {
Future<Map<String, dynamic>> getRaw(
String path, {
Map<String, dynamic>? queryParameters,
}) async {
try {
final response = await _dio.get(path, queryParameters: queryParameters);
return response.data;

View File

@@ -39,7 +39,11 @@ class OrgApi {
);
}
Future<void> updateMemberRole(String orgId, String userId, String role) async {
Future<void> 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<Invitation> createInvitation(String orgId, String username, String role) async {
Future<Invitation> 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<JoinRequest> createJoinRequest(String orgId, {String? inviteToken}) async {
Future<JoinRequest> createJoinRequest(
String orgId, {
String? inviteToken,
}) async {
final data = {'orgId': orgId};
if (inviteToken != null) {
data['inviteToken'] = inviteToken;
@@ -98,7 +109,11 @@ class OrgApi {
);
}
Future<void> acceptJoinRequest(String orgId, String requestId, String role) async {
Future<void> acceptJoinRequest(
String orgId,
String requestId,
String role,
) async {
await _apiClient.post(
'/orgs/$orgId/join-requests/$requestId/accept',
data: {'role': role},

View File

@@ -20,10 +20,12 @@ class OrganizationSettingsDialog extends StatefulWidget {
});
@override
State<OrganizationSettingsDialog> createState() => _OrganizationSettingsDialogState();
State<OrganizationSettingsDialog> createState() =>
_OrganizationSettingsDialogState();
}
class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog> with TickerProviderStateMixin {
class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
with TickerProviderStateMixin {
late TabController _tabController;
List<Member> _members = [];
List<Invitation> _invitations = [];
@@ -77,46 +79,54 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
Future<void> _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<void> _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<void> _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<void> _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<OrganizationSettingsDialog>
Future<void> _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<void> _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<void> _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<OrganizationSettingsDialog>
}
}
bool get _canManage => widget.permissionState is PermissionLoaded &&
bool get _canManage =>
widget.permissionState is PermissionLoaded &&
(widget.permissionState as PermissionLoaded).capabilities.canAdmin;
@override
@@ -232,7 +246,10 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_error!, style: TextStyle(color: AppTheme.errorColor)),
Text(
_error!,
style: TextStyle(color: AppTheme.errorColor),
),
const SizedBox(height: 16),
ModernGlassButton(
onPressed: _loadData,
@@ -271,7 +288,8 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
member.role,
style: TextStyle(color: AppTheme.secondaryText),
),
trailing: _canManage ? Row(
trailing: _canManage
? Row(
mainAxisSize: MainAxisSize.min,
children: [
if (member.role != 'owner')
@@ -291,11 +309,15 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
),
if (member.role != 'owner')
IconButton(
icon: Icon(Icons.remove_circle, color: AppTheme.errorColor),
icon: Icon(
Icons.remove_circle,
color: AppTheme.errorColor,
),
onPressed: () => _removeMember(member.userId),
),
],
) : null,
)
: null,
);
},
);
@@ -323,8 +345,14 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
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<OrganizationSettingsDialog>
DropdownButtonFormField<String>(
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,7 +424,8 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
'Requested to join',
style: TextStyle(color: AppTheme.secondaryText),
),
trailing: _canManage ? Row(
trailing: _canManage
? Row(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
@@ -408,10 +434,14 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
),
TextButton(
onPressed: () => _rejectJoinRequest(req.id),
child: Text('Reject', style: TextStyle(color: AppTheme.errorColor)),
child: Text(
'Reject',
style: TextStyle(color: AppTheme.errorColor),
),
),
],
) : null,
)
: null,
);
},
);
@@ -429,10 +459,7 @@ class _OrganizationSettingsDialogState extends State<OrganizationSettingsDialog>
),
),
const SizedBox(height: 8),
Text(
_inviteLink!,
style: TextStyle(color: AppTheme.secondaryText),
),
Text(_inviteLink!, style: TextStyle(color: AppTheme.secondaryText)),
const SizedBox(height: 16),
Row(
children: [