Files
temetro/frontend/lib/messages.ts
T
Khalid Abdi 730e07fcfc feat: real-time staff messaging over Socket.io
Add conversations/participants/messages tables, a participant-scoped REST
API (/api/conversations) and a Socket.io server (session-authenticated
handshake; per-user + per-conversation rooms) sharing the HTTP port. New
messages broadcast live and create per-recipient notifications. Also lands
the notifications table + service + routes (used by the message flow). The
Messages page is rewritten: live threads, unread state, and a compose
dialog to start a conversation with a clinic member.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 21:26:28 +03:00

70 lines
1.7 KiB
TypeScript

import { apiFetch } from "@/lib/api-client";
// Messaging shapes. Mirror the backend `src/types/messaging.ts`.
export type Participant = {
id: string;
name: string;
};
export type ConversationMessage = {
id: string;
conversationId: string;
senderId: string;
senderName: string;
body: string;
createdAt: string;
};
export type ConversationSummary = {
id: string;
name: string;
isGroup: boolean;
participants: Participant[];
lastMessage: ConversationMessage | null;
unread: boolean;
updatedAt: string;
};
export function listConversations(): Promise<ConversationSummary[]> {
return apiFetch<ConversationSummary[]>("/api/conversations");
}
export function listClinicMembers(): Promise<Participant[]> {
return apiFetch<Participant[]>("/api/conversations/members");
}
export function createConversation(input: {
participantIds: string[];
name?: string | null;
}): Promise<ConversationSummary> {
return apiFetch<ConversationSummary>("/api/conversations", {
method: "POST",
body: JSON.stringify(input),
});
}
export function getMessages(
conversationId: string,
): Promise<ConversationMessage[]> {
return apiFetch<ConversationMessage[]>(
`/api/conversations/${conversationId}/messages`,
);
}
// REST fallback for sending (the realtime path is the socket "message:send").
export function sendMessageRest(
conversationId: string,
body: string,
): Promise<ConversationMessage> {
return apiFetch<ConversationMessage>(
`/api/conversations/${conversationId}/messages`,
{ method: "POST", body: JSON.stringify({ body }) },
);
}
export function markConversationRead(conversationId: string): Promise<void> {
return apiFetch<void>(`/api/conversations/${conversationId}/read`, {
method: "POST",
});
}