Files
dyolink/frontend/src/lib/api/staff.ts

170 lines
4.4 KiB
TypeScript

import { apiClient } from './client';
import { getClientTimeZone } from '@/lib/i18n/clientTimeZone';
export interface StaffMemberDto {
id: string;
userId: string;
email: string;
name: string;
isOwner: boolean;
isActive: boolean;
invitationStatus: 'ACTIVE' | 'PENDING' | 'EXPIRED' | 'DISABLED';
invitedAt: string | null;
acceptedAt: string | null;
hasPassword: boolean;
permissions: string[] | null;
}
export interface StaffListResponse {
success: boolean;
data: {
members: StaffMemberDto[];
seats: {
used: number;
limit: number | null;
unlimited: boolean;
};
};
}
export interface InviteStaffResponse {
success: boolean;
data: {
membershipId: string;
userId: string;
email: string;
invitationId: string | null;
invitationUrl: string | null;
invitationStatus: 'PENDING' | 'ACCEPTED';
};
}
export interface PreviewInviteResponse {
success: boolean;
data: {
email: string;
name: string;
organizationName: string;
expiresAt: string;
status: 'PENDING' | 'ACCEPTED';
mode: 'join' | 'password_setup';
};
}
export const staffApi = {
list: async (): Promise<StaffListResponse> => {
const response = await apiClient.get('/staff');
return response.data;
},
invite: async (body: {
email: string;
name: string;
permissionNames: string[];
}): Promise<InviteStaffResponse> => {
const response = await apiClient.post('/staff/invite', body);
return response.data;
},
getInvitationLink: async (
membershipId: string,
): Promise<{
success: boolean;
data: {
membershipId: string;
invitationId: string;
email: string;
invitationUrl: string;
};
}> => {
const response = await apiClient.post(`/staff/members/${membershipId}/invitation-link`);
return response.data;
},
clearPassword: async (
membershipId: string,
): Promise<{
success: boolean;
data: {
membershipId: string;
invitationId: string;
email: string;
invitationUrl: string;
};
}> => {
const response = await apiClient.post(`/staff/members/${membershipId}/clear-password`);
return response.data;
},
previewInvite: async (token: string): Promise<PreviewInviteResponse> => {
const response = await apiClient.get(`/staff/invitations/preview?token=${encodeURIComponent(token)}`);
return response.data;
},
acceptInvite: async (body: {
token: string;
password: string;
name: string;
}): Promise<{ success: boolean; message: string; data: { email: string } }> => {
const response = await apiClient.post('/staff/invitations/accept', body);
return response.data;
},
updateMember: async (
membershipId: string,
body: { name?: string; permissionNames?: string[] },
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.patch(`/staff/members/${membershipId}`, body);
return response.data;
},
disableMember: async (
membershipId: string,
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.patch(`/staff/members/${membershipId}/disable`);
return response.data;
},
enableMember: async (
membershipId: string,
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.patch(`/staff/members/${membershipId}/enable`);
return response.data;
},
removeMember: async (
membershipId: string,
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.delete(`/staff/members/${membershipId}`);
return response.data;
},
getWorkingHours: async (
membershipId: string,
): Promise<{
success: boolean;
data: {
autoRepeatWeekly: boolean;
blocks: { dayOfWeek: number; startMinute: number; endMinute: number; sortOrder?: number }[];
hasWorkingHours: boolean;
};
}> => {
const response = await apiClient.get(`/staff/members/${membershipId}/working-hours`);
return response.data;
},
upsertWorkingHours: async (
membershipId: string,
body: {
autoRepeatWeekly: boolean;
blocks: { dayOfWeek: number; startMinute: number; endMinute: number; sortOrder?: number }[];
},
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.put(`/staff/members/${membershipId}/working-hours`, {
...body,
timeZone: getClientTimeZone(),
});
return response.data;
},
};