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 ( +
+
+
+

Request Campaign Modification

+ +
+ +
+
+ + +
+ + {action === "remove_test" ? ( +
+ + +
+ ) : ( +
+ + setTestId(e.target.value)} + placeholder="Paste the existing test's ID" + className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-cyan-500 focus:outline-none" + /> +
+ )} + +
+ +