Skip to content

Commit 609e5b3

Browse files
committed
fix: delete workspace successfully done
1 parent 3a7d4f5 commit 609e5b3

File tree

5 files changed

+241
-86
lines changed

5 files changed

+241
-86
lines changed

lib/features/dashboard/providers/dashboard_provider.dart

Lines changed: 83 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,16 @@ class DashboardProvider extends StateHandler {
7575
.from('workspace')
7676
.select()
7777
.eq('owner', res.id);
78-
print(_dbWorkspace);
7978
_workspaceList.clear();
8079
for (var workspace in _dbWorkspace) {
8180
WorkspaceModel newWorkspace = WorkspaceModel(
8281
id: workspace["id"],
8382
owner: workspace["owner"],
8483
name: workspace["name"],
85-
editorIdList: (workspace["editorId"] as List?)?.cast<String>() ?? [],
86-
viewerIdList: (workspace["viewerId"] as List?)?.cast<String>() ?? [],
84+
editorIdList:
85+
(workspace["editorId"] as List?)?.cast<String>() ?? [],
86+
viewerIdList:
87+
(workspace["viewerId"] as List?)?.cast<String>() ?? [],
8788
lastEdited:
8889
workspace["last edited"] != null
8990
? DateTime.parse(workspace["last edited"])
@@ -102,10 +103,11 @@ class DashboardProvider extends StateHandler {
102103
}
103104
}
104105

105-
// New method to update workspace name from WorkspaceProvider
106106
void updateWorkspaceName(String workspaceId, String newName) {
107107
if (_workspaceList.containsKey(workspaceId)) {
108-
_workspaceList[workspaceId] = _workspaceList[workspaceId]!.copyWith(name: newName);
108+
_workspaceList[workspaceId] = _workspaceList[workspaceId]!.copyWith(
109+
name: newName,
110+
);
109111
notifyListeners();
110112
}
111113
}
@@ -118,19 +120,19 @@ class DashboardProvider extends StateHandler {
118120
_isLoading = false;
119121
print("User not found");
120122
notifyListeners();
121-
return; // Add return to exit if user is null
123+
return;
122124
}
123-
Map<String, dynamic> newWorkspaceData = { // Use Map<String, dynamic> for clarity
125+
Map<String, dynamic> newWorkspaceData = {
124126
"id": Uuid().v4(),
125127
"owner": res.id,
126128
"name": "New Project",
127-
"editorId": [], // Initialize as empty list if no editors
128-
"viewerId": [], // Initialize as empty list if no viewers
129+
"editorId": [],
130+
"viewerId": [],
129131
};
130132

131133
await supabase!.from('workspace').insert(newWorkspaceData);
132134

133-
await refreshDashboard(); // Use await here
135+
await refreshDashboard();
134136
} catch (e) {
135137
print("Error creating new project: $e");
136138
} finally {
@@ -140,4 +142,75 @@ class DashboardProvider extends StateHandler {
140142
}
141143

142144
void importExistingProject(BuildContext context) {}
145+
146+
Future<void> syncWithDb() async {
147+
if (supabase == null) {
148+
print("Supabase client is not initialized. Cannot sync with DB.");
149+
return;
150+
}
151+
152+
_isLoading = true;
153+
notifyListeners();
154+
155+
try {
156+
final List<Map<String, dynamic>> workspacesToSync = [];
157+
_workspaceList.forEach((id, workspaceModel) {
158+
workspacesToSync.add(workspaceModel.toJson());
159+
});
160+
161+
if (workspacesToSync.isNotEmpty) {
162+
await supabase!.from('workspace').upsert(workspacesToSync);
163+
print("All workspaces synced successfully with the database.");
164+
} else {
165+
print("No workspaces to sync.");
166+
}
167+
} catch (e) {
168+
print("Error syncing workspaces to database: $e");
169+
} finally {
170+
_isLoading = false;
171+
notifyListeners();
172+
await refreshDashboard();
173+
}
174+
}
175+
176+
// UPDATED deleteWorkspace function
177+
Future<void> deleteWorkspace(String id) async {
178+
if (supabase == null) {
179+
print("Supabase client is not initialized. Cannot delete workspace.");
180+
return;
181+
}
182+
183+
_isLoading = true;
184+
notifyListeners();
185+
186+
try {
187+
// 1. Delete all canvas_objects linked to this workspace
188+
print('Deleting canvas_objects for workspace: $id');
189+
await supabase!
190+
.from('canvas_objects')
191+
.delete()
192+
.eq('workspace_id', id);
193+
print('Canvas objects for workspace $id deleted from database.');
194+
195+
196+
// 3. Delete the workspace from the database
197+
print('Deleting workspace: $id');
198+
await supabase!
199+
.from('workspace')
200+
.delete()
201+
.eq('id', id);
202+
print('Workspace $id deleted from database.');
203+
204+
// 4. Then remove it from the local list
205+
_workspaceList.remove(id);
206+
207+
print("Workspace $id removed from local list.");
208+
} catch (e) {
209+
print("Error deleting workspace $id: $e");
210+
} finally {
211+
_isLoading = false;
212+
notifyListeners();
213+
await refreshDashboard(); // Refresh local list after sync to pick up DB changes
214+
}
215+
}
143216
}

lib/features/dashboard/widgets/project_card.dart

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:cookethflow/core/helpers/date_time_helper.dart';
22
import 'package:cookethflow/core/router/app_route_const.dart';
33
import 'package:cookethflow/features/dashboard/providers/dashboard_provider.dart';
4+
import 'package:cookethflow/features/dashboard/widgets/workspace_options_dialog.dart';
45
import 'package:cookethflow/features/workspace/pages/workspace.dart';
56
import 'package:cookethflow/features/workspace/providers/workspace_provider.dart';
67
import 'package:flutter/material.dart';
@@ -21,7 +22,10 @@ class ProjectCard extends StatelessWidget {
2122
return GestureDetector(
2223
onTap: () {
2324
workspaceProvider.setWorkspace(workspaceId);
24-
context.goNamed(RouteName.workspace,pathParameters: {'workspace_id':workspaceId});
25+
context.goNamed(
26+
RouteName.workspace,
27+
pathParameters: {'workspace_id': workspaceId},
28+
);
2529
},
2630
child: Container(
2731
decoration: BoxDecoration(
@@ -60,7 +64,19 @@ class ProjectCard extends StatelessWidget {
6064
borderRadius: BorderRadius.circular(12.r),
6165
),
6266
child: IconButton(
63-
onPressed: () {},
67+
onPressed: () {
68+
showDialog(
69+
context: context,
70+
builder: (dialogContext) => WorkspaceOptionsDialog( // Use dialogContext to pop the dialog
71+
onPressed: () async { // Make onPressed async
72+
Navigator.of(dialogContext).pop(); // Dismiss the dialog first
73+
await provider.deleteWorkspace(workspaceId); // Then delete from DB
74+
// No need to call refreshDashboard here as deleteWorkspace already calls it
75+
},
76+
),
77+
);
78+
// Removed .then(context.pop) here
79+
},
6480
icon: Icon(
6581
PhosphorIconsRegular.dotsThree,
6682
size: 32.sp,
@@ -131,4 +147,4 @@ class ProjectCard extends StatelessWidget {
131147
},
132148
);
133149
}
134-
}
150+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import 'package:cookethflow/core/providers/supabase_provider.dart';
2+
import 'package:cookethflow/core/theme/app_theme.dart';
3+
import 'package:cookethflow/core/theme/colors.dart';
4+
import 'package:cookethflow/features/dashboard/providers/dashboard_provider.dart';
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_screenutil/flutter_screenutil.dart';
7+
import 'package:phosphor_flutter/phosphor_flutter.dart';
8+
import 'package:provider/provider.dart';
9+
10+
class WorkspaceOptionsDialog extends StatelessWidget {
11+
WorkspaceOptionsDialog({super.key, required this.onPressed});
12+
void Function()? onPressed;
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return Consumer2<SupabaseService, DashboardProvider>(
17+
builder: (context, supa, dashboard, child) {
18+
return Dialog(
19+
shape: RoundedRectangleBorder(
20+
borderRadius: BorderRadius.circular(20.sp),
21+
),
22+
backgroundColor:
23+
supa.isDark
24+
? AppTheme.dark().scaffoldBackgroundColor
25+
: AppTheme.light().scaffoldBackgroundColor,
26+
child: Padding(
27+
padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w),
28+
child: Container(
29+
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 30.h),
30+
decoration: BoxDecoration(
31+
border: Border.all(color: primaryColor),
32+
borderRadius: BorderRadius.circular(20.sp),
33+
),
34+
height: 0.2.sh,
35+
child: Column(
36+
// mainAxisAlignment: MainAxisAlignment.start,
37+
crossAxisAlignment: CrossAxisAlignment.start,
38+
children: [
39+
TextButton.icon(
40+
onPressed: onPressed,
41+
icon: Icon(
42+
PhosphorIcons.trashSimple(),
43+
size: 25.sp,
44+
color: Colors.red,
45+
),
46+
label: Text(
47+
'Delete Workspace',
48+
style:
49+
supa.isDark
50+
? AppTheme.dark().textTheme.headlineSmall
51+
: AppTheme.light().textTheme.headlineSmall,
52+
),
53+
),
54+
],
55+
),
56+
),
57+
),
58+
);
59+
},
60+
);
61+
}
62+
}
Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
// import 'package:cookethflow/features/models/connection_model.dart';
2-
// import 'package:cookethflow/features/models/node_model.dart';
3-
1+
// WorkspaceModel.dart (Ensuring correct key names for toJson and fromJson)
42
class WorkspaceModel {
53
String id;
64
String owner;
75
String name;
86
List<String> editorIdList;
97
List<String> viewerIdList;
108
DateTime? lastEdited;
11-
// List<NodeModel> nodeList;
12-
// List<ConnectionModel> connectionList;
139

1410
WorkspaceModel({
1511
required this.id,
@@ -18,8 +14,6 @@ class WorkspaceModel {
1814
required this.editorIdList,
1915
required this.viewerIdList,
2016
required this.lastEdited,
21-
// this.nodeList = const [],
22-
// this.connectionList = const [],
2317
});
2418

2519
WorkspaceModel copyWith({
@@ -29,8 +23,6 @@ class WorkspaceModel {
2923
List<String>? editorIdList,
3024
List<String>? viewerIdList,
3125
DateTime? lastEdited,
32-
// List<NodeModel>? nodeList,
33-
// List<ConnectionModel>? connectionList,
3426
}) {
3527
return WorkspaceModel(
3628
id: id ?? this.id,
@@ -39,8 +31,6 @@ class WorkspaceModel {
3931
editorIdList: editorIdList ?? List.from(this.editorIdList),
4032
viewerIdList: viewerIdList ?? List.from(this.viewerIdList),
4133
lastEdited: lastEdited ?? this.lastEdited,
42-
// nodeList: nodeList ?? List.from(this.nodeList),
43-
// connectionList: connectionList ?? List.from(this.connectionList),
4434
);
4535
}
4636

@@ -49,11 +39,10 @@ class WorkspaceModel {
4939
'id': id,
5040
'owner': owner,
5141
'name': name,
52-
'editorIdList': editorIdList,
53-
'viewerIdList': viewerIdList,
54-
'lastEdited': lastEdited?.toIso8601String(),
55-
// 'nodeList': nodeList.map((node) => node.toJson()).toList(),
56-
// 'connectionList': connectionList.map((conn) => conn.toJson()).toList(),
42+
// Ensure these keys match your Supabase table column names exactly
43+
'editorId': editorIdList,
44+
'viewerId': viewerIdList,
45+
'last edited': lastEdited?.toIso8601String(),
5746
};
5847
}
5948

@@ -62,23 +51,12 @@ class WorkspaceModel {
6251
id: json['id'] as String,
6352
owner: json['owner'] as String,
6453
name: json['name'] as String,
65-
editorIdList: List<String>.from(json['editorIdList']),
66-
viewerIdList: List<String>.from(json['viewerIdList']),
67-
lastEdited: DateTime.parse(json['lastEdited'] as String),
68-
// nodeList:
69-
// (json['nodeList'] as List<dynamic>)
70-
// .map(
71-
// (nodeJson) =>
72-
// NodeModel.fromJson(nodeJson as Map<String, dynamic>),
73-
// )
74-
// .toList(),
75-
// connectionList:
76-
// (json['connectionList'] as List<dynamic>)
77-
// .map(
78-
// (connJson) =>
79-
// ConnectionModel.fromJson(connJson as Map<String, dynamic>),
80-
// )
81-
// .toList(),
54+
// Ensure these keys match your Supabase table column names exactly
55+
editorIdList: List<String>.from(json['editorId'] ?? []), // Handle potential null if not always present
56+
viewerIdList: List<String>.from(json['viewerId'] ?? []), // Handle potential null if not always present
57+
lastEdited: json['last edited'] != null
58+
? DateTime.parse(json['last edited'] as String)
59+
: null, // Handle potential null for 'last edited'
8260
);
8361
}
84-
}
62+
}

0 commit comments

Comments
 (0)