diff --git a/apps/dashboard/src/features/conversations/conversation-api.ts b/apps/dashboard/src/features/conversations/conversation-api.ts index 44ed190..d81379b 100644 --- a/apps/dashboard/src/features/conversations/conversation-api.ts +++ b/apps/dashboard/src/features/conversations/conversation-api.ts @@ -3,6 +3,7 @@ import { ConversationsResponseSchema, ConversationDetailResponseSchema, ErrorResponseSchema, + ProcessedPostsResponseSchema, SendReplyRequestSchema, StartConversationRequestSchema, StartConversationResponseSchema, @@ -10,6 +11,7 @@ import { SuggestedReplyResponseSchema, type ActiveChat, type ConversationDetailResponse, + type ProcessedPost, type SuccessResponse, } from '../../../../../packages/api-contracts/src/index.js'; @@ -30,6 +32,8 @@ export interface ConversationApi { list(): Promise; detail(id: string): Promise; suggestReply(id: string): Promise; + suggestMediaAsk(id: string): Promise; + processedPosts(username: string): Promise; sendReply(id: string, message: string): Promise; startConversation(username: string, message: string): Promise; } @@ -53,6 +57,19 @@ export function createConversationApi(fetchImplementation?: typeof fetch): Conve ); return response.suggestedReply; }, + async suggestMediaAsk(id) { + const response = await parseResponse( + await request(`${conversationPath(id)}/suggest-media-ask`, { method: 'POST' }), + SuggestedReplyResponseSchema, + ); + return response.suggestedReply; + }, + async processedPosts(username) { + return parseResponse( + await request(`/api/posts/by-author/${encodeURIComponent(username.trim().replace(/^u\//i, ''))}`), + ProcessedPostsResponseSchema, + ); + }, async sendReply(id, message) { const body = SendReplyRequestSchema.parse({ message: message.trim() }); return parseResponse( diff --git a/apps/dashboard/src/features/conversations/conversation-detail.tsx b/apps/dashboard/src/features/conversations/conversation-detail.tsx index d29e2bd..d573153 100644 --- a/apps/dashboard/src/features/conversations/conversation-detail.tsx +++ b/apps/dashboard/src/features/conversations/conversation-detail.tsx @@ -1,6 +1,6 @@ import { useCallback, useRef, useState } from 'react'; import type { ConversationDetailResponse } from '../../../../../packages/api-contracts/src/index.js'; -import { useConversationDetailQuery, useSendReplyMutation, useSuggestReplyMutation } from './conversation-queries.js'; +import { useConversationDetailQuery, useSendReplyMutation, useSuggestMediaAskMutation, useSuggestReplyMutation } from './conversation-queries.js'; import { SendConfirmationDialog } from './send-confirmation-dialog.js'; interface ConversationDetailProps { @@ -38,6 +38,7 @@ function ConversationComposer({ conversation }: { conversation: ConversationDeta const [wasSent, setWasSent] = useState(false); const sendButtonRef = useRef(null); const suggestionMutation = useSuggestReplyMutation(conversation.roomId ?? conversation.username); + const mediaAskMutation = useSuggestMediaAskMutation(conversation.roomId ?? conversation.username); const sendMutation = useSendReplyMutation(conversation.roomId ?? conversation.username); const canSend = draft.trim().length > 0 && !sendMutation.isPending; @@ -51,6 +52,11 @@ function ConversationComposer({ conversation }: { conversation: ConversationDeta suggestionMutation.mutate(undefined, { onSuccess: (suggestion) => setDraft(suggestion) }); } + function suggestMediaAsk() { + setWasSent(false); + mediaAskMutation.mutate(undefined, { onSuccess: (suggestion) => setDraft(suggestion) }); + } + function sendReply() { if (!canSend) return; sendMutation.mutate(draft, { @@ -69,6 +75,9 @@ function ConversationComposer({ conversation }: { conversation: ConversationDeta +