feature: clinic & lab invitation flow added. minimal ui implemented for organizations tab.

This commit is contained in:
2026-05-05 19:50:07 +03:30
parent 43e39883a4
commit adfb5b436e
22 changed files with 1265 additions and 23 deletions

View File

@@ -0,0 +1,79 @@
import { apiClient } from './client';
export interface CounterpartSearchResultDto {
id: string;
name: string;
email: string;
phone: string | null;
owner: { email: string; name: string };
}
export interface CounterpartItemDto {
id: string;
kind: 'LINK' | 'INVITATION';
counterpartOrganizationId: string | null;
organizationName: string;
ownerEmail: string;
phone: string | null;
status: 'PENDING' | 'ACTIVE' | 'REJECTED' | 'EXPIRED';
invitationUrl: string | null;
createdAt: string;
acceptedAt: string | null;
}
export const organizationApi = {
search: async (q: string): Promise<{ success: boolean; data: CounterpartSearchResultDto[] }> => {
const response = await apiClient.get(`/organizations/search?q=${encodeURIComponent(q)}`);
return response.data;
},
list: async (): Promise<{ success: boolean; data: { items: CounterpartItemDto[] } }> => {
const response = await apiClient.get('/organizations/links');
return response.data;
},
createLink: async (
targetOrganizationId: string,
): Promise<{ success: boolean; data: { id: string; status: 'PENDING' | 'ACTIVE' | 'REJECTED' } }> => {
const response = await apiClient.post('/organizations/links', { targetOrganizationId });
return response.data;
},
invite: async (body: {
organizationName: string;
ownerEmail: string;
phone?: string;
}): Promise<{ success: boolean; data: { invitationId: string; invitationUrl: string; status: 'PENDING' } }> => {
const response = await apiClient.post('/organizations/invite', body);
return response.data;
},
previewInvite: async (
token: string,
): Promise<{
success: boolean;
data: {
ownerEmail: string;
organizationName: string;
organizationType: 'CLINIC' | 'LAB';
inviterOrganizationName: string;
expiresAt: string;
status: 'PENDING' | 'ACCEPTED';
};
}> => {
const response = await apiClient.get(
`/organizations/invitations/preview?token=${encodeURIComponent(token)}`,
);
return response.data;
},
acceptInvite: async (body: {
token: string;
organizationName: string;
ownerName: string;
password: string;
}): Promise<{ success: boolean; message: string; data: { organizationId: string } }> => {
const response = await apiClient.post('/organizations/invitations/accept', body);
return response.data;
},
};