diff --git a/frontend/src/components/source/SourceDetailContent.tsx b/frontend/src/components/source/SourceDetailContent.tsx index e7ccf90..fe350ac 100644 --- a/frontend/src/components/source/SourceDetailContent.tsx +++ b/frontend/src/components/source/SourceDetailContent.tsx @@ -164,7 +164,8 @@ export function SourceDetailContent({ } } - const handleDeleteInsight = async () => { + const handleDeleteInsight = async (e?: React.MouseEvent) => { + e?.preventDefault() if (!insightToDelete) return try { @@ -780,6 +781,12 @@ export function SourceDetailContent({ } }} insight={selectedInsight ?? undefined} + onDelete={async (insightId) => { + await insightsApi.delete(insightId) + toast.success('Insight deleted successfully') + setSelectedInsight(null) + await fetchInsights() + }} /> setInsightToDelete(null)}> @@ -792,12 +799,14 @@ export function SourceDetailContent({ Cancel - - {deletingInsight ? 'Deleting...' : 'Delete'} + + diff --git a/frontend/src/components/source/SourceInsightDialog.tsx b/frontend/src/components/source/SourceInsightDialog.tsx index 6103e7d..d7ded43 100644 --- a/frontend/src/components/source/SourceInsightDialog.tsx +++ b/frontend/src/components/source/SourceInsightDialog.tsx @@ -1,7 +1,10 @@ 'use client' -import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' +import { useState, useEffect } from 'react' +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog' import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { Trash2 } from 'lucide-react' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import { useInsight } from '@/lib/hooks/use-insights' @@ -15,9 +18,13 @@ interface SourceInsightDialogProps { content?: string created?: string } + onDelete?: (insightId: string) => Promise } -export function SourceInsightDialog({ open, onOpenChange, insight }: SourceInsightDialogProps) { +export function SourceInsightDialog({ open, onOpenChange, insight, onDelete }: SourceInsightDialogProps) { + const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) + const [isDeleting, setIsDeleting] = useState(false) + // Ensure insight ID has 'source_insight:' prefix for API calls const insightIdWithPrefix = insight?.id ? (insight.id.includes(':') ? insight.id : `source_insight:${insight.id}`) @@ -28,49 +35,108 @@ export function SourceInsightDialog({ open, onOpenChange, insight }: SourceInsig // Use fetched data if available, otherwise fall back to passed-in insight const displayInsight = fetchedInsight ?? insight + // Reset delete state when dialog closes + useEffect(() => { + if (!open) { + setShowDeleteConfirm(false) + setIsDeleting(false) + } + }, [open]) + + const handleDelete = async () => { + if (!insight?.id || !onDelete) return + + try { + setIsDeleting(true) + await onDelete(insight.id) + // Parent's onDelete callback handles closing the dialog via setSelectedInsight(null) + } catch { + // Only reset state if delete failed - dialog stays open + setShowDeleteConfirm(false) + setIsDeleting(false) + } + } + return ( Source Insight - {displayInsight?.insight_type && ( - - {displayInsight.insight_type} - - )} +
+ {displayInsight?.insight_type && ( + + {displayInsight.insight_type} + + )} + {onDelete && insight?.id && !showDeleteConfirm && ( + + )} +
-
- {isLoading ? ( -
- Loading insight… -
- ) : displayInsight ? ( -
- ( -
- {children}
-
- ), - thead: ({ children }) => {children}, - tbody: ({ children }) => {children}, - tr: ({ children }) => {children}, - th: ({ children }) => {children}, - td: ({ children }) => {children}, - }} + {showDeleteConfirm ? ( +
+

+ Are you sure you want to delete this insight?
+ This action cannot be undone. +

+
+ +
- ) : ( -

No insight selected.

- )} -
+
+ ) : ( +
+ {isLoading ? ( +
+ Loading insight… +
+ ) : displayInsight ? ( +
+ ( +
+ {children}
+
+ ), + thead: ({ children }) => {children}, + tbody: ({ children }) => {children}, + tr: ({ children }) => {children}, + th: ({ children }) => {children}, + td: ({ children }) => {children}, + }} + > + {displayInsight.content} +
+
+ ) : ( +

No insight selected.

+ )} +
+ )}
)