frontend phase 15

This commit is contained in:
hamid
2026-07-10 20:28:06 +03:30
parent bc51cf59b4
commit 70cf00ce4a
151 changed files with 10711 additions and 44 deletions
@@ -0,0 +1,25 @@
import { useQuery } from '@tanstack/react-query';
import { ticketsApi } from '../apis';
import { ticketKeys } from '../keys';
import { TICKETS_GC_TIME, TICKET_THREAD_STALE_TIME } from '../constants';
import type { AdminTicketMessage } from '../types';
import { useTicketViewer } from './useTicketViewer';
/**
* Just the messages of an admin thread — a `select` over the same `adminDetail(id)` cache the admin header
* reads (mirrors `useTicketThread`). One network fetch feeds both; the message list re-renders on a new
* message without re-rendering the thread header. Because it is the admin view, the returned messages CARRY
* `isInternal` (internal-styled bubbles render here — they never do in the user thread). Optimistic admin
* sends mutate `adminDetail(id)`, so the list updates instantly.
*/
export function useAdminTicketThread(ticketId: number | null) {
const { userId } = useTicketViewer();
return useQuery({
queryKey: ticketKeys.adminDetail(ticketId ?? -1),
queryFn: () => ticketsApi.getAdminTicket(ticketId as number, userId),
enabled: ticketId != null && ticketId > 0,
staleTime: TICKET_THREAD_STALE_TIME,
gcTime: TICKETS_GC_TIME,
select: (detail): AdminTicketMessage[] => detail.messages,
});
}