feat(ui): reusable app-styled confirm dialog, replacing window.confirm
Add a promise-based ConfirmProvider + useConfirm() hook (built on the Modal shell, liquid-glass styling, danger variant, Esc/backdrop = cancel, Enter = confirm) so confirmations match the app instead of the native browser dialog. Wire it in at the app root and replace both window.confirm call sites (playlist delete, channel unsubscribe). Trilingual common.confirm/confirmTitle strings.
This commit is contained in:
parent
50bc35d78f
commit
48cb11434d
7 changed files with 103 additions and 9 deletions
|
|
@ -29,6 +29,7 @@ import {
|
|||
import { api, type Playlist, type Video } from "../lib/api";
|
||||
import { formatDuration } from "../lib/format";
|
||||
import PlayerModal from "./PlayerModal";
|
||||
import { useConfirm } from "./ConfirmProvider";
|
||||
|
||||
function Row({
|
||||
video,
|
||||
|
|
@ -98,6 +99,7 @@ function Row({
|
|||
export default function Playlists() {
|
||||
const { t } = useTranslation();
|
||||
const qc = useQueryClient();
|
||||
const confirm = useConfirm();
|
||||
const [selectedId, setSelectedId] = useState<number | null>(null);
|
||||
const [newName, setNewName] = useState("");
|
||||
const [renaming, setRenaming] = useState(false);
|
||||
|
|
@ -173,7 +175,13 @@ export default function Playlists() {
|
|||
|
||||
async function deletePlaylist() {
|
||||
if (selectedId == null || !detail) return;
|
||||
if (!window.confirm(t("playlists.confirmDelete", { name: detail.name }))) return;
|
||||
const ok = await confirm({
|
||||
title: t("playlists.delete"),
|
||||
message: t("playlists.confirmDelete", { name: detail.name }),
|
||||
confirmLabel: t("playlists.delete"),
|
||||
danger: true,
|
||||
});
|
||||
if (!ok) return;
|
||||
await api.deletePlaylist(selectedId);
|
||||
setSelectedId(null);
|
||||
qc.invalidateQueries({ queryKey: ["playlists"] });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue