125 lines
3.6 KiB
Dart
125 lines
3.6 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../core/api/client.dart';
|
|
import '../core/api/endpoints.dart';
|
|
import '../core/api/exceptions.dart';
|
|
import '../models/workspace.dart';
|
|
|
|
class WorkspaceState {
|
|
final List<Workspace> workspaces;
|
|
final Workspace? selectedWorkspace;
|
|
final List<WorkspaceMember> members;
|
|
final bool isLoading;
|
|
final String? error;
|
|
|
|
WorkspaceState({
|
|
this.workspaces = const [],
|
|
this.selectedWorkspace,
|
|
this.members = const [],
|
|
this.isLoading = false,
|
|
this.error,
|
|
});
|
|
|
|
WorkspaceState copyWith({
|
|
List<Workspace>? workspaces,
|
|
Workspace? selectedWorkspace,
|
|
List<WorkspaceMember>? members,
|
|
bool? isLoading,
|
|
String? error,
|
|
}) =>
|
|
WorkspaceState(
|
|
workspaces: workspaces ?? this.workspaces,
|
|
selectedWorkspace: selectedWorkspace ?? this.selectedWorkspace,
|
|
members: members ?? this.members,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
error: error,
|
|
);
|
|
}
|
|
|
|
class WorkspaceNotifier extends StateNotifier<WorkspaceState> {
|
|
final ApiClient _api;
|
|
|
|
WorkspaceNotifier(this._api) : super(WorkspaceState());
|
|
|
|
Future<void> loadWorkspaces() async {
|
|
state = state.copyWith(isLoading: true, error: null);
|
|
try {
|
|
final response = await _api.get(Endpoints.workspaces);
|
|
final list = (response.data as List<dynamic>)
|
|
.map((e) => Workspace.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
state = state.copyWith(workspaces: list, isLoading: false);
|
|
} on ApiException catch (e) {
|
|
state = state.copyWith(isLoading: false, error: e.message);
|
|
}
|
|
}
|
|
|
|
Future<Workspace?> createWorkspace(CreateWorkspaceRequest request) async {
|
|
try {
|
|
final response =
|
|
await _api.post(Endpoints.workspaces, data: request.toJson());
|
|
final ws =
|
|
Workspace.fromJson(response.data as Map<String, dynamic>);
|
|
state = state.copyWith(workspaces: [...state.workspaces, ws]);
|
|
return ws;
|
|
} on ApiException catch (e) {
|
|
state = state.copyWith(error: e.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<void> selectWorkspace(Workspace workspace) async {
|
|
state = state.copyWith(selectedWorkspace: workspace);
|
|
await loadMembers(workspace.id);
|
|
}
|
|
|
|
Future<void> loadMembers(String workspaceId) async {
|
|
try {
|
|
final response =
|
|
await _api.get(Endpoints.workspaceMembers(workspaceId));
|
|
final list = (response.data as List<dynamic>)
|
|
.map((e) => WorkspaceMember.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
state = state.copyWith(members: list);
|
|
} on ApiException catch (e) {
|
|
state = state.copyWith(error: e.message);
|
|
}
|
|
}
|
|
|
|
Future<bool> addMember(String workspaceId, String email, String role) async {
|
|
try {
|
|
await _api.post(Endpoints.workspaceMembers(workspaceId), data: {
|
|
'email': email,
|
|
'role': role,
|
|
});
|
|
await loadMembers(workspaceId);
|
|
return true;
|
|
} on ApiException catch (e) {
|
|
state = state.copyWith(error: e.message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> removeMember(String workspaceId, String userId) async {
|
|
try {
|
|
await _api.delete(Endpoints.workspaceMember(workspaceId, userId));
|
|
state = state.copyWith(
|
|
members: state.members.where((m) => m.userId != userId).toList(),
|
|
);
|
|
return true;
|
|
} on ApiException catch (e) {
|
|
state = state.copyWith(error: e.message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void clearError() {
|
|
state = state.copyWith(error: null);
|
|
}
|
|
}
|
|
|
|
final workspaceProvider =
|
|
StateNotifierProvider<WorkspaceNotifier, WorkspaceState>((ref) {
|
|
final api = ref.read(apiClientProvider);
|
|
return WorkspaceNotifier(api);
|
|
});
|