1"use client";
2
3
22import { useMutation, useQueryClient } from "@tanstack/react-query";
23import { apiFetch } from "@/lib/api";
24
25
27export const ASSIGNABLE_ROLES = ["ADMIN", "MEMBER", "GUEST"] as const;
28export type AssignableRole = (typeof ASSIGNABLE_ROLES)[number];
29
30export const ROLE_LABELS: Record<string, string> = {
31 OWNER: "Owner",
32 ADMIN: "Admin",
33 MEMBER: "Member",
34 GUEST: "Guest"
35};
36
37
38export function roleLabel(role: string): string {
39 if (!role) return role;
40 const key = role.toUpperCase();
41 return ROLE_LABELS[key] ?? key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
42}
43
44export interface UseMembersArgs {
45 workspaceId: string;
46}
47
48
49export function useUpdateMemberRole({ workspaceId }: UseMembersArgs) {
50 const qc = useQueryClient();
51 return useMutation({
52 mutationFn: async (input: { userId: string; role: AssignableRole }): Promise<void> => {
53 await apiFetch(`/workspaces/${workspaceId}/members/${input.userId}`, {
54 method: "PATCH",
55 body: { role: input.role }
56 });
57 },
58 onSuccess: () => {
59 qc.invalidateQueries({ queryKey: ["workspaces", workspaceId, "members"] });
60 }
61 });
62}
63
64
65export function useRemoveMember({ workspaceId }: UseMembersArgs) {
66 const qc = useQueryClient();
67 return useMutation({
68 mutationFn: async (userId: string): Promise<void> => {
69 await apiFetch(`/workspaces/${workspaceId}/members/${userId}`, { method: "DELETE" });
70 },
71 onSuccess: () => {
72 qc.invalidateQueries({ queryKey: ["workspaces", workspaceId, "members"] });
73 }
74 });
75}
76
77
78export function useInviteMember({ workspaceId }: UseMembersArgs) {
79 const qc = useQueryClient();
80 return useMutation({
81 mutationFn: async (input: { email: string; role: AssignableRole }): Promise<void> => {
82 await apiFetch(`/workspaces/${workspaceId}/members/invites`, {
83 method: "POST",
84 body: { email: input.email, role: input.role }
85 });
86 },
87 onSuccess: () => {
88
89
90 qc.invalidateQueries({ queryKey: ["workspaces", workspaceId] });
91 }
92 });
93}
94