import { useApi } from '@/composables/useApi' import type { LinkableUser } from '@/lib/directoryTypes' export type UserListItem = | { kind: 'user' id: number username: string display_name: string email: string role: 'owner' | 'admin' status: 'accepted' created_at: string } | { kind: 'invite' id: number email: string display_name?: string status: 'pending' | 'expired' created_at: string } export const USER_SKELETON_ROWS = 5 export function userRowKey(kind: UserListItem['kind'], id: number) { return `${kind}-${id}` } export function userDisplayName(item: UserListItem) { return item.display_name ?? '' } export function userRole(item: UserListItem): 'owner' | 'admin' { return item.kind === 'user' ? item.role : 'admin' } export interface CreatedInvite { id: number kind: 'invite' email: string status: 'pending' created_at: string expires_at: string } export function useUsers() { const { request } = useApi() function listUsers(): Promise { return request('/v1/user/') } async function listLinkableUsers( takenUserIds: ReadonlySet, ): Promise { const users = await listUsers() return users.flatMap((user) => user.kind === 'user' && !takenUserIds.has(user.id) ? [ { id: user.id, label: user.display_name || user.username, email: user.email, }, ] : [], ) } function inviteUser(email: string): Promise { return request('/v1/user/invite', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }) } function cancelInvite(id: number): Promise { return request(`/v1/user/invite/${id}`, { method: 'DELETE' }) } function renewInvite(id: number): Promise { return request(`/v1/user/invite/${id}/renew`, { method: 'POST', }) } return { listUsers, listLinkableUsers, inviteUser, cancelInvite, renewInvite, } }