'use client' import { useQuery, useQueryClient, keepPreviousData } from '@tanstack/react-query' import { apiClient, OfflineError } from '../client' import type { PaginatedResponse, ApiMessageSummary, ApiMessageFull, ApiMailAccount, MessageSearchFilter, } from '../types' export function useMessages(folder: string, accountId?: string, page?: number) { return useQuery({ queryKey: ['messages', folder, accountId, page], queryFn: () => apiClient.get>('/mail/messages', { folder, account_id: accountId, page: String(page ?? 1), page_size: '50', }), placeholderData: keepPreviousData, staleTime: 60_000, }) } export function useMessage(messageId: string | null) { return useQuery({ queryKey: ['message', messageId], queryFn: () => apiClient.get(`/mail/messages/${messageId}`), enabled: !!messageId, }) } export function useThread(threadId: string | null) { return useQuery({ queryKey: ['thread', threadId], queryFn: () => apiClient.get(`/mail/threads/${threadId}`), enabled: !!threadId, }) } export function useMailAccounts() { return useQuery({ queryKey: ['accounts'], queryFn: () => apiClient.get('/mail/accounts'), staleTime: 5 * 60_000, }) } export function useMailSearch(filter: MessageSearchFilter | null) { const queryClient = useQueryClient() return useQuery({ queryKey: ['mail-search', filter], queryFn: async () => { const params: Record = {} if (filter) { if (filter.q) params.q = filter.q if (filter.from) params.from = filter.from if (filter.label) params.label = filter.label if (filter.account_id) params.account_id = filter.account_id if (filter.date_from) params.date_from = filter.date_from if (filter.date_to) params.date_to = filter.date_to if (filter.has_attachment !== undefined) params.has_attachment = String(filter.has_attachment) } try { return await apiClient.get>('/mail/search', params) } catch (err) { if (err instanceof OfflineError) { const cached = queryClient.getQueriesData>({ queryKey: ['messages'], }) const allMessages: ApiMessageSummary[] = [] for (const [, data] of cached) { if (data?.data) allMessages.push(...data.data) } const q = filter?.q?.toLowerCase() const filtered = allMessages.filter((m) => { if (q) { const matchSubject = m.subject.toLowerCase().includes(q) const matchSnippet = m.snippet.toLowerCase().includes(q) const matchFrom = m.from.some( (r) => r.address.toLowerCase().includes(q) || r.name.toLowerCase().includes(q) ) if (!matchSubject && !matchSnippet && !matchFrom) return false } if (filter?.from) { const fromMatch = m.from.some( (r) => r.address.toLowerCase().includes(filter.from!.toLowerCase()) || r.name.toLowerCase().includes(filter.from!.toLowerCase()) ) if (!fromMatch) return false } if (filter?.label) { if (!m.labels.includes(filter.label)) return false } return true }) return { data: filtered, pagination: { page: 1, page_size: filtered.length } } } throw err } }, enabled: !!(filter?.q || filter?.from || filter?.label), }) }