diff --git a/frontend/src/components/RequestCampaignModificationModal.tsx b/frontend/src/components/RequestCampaignModificationModal.tsx new file mode 100644 index 0000000..4885453 --- /dev/null +++ b/frontend/src/components/RequestCampaignModificationModal.tsx @@ -0,0 +1,136 @@ +import { useState } from "react"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { X, Loader2 } from "lucide-react"; +import { createModificationRequest, type CampaignTest } from "../api/campaigns"; + +interface Props { + campaignId: string; + tests: CampaignTest[]; + open: boolean; + onClose: () => void; + onSuccess: () => void; +} + +export default function RequestCampaignModificationModal({ + campaignId, + tests, + open, + onClose, + onSuccess, +}: Props) { + const queryClient = useQueryClient(); + const [action, setAction] = useState<"add_test" | "remove_test">("remove_test"); + const [testId, setTestId] = useState(""); + const [justification, setJustification] = useState(""); + + const mutation = useMutation({ + mutationFn: () => + createModificationRequest(campaignId, { + action, + test_id: testId, + justification: justification.trim(), + }), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["campaign-modification-requests", campaignId] }); + setTestId(""); + setJustification(""); + onSuccess(); + onClose(); + }, + }); + + if (!open) return null; + + const canSubmit = testId && justification.trim().length > 0 && !mutation.isPending; + + return ( +
+ {r.action.replace("_", " ")} + {" — "} + {r.test_name || r.test_id || "deleted test"} +
+{r.justification}
+ {r.review_notes && ( +Manager notes: {r.review_notes}
+ )} +