diff --git a/frontend/src/hooks/useAnalysis.ts b/frontend/src/hooks/useAnalysis.ts
index 87425c9..c3249c3 100644
--- a/frontend/src/hooks/useAnalysis.ts
+++ b/frontend/src/hooks/useAnalysis.ts
@@ -1,5 +1,5 @@
-import { useQuery } from "@tanstack/react-query";
-import { getAnalysis, getAnalysisStatus } from "../api/analysis";
+import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
+import { getAnalysis, getAnalysisStatus, deleteAnalysis } from "../api/analysis";
import type { AnalysisDetail, AnalysisStatus } from "../types/analysis";
export function useAnalysis(analysisId: string | undefined) {
@@ -10,6 +10,17 @@ export function useAnalysis(analysisId: string | undefined) {
});
}
+export function useDeleteAnalysis() {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (analysisId: string) => deleteAnalysis(analysisId),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["projects"] });
+ queryClient.invalidateQueries({ queryKey: ["project"] });
+ },
+ });
+}
+
export function useAnalysisStatus(
analysisId: string | undefined,
enabled: boolean = true,
diff --git a/frontend/src/pages/AnalysisView.tsx b/frontend/src/pages/AnalysisView.tsx
index b83596a..ed30893 100644
--- a/frontend/src/pages/AnalysisView.tsx
+++ b/frontend/src/pages/AnalysisView.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
-import { useParams } from "react-router-dom";
-import { useAnalysis } from "../hooks/useAnalysis";
+import { useParams, useNavigate } from "react-router-dom";
+import { useAnalysis, useDeleteAnalysis } from "../hooks/useAnalysis";
import { useAnalysisStore, type AnalysisTab } from "../stores/analysisStore";
import { getAnalysisImageUrl, checkAIInsightsAvailable, generateAIInsights } from "../api/analysis";
import type { Insight } from "../types/analysis";
@@ -125,7 +125,9 @@ const tabs: { key: AnalysisTab; label: string }[] = [
export default function AnalysisView() {
const { analysisId } = useParams<{ analysisId: string }>();
+ const navigate = useNavigate();
const { data: analysis, isLoading, error } = useAnalysis(analysisId);
+ const deleteAnalysisMutation = useDeleteAnalysis();
const activeTab = useAnalysisStore((s) => s.activeTab);
const setActiveTab = useAnalysisStore((s) => s.setActiveTab);
const setCurrentAnalysis = useAnalysisStore((s) => s.setCurrentAnalysis);
@@ -180,6 +182,13 @@ export default function AnalysisView() {
};
}, [analysis, setCurrentAnalysis, reset]);
+ const handleDeleteAnalysis = async () => {
+ if (!analysisId) return;
+ if (!window.confirm("Are you sure you want to delete this analysis? This cannot be undone.")) return;
+ await deleteAnalysisMutation.mutateAsync(analysisId);
+ navigate(-1);
+ };
+
const handleDownloadPdf = async () => {
if (!analysisId) return;
try {
@@ -241,6 +250,13 @@ export default function AnalysisView() {
)}
+
diff --git a/frontend/src/pages/ProjectDetail.tsx b/frontend/src/pages/ProjectDetail.tsx
index 70359f8..4feaf67 100644
--- a/frontend/src/pages/ProjectDetail.tsx
+++ b/frontend/src/pages/ProjectDetail.tsx
@@ -1,5 +1,7 @@
+import { useState } from "react";
import { useParams, Link, useNavigate } from "react-router-dom";
import { useProject, useDeleteProject } from "../hooks/useProjects";
+import { useDeleteAnalysis } from "../hooks/useAnalysis";
import { getAnalysisImageUrl } from "../api/analysis";
import Card from "../components/common/Card";
import Button from "../components/common/Button";
@@ -10,6 +12,20 @@ export default function ProjectDetail() {
const navigate = useNavigate();
const { data: project, isLoading, error } = useProject(projectId);
const deleteProject = useDeleteProject();
+ const deleteAnalysis = useDeleteAnalysis();
+ const [deletingId, setDeletingId] = useState(null);
+
+ const handleDeleteAnalysis = async (e: React.MouseEvent, analysisId: string, analysisName: string) => {
+ e.preventDefault();
+ e.stopPropagation();
+ if (!window.confirm(`Delete analysis "${analysisName}"? This cannot be undone.`)) return;
+ setDeletingId(analysisId);
+ try {
+ await deleteAnalysis.mutateAsync(analysisId);
+ } finally {
+ setDeletingId(null);
+ }
+ };
const handleDelete = async () => {
if (!projectId) return;
@@ -131,12 +147,31 @@ export default function ProjectDetail() {
-
- {analysis.name}
-
+
+
+ {analysis.name}
+
+
+
{analysis.model}