From 8644f1923c5c4cc5213de6c8ee5a85e2630cdf8b Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Thu, 18 Dec 2025 18:04:41 -0500 Subject: [PATCH] feat: add delete insight functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ability to delete insights from sources with a confirmation dialog. Uses AlertDialog component for a native React experience instead of browser confirm(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../components/source/SourceDetailContent.tsx | 60 ++++++++++++++++++- frontend/src/lib/api/insights.ts | 4 ++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/source/SourceDetailContent.tsx b/frontend/src/components/source/SourceDetailContent.tsx index 7e966c5..e7ccf90 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,23 @@ export function SourceDetailContent({ } } + const handleDeleteInsight = async () => { + 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 +602,18 @@ export function SourceDetailContent({

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

-
+
+
))} @@ -744,6 +781,27 @@ export function SourceDetailContent({ }} insight={selectedInsight ?? undefined} /> + + setInsightToDelete(null)}> + + + Delete Insight? + + This action cannot be undone. This insight will be permanently deleted. + + + + Cancel + + {deletingInsight ? 'Deleting...' : 'Delete'} + + + + ) } 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