Add Personal tab and fix org selection + API error handling
This commit is contained in:
@@ -73,10 +73,18 @@ class OrganizationBloc extends Bloc<OrganizationEvent, OrganizationState> {
|
|||||||
) {
|
) {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is OrganizationLoaded) {
|
if (currentState is OrganizationLoaded) {
|
||||||
final selected = currentState.organizations.firstWhere(
|
Organization? selected;
|
||||||
(org) => org.id == event.orgId,
|
|
||||||
orElse: () => currentState.selectedOrg!,
|
if (event.orgId.isEmpty) {
|
||||||
);
|
// Personal workspace - set to null to indicate no org selected
|
||||||
|
selected = null;
|
||||||
|
} else {
|
||||||
|
selected = currentState.organizations.firstWhere(
|
||||||
|
(org) => org.id == event.orgId,
|
||||||
|
orElse: () => currentState.selectedOrg!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
OrganizationLoaded(
|
OrganizationLoaded(
|
||||||
organizations: currentState.organizations,
|
organizations: currentState.organizations,
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ class _MainAppState extends State<MainApp> {
|
|||||||
theme: AppTheme.darkTheme,
|
theme: AppTheme.darkTheme,
|
||||||
home: const Scaffold(
|
home: const Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
AppTheme.accentColor,
|
AppTheme.accentColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
|
|||||||
@@ -131,8 +131,9 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
final name = controller.text.trim();
|
final name = controller.text.trim();
|
||||||
if (name.isNotEmpty) {
|
if (name.isNotEmpty) {
|
||||||
// Use the parent context, not the dialog context
|
// Use the parent context, not the dialog context
|
||||||
BlocProvider.of<OrganizationBloc>(context)
|
BlocProvider.of<OrganizationBloc>(
|
||||||
.add(CreateOrganization(name));
|
context,
|
||||||
|
).add(CreateOrganization(name));
|
||||||
Navigator.of(dialogContext).pop();
|
Navigator.of(dialogContext).pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -151,8 +152,9 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
final name = controller.text.trim();
|
final name = controller.text.trim();
|
||||||
if (name.isNotEmpty) {
|
if (name.isNotEmpty) {
|
||||||
// Use the parent context, not the dialog context
|
// Use the parent context, not the dialog context
|
||||||
BlocProvider.of<OrganizationBloc>(context)
|
BlocProvider.of<OrganizationBloc>(
|
||||||
.add(CreateOrganization(name));
|
context,
|
||||||
|
).add(CreateOrganization(name));
|
||||||
Navigator.of(dialogContext).pop();
|
Navigator.of(dialogContext).pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -189,6 +191,18 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
// Personal workspace button (always show when logged in)
|
||||||
|
_buildOrgButton(
|
||||||
|
Organization(id: '', name: 'Personal'),
|
||||||
|
selectedOrg == null,
|
||||||
|
() {
|
||||||
|
context.read<OrganizationBloc>().add(
|
||||||
|
SelectOrganization(''),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
// Organization tabs
|
||||||
...orgs.map(
|
...orgs.map(
|
||||||
(org) => Row(
|
(org) => Row(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -120,8 +120,17 @@ class ApiClient {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String code = data?['code'] ?? 'UNKNOWN';
|
// Only try to extract code/message if data is a Map
|
||||||
String message = data?['message'] ?? 'Unknown error';
|
String code = 'UNKNOWN';
|
||||||
|
String message = 'Unknown error';
|
||||||
|
|
||||||
|
if (data is Map<String, dynamic>) {
|
||||||
|
code = data['code'] ?? 'UNKNOWN';
|
||||||
|
message = data['message'] ?? 'Unknown error';
|
||||||
|
} else if (data != null) {
|
||||||
|
message = data.toString();
|
||||||
|
}
|
||||||
|
|
||||||
return ApiError(code: code, message: message, status: status);
|
return ApiError(code: code, message: message, status: status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user