diff --git a/src/components/ActionBar/ActionBar.jsx b/src/components/ActionBar/ActionBar.jsx index 6fd85c1..e3eec26 100644 --- a/src/components/ActionBar/ActionBar.jsx +++ b/src/components/ActionBar/ActionBar.jsx @@ -1,23 +1,24 @@ import { useSelection } from '../../context/SelectionContext'; import { useScriptGenerator } from '../../hooks/useScriptGenerator'; +import { useState } from 'react'; +import WinDialog from '../Common/WinDialog'; const ActionBar = () => { const { selectedSoftware, selectedConfigs, clearAll } = useSelection(); const { downloadScript } = useScriptGenerator(); + const [showClearDialog, setShowClearDialog] = useState(false); + const [showDownloadDialog, setShowDownloadDialog] = useState(false); const totalSelected = selectedSoftware.length + selectedConfigs.length; const handleDownload = () => { - downloadScript(); + if (totalSelected === 0) return; + setShowDownloadDialog(true); }; const handleClear = () => { - if ( - totalSelected > 0 && - confirm(`Clear all ${totalSelected} selections?`) - ) { - clearAll(); - } + if (totalSelected === 0) return; + setShowClearDialog(true); }; return ( @@ -60,6 +61,48 @@ const ActionBar = () => { + + setShowDownloadDialog(false)} + primaryAction={{ + label: 'Download', + onClick: () => { + downloadScript(); + setShowDownloadDialog(false); + }, + variant: 'primary', + }} + secondaryAction={{ + label: 'Close', + onClick: () => setShowDownloadDialog(false), + }} + > + Right-click the downloaded .bat file and select "Run as Administrator" + + + setShowClearDialog(false)} + primaryAction={{ + label: 'Clear', + onClick: () => { + clearAll(); + setShowClearDialog(false); + }, + variant: 'danger', + }} + secondaryAction={{ + label: 'Cancel', + onClick: () => setShowClearDialog(false), + }} + > + Clear all {totalSelected} selections? + ); }; diff --git a/src/components/Common/WinDialog.jsx b/src/components/Common/WinDialog.jsx new file mode 100644 index 0000000..3bdf832 --- /dev/null +++ b/src/components/Common/WinDialog.jsx @@ -0,0 +1,110 @@ +import { useEffect, useId, useRef } from 'react'; + +const WinDialog = ({ + open, + title, + children, + primaryAction, + secondaryAction, + onClose, + icon = 'ℹ️', + width = 420, +}) => { + const titleId = useId(); + const dialogRef = useRef(null); + const primaryButtonRef = useRef(null); + + useEffect(() => { + if (!open) return; + + const previousOverflow = document.body.style.overflow; + document.body.style.overflow = 'hidden'; + + const focusTimer = window.setTimeout(() => { + if (primaryButtonRef.current) { + primaryButtonRef.current.focus(); + } else if (dialogRef.current) { + dialogRef.current.focus(); + } + }, 0); + + const handleKeyDown = (e) => { + if (e.key === 'Escape') onClose?.(); + }; + window.addEventListener('keydown', handleKeyDown); + + return () => { + window.clearTimeout(focusTimer); + window.removeEventListener('keydown', handleKeyDown); + document.body.style.overflow = previousOverflow; + }; + }, [open, onClose]); + + if (!open) return null; + + return ( +
{ + if (e.target === e.currentTarget) onClose?.(); + }} + > +
+
+
+ {icon} + {title} +
+
+ +
+
+ +
+
+ {children} +
+ +
+ {secondaryAction && ( + + )} + {primaryAction && ( + + )} +
+
+
+
+ ); +}; + +export default WinDialog; + diff --git a/src/components/Layout/Header.jsx b/src/components/Layout/Header.jsx index ad80a91..4837821 100644 --- a/src/components/Layout/Header.jsx +++ b/src/components/Layout/Header.jsx @@ -19,8 +19,6 @@ const Header = () => { • automatically installs selected programs
• adjusts selected settings
Everything automatically
-
- Right-click the downloaded .bat file and select "Run as Administrator"