React hooks for managing collaborators on goals, including adding, updating roles, and removing collaborators.
useCollaborators
Fetch all collaborators for a goal.
const { data, isLoading, error } = useCollaborators(goalId)
Parameters
The ID of the goal to fetch collaborators for
Returns
Array of collaborators with user information included
Loading state of the query
Error object if the query failed
Example
import { useCollaborators } from '@features/goals/api/use-collaborators'
function CollaboratorsList({ goalId }: { goalId: string }) {
const { data: collaborators, isLoading } = useCollaborators(goalId)
if (isLoading) return <div>Loading...</div>
return (
<ul>
{collaborators?.map((collab) => (
<li key={collab.user_id}>
{collab.user.email} - {collab.role}
</li>
))}
</ul>
)
}
useAddCollaborator
Add a new collaborator to a goal by email.
const { mutate, mutateAsync, isPending } = useAddCollaborator()
Returns
mutate
(params: AddCollaboratorParams) => void
Function to add a collaborator
mutateAsync
(params: AddCollaboratorParams) => Promise<Collaborator>
Async function to add a collaborator and await the result
Loading state of the mutation
Parameters
The ID of the goal to add the collaborator to
The email address of the user to add as a collaborator
The role to assign to the collaborator. Possible values: 'viewer', 'editor', 'admin'
Example
import { useAddCollaborator } from '@features/goals/api/use-collaborators'
function AddCollaboratorForm({ goalId }: { goalId: string }) {
const { mutate: addCollaborator, isPending } = useAddCollaborator()
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
addCollaborator({
goalId,
email: formData.get('email') as string,
role: formData.get('role') as CollaboratorRole,
})
}
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<select name="role" required>
<option value="viewer">Viewer</option>
<option value="editor">Editor</option>
<option value="admin">Admin</option>
</select>
<button disabled={isPending}>Add Collaborator</button>
</form>
)
}
useUpdateCollaboratorRole
Update the role of an existing collaborator.
const { mutate, mutateAsync, isPending } = useUpdateCollaboratorRole()
Returns
mutate
(params: UpdateRoleParams) => void
Function to update a collaborator’s role
mutateAsync
(params: UpdateRoleParams) => Promise<void>
Async function to update a collaborator’s role and await completion
Loading state of the mutation
Parameters
The ID of the user whose role to update
The new role to assign. Possible values: 'viewer', 'editor', 'admin'
Example
import { useUpdateCollaboratorRole } from '@features/goals/api/use-collaborators'
function CollaboratorRoleSelect({
goalId,
userId,
currentRole,
}: {
goalId: string
userId: string
currentRole: string
}) {
const { mutate: updateRole } = useUpdateCollaboratorRole()
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
updateRole({
goalId,
userId,
role: e.target.value as CollaboratorRole,
})
}
return (
<select value={currentRole} onChange={handleChange}>
<option value="viewer">Viewer</option>
<option value="editor">Editor</option>
<option value="admin">Admin</option>
</select>
)
}
useRemoveCollaborator
Remove a collaborator from a goal.
const { mutate, mutateAsync, isPending } = useRemoveCollaborator()
Returns
mutate
(params: RemoveCollaboratorParams) => void
Function to remove a collaborator
mutateAsync
(params: RemoveCollaboratorParams) => Promise<void>
Async function to remove a collaborator and await completion
Loading state of the mutation
Parameters
The ID of the user to remove as a collaborator
Example
import { useRemoveCollaborator } from '@features/goals/api/use-collaborators'
function RemoveCollaboratorButton({
goalId,
userId,
}: {
goalId: string
userId: string
}) {
const { mutate: removeCollaborator, isPending } = useRemoveCollaborator()
const handleRemove = () => {
if (confirm('Remove this collaborator?')) {
removeCollaborator({ goalId, userId })
}
}
return (
<button onClick={handleRemove} disabled={isPending}>
Remove
</button>
)
}