diff --git a/frontend/src/components/ConfirmDialog.tsx b/frontend/src/components/ConfirmDialog.tsx
new file mode 100644
index 0000000..bddc2c8
--- /dev/null
+++ b/frontend/src/components/ConfirmDialog.tsx
@@ -0,0 +1,41 @@
+/** Переиспользуемое модальное подтверждение (без нативного confirm()). */
+export function ConfirmDialog({
+ open,
+ title,
+ message,
+ confirmLabel = "Подтвердить",
+ cancelLabel = "Отмена",
+ danger = false,
+ onConfirm,
+ onCancel,
+}: {
+ open: boolean;
+ title: string;
+ message?: string;
+ confirmLabel?: string;
+ cancelLabel?: string;
+ danger?: boolean;
+ onConfirm: () => void;
+ onCancel: () => void;
+}) {
+ if (!open) return null;
+ return (
+
+
e.stopPropagation()}>
+
{title}
+ {message &&
{message}
}
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/pages/MatchDetailPage.tsx b/frontend/src/pages/MatchDetailPage.tsx
index 32323a9..d68ec50 100644
--- a/frontend/src/pages/MatchDetailPage.tsx
+++ b/frontend/src/pages/MatchDetailPage.tsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { ApiError } from "../api/client";
+import { ConfirmDialog } from "../components/ConfirmDialog";
import { MatchMedia } from "../components/MatchMedia";
import { Spinner } from "../components/Spinner";
import { formatDuration, formatTime } from "../domain/format";
@@ -39,6 +40,7 @@ export function MatchDetailPage() {
const [winReason, setWinReason] = useState("objectives");
const [overall, setOverall] = useState("");
const [error, setError] = useState(null);
+ const [confirmRemove, setConfirmRemove] = useState(false);
if (isLoading) return ;
if (!match) return Партия не найдена.
;
@@ -271,10 +273,32 @@ export function MatchDetailPage() {
)}
{canModify && (
-