1
1
import { redirect } from "next/navigation" ;
2
2
import CollaborativeSandpackEditor from "@/src/components/editor/CollaborativeSandpackEditor" ;
3
- import { templates } from "@/src/utils" ;
4
- import { auth } from "@clerk/nextjs/server" ;
5
- import { createNewRoom , fetchLatestRoomFilesState } from "@/src/lib/actions" ;
6
- import { logFailureCb , handleFailureCase } from "@/src/lib/utils" ;
3
+ import { auth , currentUser } from "@clerk/nextjs/server" ;
4
+ import { createNewRoom , fetchLatestRoomFilesState , fetchRoomMembers , inviteUserToRoom } from "@/src/lib/actions" ;
5
+ import { logFailureCb , handleFailureCase , templates , RoomRole } from "@/src/lib/utils" ;
7
6
8
7
9
8
10
9
export default async function CollaborativeRoomPage ( { params, searchParams } ) {
11
10
const { userId } = await auth ( ) ;
11
+ const user = await currentUser ( ) ;
12
12
const roomId = params [ "roomId" ] ;
13
13
const template = searchParams [ "template" ] ;
14
14
console . log ( "Template: " , template ) ;
@@ -18,7 +18,7 @@ export default async function CollaborativeRoomPage({ params, searchParams }) {
18
18
redirect ( "/" ) ;
19
19
}
20
20
21
- let shardDetails ;
21
+ let shardDetails , userRole ;
22
22
if ( roomId === "new-room" ) {
23
23
if ( ! template || ! templates . includes ( template ) ) {
24
24
console . log ( "Template not valid" ) ;
@@ -33,36 +33,94 @@ export default async function CollaborativeRoomPage({ params, searchParams }) {
33
33
src : "createNewRoom()"
34
34
} , logFailureCb ) ;
35
35
36
- shardDetails = out . data . shards ;
36
+ shardDetails = out . data . shards ?. [ 0 ] ;
37
37
const files = out . data . files ;
38
38
console . log ( "shard details: " , shardDetails ) ;
39
39
console . log ( "files: " , files ) ;
40
40
shardDetails . files = files ;
41
+
42
+ const newRoomId = shardDetails ?. id ;
43
+
44
+ let roomMembersResponse = await fetchRoomMembers ( userId , newRoomId ) ;
45
+ if ( ! roomMembersResponse || roomMembersResponse ?. error || ! roomMembersResponse ?. data ) {
46
+ console . log ( "could not fetch room members: " + roomMembersResponse ) ;
47
+ if ( roomMembersResponse ?. error ) console . log ( "explicit error message: " + roomMembersResponse ?. error ?. message || "could not fetch room members" )
48
+ redirect ( "/" ) ;
49
+ }
50
+
51
+ console . log ( "members: " , roomMembersResponse . data ) ;
52
+ // Member type => [{id: number, userId: string, roomId: number, role : enum<'owner', 'editor', 'viewer'>}]
53
+ let members = roomMembersResponse . data . members ?? [ ] ;
54
+ const isOwner = members . some ( member => member . userId === userId && member . role === RoomRole . OWNER ) ;
55
+
56
+ if ( isOwner ) {
57
+ // user is already an owner of the room, redirect to the room
58
+ redirect ( `/room/${ newRoomId } ` ) ;
59
+ }
60
+ else {
61
+ // user is not an owner of the room, add them as an owner
62
+ const out = await inviteUserToRoom ( userId , newRoomId , user . primaryEmailAddress ?. emailAddress ?? "" , RoomRole . OWNER ) ;
63
+ if ( out ?. error ) {
64
+ console . log ( "error occurred in inviteUserToRoom: " , out ) ;
65
+ redirect ( "/" ) ;
66
+ }
67
+
68
+ userRole = RoomRole . OWNER ;
69
+ }
41
70
}
42
71
43
72
if ( roomId !== "new-room" ) {
44
73
let out = await fetchLatestRoomFilesState ( userId , roomId ) ;
45
74
if ( ! out || out ?. error || ! out ?. data ) {
46
75
console . log ( "could not fetch latest room state: " + out ) ;
47
76
if ( out ?. error ) console . log ( "explicit error message: " + out ?. error ?. message )
48
- redirect ( "/your-work " ) ;
77
+ redirect ( "/" ) ;
49
78
}
50
79
51
80
let data = out . data ;
52
81
shardDetails = data . shard ;
82
+
83
+ let roomMembersResponse = await fetchRoomMembers ( userId , roomId ) ;
84
+ if ( ! roomMembersResponse || roomMembersResponse ?. error || ! roomMembersResponse ?. data ) {
85
+ console . log ( "could not fetch room members: " + roomMembersResponse ) ;
86
+ if ( roomMembersResponse ?. error ) console . log ( "explicit error message: " + roomMembersResponse ?. error ?. message || "could not fetch room members" )
87
+ redirect ( "/" ) ;
53
88
}
54
89
55
- console . log ( "Shard details: " , shardDetails ) ;
90
+ console . log ( "members: " , roomMembersResponse . data ) ;
91
+ // Member type => [{id: number, userId: string, roomId: number, role : enum<'owner', 'editor', 'viewer'>}]
92
+ let members = roomMembersResponse . data . members ?? [ ] ;
93
+ const isMember = members . some ( member => member . userId === userId ) ;
56
94
57
- const { userId : creator , isTemplate, id } = shardDetails ;
95
+ if ( shardDetails ?. userId === userId && ! isMember ) {
96
+ // user is the creator of the room and not a member yet, add them as a "owner"
97
+ const out = await inviteUserToRoom ( userId , roomId , user . primaryEmailAddress ?. emailAddress ?? "" , RoomRole . OWNER ) ;
98
+ if ( out ?. error ) {
99
+ console . log ( "error occurred in inviteUserToRoom: " , out ) ;
100
+ redirect ( "/" ) ;
101
+ }
102
+ userRole = RoomRole . OWNER ;
103
+ }
104
+ else if ( ! isMember && shardDetails ?. userId !== userId ) {
105
+ // user is not a member of the room and is not the creator of the room, redirect to the home page
106
+ redirect ( "/" ) ;
107
+ }
108
+ else if ( isMember ) {
109
+ userRole = members . find ( member => member . userId === userId ) ?. role ?? 'undefined' ;
110
+ }
111
+ }
112
+
113
+ console . log ( "Shard details: " , shardDetails ) ;
114
+ console . log ( "User role: " , userRole ) ;
58
115
59
116
return (
60
117
< >
61
118
< CollaborativeSandpackEditor
62
119
shardDetails = { JSON . stringify ( shardDetails ) }
63
- template = { isTemplate ? shardDetails ?. templateType : "react" }
120
+ template = { shardDetails ?. templateType }
64
121
id = { shardDetails ?. id ?? "" }
65
122
isNewShard = { roomId === "new-room" }
123
+ userRole = { userRole }
66
124
/>
67
125
</ >
68
126
) ;
0 commit comments