diff --git a/src/client/components/Modal.tsx b/src/client/components/Modal.tsx index 68eafa2..203d1c5 100644 --- a/src/client/components/Modal.tsx +++ b/src/client/components/Modal.tsx @@ -1,15 +1,35 @@ -import type { ReactNode } from "react"; +import { useEffect, type ReactNode } from "react"; export function Modal({ maxWidth = "max-w-sm", children, + onClose, + labelledBy, }: { maxWidth?: string; children: ReactNode; + onClose?: () => void; + labelledBy?: string; }) { + useEffect(() => { + if (!onClose) return; + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key !== "Escape" || event.defaultPrevented) return; + event.preventDefault(); + onClose(); + }; + + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [onClose]); + return (
{children}
diff --git a/src/client/components/table/ExportToSheetsModal.tsx b/src/client/components/table/ExportToSheetsModal.tsx index 896b0a8..2971519 100644 --- a/src/client/components/table/ExportToSheetsModal.tsx +++ b/src/client/components/table/ExportToSheetsModal.tsx @@ -28,13 +28,17 @@ export function ExportToSheetsModal() { }; return ( - +
-

+

Copied {rowCount} row{rowCount === 1 ? "" : "s"} to your clipboard

diff --git a/src/client/features/rank-tracking/CheckConfirmModal.tsx b/src/client/features/rank-tracking/CheckConfirmModal.tsx index c33fa65..93a8f6e 100644 --- a/src/client/features/rank-tracking/CheckConfirmModal.tsx +++ b/src/client/features/rank-tracking/CheckConfirmModal.tsx @@ -34,9 +34,13 @@ export function CheckConfirmModal({ Math.ceil(totalChecks / KEYWORDS_PER_BATCH) * SECONDS_PER_BATCH; return ( - +
-

+

Check {keywordCount} keyword {keywordCount !== 1 ? "s" : ""}

diff --git a/src/client/features/rank-tracking/KeywordSuggestionStep.tsx b/src/client/features/rank-tracking/KeywordSuggestionStep.tsx index edaf762..7405ce9 100644 --- a/src/client/features/rank-tracking/KeywordSuggestionStep.tsx +++ b/src/client/features/rank-tracking/KeywordSuggestionStep.tsx @@ -255,7 +255,9 @@ export function KeywordSuggestionStep({ const sectionHeader = (title: string) => (
-

{title}

+

+ {title} +

diff --git a/src/client/features/rank-tracking/RankTrackingConfigModal.tsx b/src/client/features/rank-tracking/RankTrackingConfigModal.tsx index 8fd4fac..9348120 100644 --- a/src/client/features/rank-tracking/RankTrackingConfigModal.tsx +++ b/src/client/features/rank-tracking/RankTrackingConfigModal.tsx @@ -127,8 +127,14 @@ export function RankTrackingConfigModal({ const isPending = createMutation.isPending || updateMutation.isPending; if (step === "keywords" && createdConfigId) { + const closeKeywordStep = () => onSaved(createdConfigId); + return ( - + onSaved(id)} - onClose={() => onSaved(createdConfigId ?? undefined)} + onClose={closeKeywordStep} /> ); } return ( - +
-

+

{isEdit ? "Edit Domain Config" : "Add Domain"}

{archiveTarget && ( - -

+ setArchiveTarget(null)} + labelledBy="archive-domain-title" + > +

Archive {archiveTarget.domain}?

diff --git a/src/client/features/rank-tracking/RankTrackingTable.tsx b/src/client/features/rank-tracking/RankTrackingTable.tsx index 2da9feb..b24d9af 100644 --- a/src/client/features/rank-tracking/RankTrackingTable.tsx +++ b/src/client/features/rank-tracking/RankTrackingTable.tsx @@ -129,8 +129,13 @@ export function RankTrackingTable({ {/* Confirm modal */} {showConfirm && ( - -

Remove keywords?

+ setShowConfirm(false)} + labelledBy="remove-keywords-title" + > +

+ Remove keywords? +

This will stop tracking {selectedCount} keyword {selectedCount !== 1 ? "s" : ""}. Historical ranking data is