170 lines
4.4 KiB
TypeScript
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;
|
|
},
|
|
};
|