Files
temetro/frontend/lib/messages.ts
T
Khalid Abdi 91e4f4ed30 frontend: messages visual polish
Same layout, better inbox: avatars on conversation rows, a numeric unread
badge (kept live by the socket handler), primary-tinted timestamps for unread
rows and softer hover states. In the thread: day separators
(Today/Yesterday/date), consecutive same-sender messages within 5 minutes
grouped with one sender label + one timestamp and tightened corners, and a
"Start a conversation" button on the empty state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 21:04:12 +03:00

72 lines
1.8 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;
// Messages from others newer than the caller's read pointer.
unreadCount: number;
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",
});
}