diff --git a/b0esche_cloud/lib/blocs/organization/organization_bloc.dart b/b0esche_cloud/lib/blocs/organization/organization_bloc.dart index c6ad4be..605ee06 100644 --- a/b0esche_cloud/lib/blocs/organization/organization_bloc.dart +++ b/b0esche_cloud/lib/blocs/organization/organization_bloc.dart @@ -97,59 +97,73 @@ class OrganizationBloc extends Bloc { CreateOrganization event, Emitter emit, ) async { - final currentState = state; - if (currentState is OrganizationLoaded) { - final name = event.name.trim(); - if (name.isEmpty) { + final name = event.name.trim(); + if (name.isEmpty) { + // Try to preserve current state if possible + if (state is OrganizationLoaded) { emit( OrganizationLoaded( - organizations: currentState.organizations, - selectedOrg: currentState.selectedOrg, + organizations: (state as OrganizationLoaded).organizations, + selectedOrg: (state as OrganizationLoaded).selectedOrg, isLoading: false, error: 'Organization name cannot be empty', ), ); - return; } - if (currentState.organizations.any((org) => org.name == name)) { + return; + } + + // Get existing organizations list + List existingOrgs = []; + Organization? selectedOrg; + + if (state is OrganizationLoaded) { + existingOrgs = (state as OrganizationLoaded).organizations; + selectedOrg = (state as OrganizationLoaded).selectedOrg; + + // Check for duplicate name (client-side validation) + if (existingOrgs.any((org) => org.name == name)) { emit( OrganizationLoaded( - organizations: currentState.organizations, - selectedOrg: currentState.selectedOrg, + organizations: existingOrgs, + selectedOrg: selectedOrg, isLoading: false, error: 'Organization with this name already exists', ), ); return; } + } + + // Set loading state + emit( + OrganizationLoaded( + organizations: existingOrgs, + selectedOrg: selectedOrg, + isLoading: true, + ), + ); + + try { + final newOrg = await orgApi.createOrganization(name); + final updatedOrgs = [...existingOrgs, newOrg]; + emit( + OrganizationLoaded(organizations: updatedOrgs, selectedOrg: newOrg), + ); + // Reset blocs and load permissions for new org + permissionBloc.add(PermissionsReset()); + fileBrowserBloc.add(ResetFileBrowser()); + uploadBloc.add(ResetUploads()); + permissionBloc.add(LoadPermissions(newOrg.id)); + } catch (e) { emit( OrganizationLoaded( - organizations: currentState.organizations, - selectedOrg: currentState.selectedOrg, - isLoading: true, + organizations: existingOrgs, + selectedOrg: selectedOrg, + isLoading: false, + error: _getErrorMessage(e), ), ); - try { - final newOrg = await orgApi.createOrganization(name); - final updatedOrgs = [...currentState.organizations, newOrg]; - emit( - OrganizationLoaded(organizations: updatedOrgs, selectedOrg: newOrg), - ); - // Reset blocs and load permissions for new org - permissionBloc.add(PermissionsReset()); - fileBrowserBloc.add(ResetFileBrowser()); - uploadBloc.add(ResetUploads()); - permissionBloc.add(LoadPermissions(newOrg.id)); - } catch (e) { - emit( - OrganizationLoaded( - organizations: currentState.organizations, - selectedOrg: currentState.selectedOrg, - isLoading: false, - error: _getErrorMessage(e), - ), - ); - } } } } diff --git a/b0esche_cloud/lib/services/api_client.dart b/b0esche_cloud/lib/services/api_client.dart index bfb4ad4..2a66f89 100644 --- a/b0esche_cloud/lib/services/api_client.dart +++ b/b0esche_cloud/lib/services/api_client.dart @@ -29,8 +29,13 @@ class ApiClient { }, onError: (error, handler) async { if (error.response?.statusCode == 401) { - // Session expired, trigger logout - _sessionBloc.add(SessionExpired()); + final path = error.requestOptions.path; + // Do not expire session for auth endpoints; show inline error instead + final isAuthEndpoint = path.startsWith('/auth/'); + if (!isAuthEndpoint) { + // Session expired, trigger logout + _sessionBloc.add(SessionExpired()); + } } return handler.next(error); },