diff --git a/frontend/src/components/source/SourceDetailContent.tsx b/frontend/src/components/source/SourceDetailContent.tsx index 7e966c5..8757141 100644 --- a/frontend/src/components/source/SourceDetailContent.tsx +++ b/frontend/src/components/source/SourceDetailContent.tsx @@ -24,6 +24,16 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from '@/components/ui/alert-dialog' import { Select, SelectContent, @@ -80,6 +90,8 @@ export function SourceDetailContent({ const [isDownloadingFile, setIsDownloadingFile] = useState(false) const [fileAvailable, setFileAvailable] = useState(null) const [selectedInsight, setSelectedInsight] = useState(null) + const [insightToDelete, setInsightToDelete] = useState(null) + const [deletingInsight, setDeletingInsight] = useState(false) const fetchSource = useCallback(async () => { try { @@ -152,6 +164,24 @@ export function SourceDetailContent({ } } + const handleDeleteInsight = async (e?: React.MouseEvent) => { + e?.preventDefault() + if (!insightToDelete) return + + try { + setDeletingInsight(true) + await insightsApi.delete(insightToDelete) + toast.success('Insight deleted successfully') + setInsightToDelete(null) + await fetchInsights() + } catch (err) { + console.error('Failed to delete insight:', err) + toast.error('Failed to delete insight') + } finally { + setDeletingInsight(false) + } + } + const handleUpdateTitle = async (title: string) => { if (!source || title === source.title) return @@ -573,10 +603,18 @@ export function SourceDetailContent({

{insight.content.slice(0, 180)}{insight.content.length > 180 ? '…' : ''}

-
+
+
))} @@ -743,7 +781,41 @@ export function SourceDetailContent({ } }} insight={selectedInsight ?? undefined} + onDelete={async (insightId) => { + try { + await insightsApi.delete(insightId) + toast.success('Insight deleted successfully') + setSelectedInsight(null) + await fetchInsights() + } catch (err) { + console.error('Failed to delete insight:', err) + toast.error('Failed to delete insight') + } + }} /> + + setInsightToDelete(null)}> + + + Delete Insight? + + This action cannot be undone. This insight will be permanently deleted. + + + + Cancel + + + + + + ) } diff --git a/frontend/src/components/source/SourceInsightDialog.tsx b/frontend/src/components/source/SourceInsightDialog.tsx index 9946277..1ff3ad5 100644 --- a/frontend/src/components/source/SourceInsightDialog.tsx +++ b/frontend/src/components/source/SourceInsightDialog.tsx @@ -1,6 +1,7 @@ '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 { FileText } from 'lucide-react' @@ -19,6 +20,7 @@ interface SourceInsightDialogProps { created?: string source_id?: string } + onDelete?: (insightId: string) => Promise } export function SourceInsightDialog({ open, onOpenChange, insight }: SourceInsightDialogProps) { @@ -70,35 +72,60 @@ export function SourceInsightDialog({ open, onOpenChange, insight }: SourceInsig -
- {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.

+ )} +
+ )} ) diff --git a/frontend/src/lib/api/insights.ts b/frontend/src/lib/api/insights.ts index d59f854..1f6677c 100644 --- a/frontend/src/lib/api/insights.ts +++ b/frontend/src/lib/api/insights.ts @@ -30,5 +30,9 @@ export const insightsApi = { data ) return response.data + }, + + delete: async (insightId: string) => { + await apiClient.delete(`/insights/${insightId}`) } } \ No newline at end of file