Skip to content

Commit 3575220

Browse files
committed
feat: add member role display to ProfileCard component and fetch member role on mount.
1 parent ec22660 commit 3575220

2 files changed

Lines changed: 99 additions & 12 deletions

File tree

src/action/workspace.action.ts

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import type { NewWorkspaceFormSchema } from "@/lib/form/new-workspace-form";
1010
import type { z } from "zod";
1111
import { canDeleteWorkspace } from "@/lib/workspace-auth";
1212
import { getCurrentUser } from "@/lib/session";
13+
import type { userRole } from "@/types";
1314

1415
type NewWorkspaceFormSchemaType = z.infer<typeof NewWorkspaceFormSchema>;
1516

1617
export async function createWorkspace(
17-
workspaceData: NewWorkspaceFormSchemaType,
18+
workspaceData: NewWorkspaceFormSchemaType
1819
) {
1920
try {
2021
const response = await auth.api.createOrganization({
@@ -48,7 +49,7 @@ export async function createWorkspace(
4849
*/
4950
export async function updateWorkspace(
5051
workspaceId: string,
51-
data: { name?: string; slug?: string },
52+
data: { name?: string; slug?: string }
5253
): Promise<APIResponse<{ name: string; slug: string }>> {
5354
try {
5455
// Use better-auth's API to update the organization
@@ -109,8 +110,8 @@ export async function getWorkspaceUsers(workspaceId: string) {
109110
.where(
110111
and(
111112
eq(membersTable.userId, authUser.id),
112-
eq(membersTable.workspaceId, workspaceId),
113-
),
113+
eq(membersTable.workspaceId, workspaceId)
114+
)
114115
)
115116
.execute();
116117

@@ -152,8 +153,8 @@ export async function validateWorkspaceAccess(workspaceId: string) {
152153
.where(
153154
and(
154155
eq(membersTable.userId, authUser.id),
155-
eq(membersTable.workspaceId, workspaceId),
156-
),
156+
eq(membersTable.workspaceId, workspaceId)
157+
)
157158
)
158159
.execute();
159160

@@ -211,7 +212,7 @@ export async function getAllWorkspaces() {
211212
workspaceId: membersTable.workspaceId,
212213
})
213214
.from(membersTable)
214-
.where(eq(membersTable.userId, user.id ?? "")),
215+
.where(eq(membersTable.userId, user.id ?? ""))
215216
),
216217
});
217218

@@ -222,7 +223,7 @@ export async function getAllWorkspaces() {
222223
export async function updateUserRole(
223224
userId: string,
224225
workspaceId: string,
225-
role: userRole,
226+
role: userRole
226227
): Promise<APIResponse<{ role: string }>> {
227228
try {
228229
const updatedMember = await db
@@ -231,8 +232,8 @@ export async function updateUserRole(
231232
.where(
232233
and(
233234
eq(membersTable.userId, userId),
234-
eq(membersTable.workspaceId, workspaceId),
235-
),
235+
eq(membersTable.workspaceId, workspaceId)
236+
)
236237
)
237238
.returning();
238239

@@ -310,3 +311,74 @@ export async function setWorkspaceFromDB() {
310311
};
311312
}
312313
}
314+
315+
export async function getWorkspaceUserRole(workspaceSlug: string) {
316+
try {
317+
const authUser = await getCurrentAuthUser();
318+
if (!authUser) {
319+
return {
320+
error: "User not authenticated",
321+
success: false,
322+
};
323+
}
324+
const org = await auth.api.getActiveMemberRole({
325+
query: {
326+
userId: authUser.id,
327+
organizationSlug: workspaceSlug,
328+
},
329+
headers: await headers(),
330+
});
331+
332+
if (!org || !org.role) {
333+
return {
334+
error: "Failed to retrieve user role",
335+
success: false,
336+
};
337+
}
338+
339+
return org.role;
340+
} catch (error: unknown) {
341+
return {
342+
error: `Failed to get user role:\n ${error}`,
343+
success: false,
344+
};
345+
}
346+
}
347+
348+
/**
349+
* Delete a workspace
350+
* Only owners can delete workspaces
351+
*/
352+
export async function deleteWorkspace(
353+
workspaceId: string
354+
): Promise<APIResponse<{ deleted: boolean }>> {
355+
try {
356+
// Check if user has permission to delete
357+
const permission = await canDeleteWorkspace();
358+
359+
if (!permission.allowed) {
360+
return {
361+
error:
362+
"You don't have permission to delete this workspace. Only owners can delete workspaces.",
363+
success: false,
364+
};
365+
}
366+
367+
// Use better-auth's API to delete the organization
368+
await auth.api.deleteOrganization({
369+
headers: await headers(),
370+
body: {
371+
organizationId: workspaceId,
372+
},
373+
});
374+
375+
return { data: { deleted: true }, success: true };
376+
} catch (error: unknown) {
377+
const message =
378+
error instanceof Error ? error.message : "An unknown error occurred";
379+
return {
380+
error: `Failed to delete workspace: ${message}`,
381+
success: false,
382+
};
383+
}
384+
}

src/components/ProfileCard.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"use client";
22
import Image from "next/image";
33
import { authClient, useSession } from "@/lib/auth-client";
4-
import { useWorkspaceStore } from "@/store/workspace";
54
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
65
import { useEffect, useState } from "react";
76

@@ -13,10 +12,21 @@ type org = {
1312
const ProfileCard = () => {
1413
const { data: session } = useSession();
1514
const [org, setOrg] = useState<org>({});
15+
const [memberRole, setMemberRole] = useState<{ role?: string }>({});
16+
17+
useEffect(() => {
18+
const fetchMember = async () => {
19+
const result = await authClient.organization.getActiveMemberRole();
20+
if (result.data) {
21+
setMemberRole({ role: result.data.role });
22+
}
23+
};
24+
fetchMember();
25+
}, []);
26+
1627
useEffect(() => {
1728
const fetchOrg = async () => {
1829
const orgData = await authClient.organization.getFullOrganization();
19-
console.log(orgData.data);
2030
setOrg({ data: orgData.data });
2131
};
2232
fetchOrg();
@@ -50,6 +60,11 @@ const ProfileCard = () => {
5060
Team: {org?.data?.name}
5161
</p>
5262
)}
63+
{memberRole && (
64+
<p className="text-white/75 mt-2.5 text-xs xl:text-lg">
65+
Role: {memberRole?.role}
66+
</p>
67+
)}
5368
</div>
5469
</div>
5570
<div className="flex flex-col gap-2 px-2 items-start justify-center">

0 commit comments

Comments
 (0)