226 lines
5.5 KiB
TypeScript
226 lines
5.5 KiB
TypeScript
import React, { useEffect } from 'react';
|
||
|
||
interface CopyPagesDialogProps {
|
||
selectedCount: number;
|
||
pageCount: number;
|
||
targetPosition: string;
|
||
error: string | null;
|
||
onTargetPositionChange: (value: string) => void;
|
||
onCancel: () => void;
|
||
onConfirm: (e?: React.FormEvent) => void;
|
||
}
|
||
|
||
const CopyPagesDialog: React.FC<CopyPagesDialogProps> = ({
|
||
selectedCount,
|
||
pageCount,
|
||
targetPosition,
|
||
error,
|
||
onTargetPositionChange,
|
||
onCancel,
|
||
onConfirm,
|
||
}) => {
|
||
useEffect(() => {
|
||
const handleKeyDown = (e: KeyboardEvent) => {
|
||
if (e.key === 'Escape') {
|
||
e.preventDefault();
|
||
onCancel();
|
||
}
|
||
};
|
||
|
||
window.addEventListener('keydown', handleKeyDown);
|
||
|
||
return () => {
|
||
window.removeEventListener('keydown', handleKeyDown);
|
||
};
|
||
}, [onCancel]);
|
||
|
||
return (
|
||
<div
|
||
role="dialog"
|
||
aria-modal="true"
|
||
aria-labelledby="copy-pages-dialog-title"
|
||
onPointerDown={(e) => {
|
||
if (e.target === e.currentTarget) {
|
||
onCancel();
|
||
}
|
||
}}
|
||
style={{
|
||
position: 'fixed',
|
||
inset: 0,
|
||
zIndex: 60,
|
||
background: 'var(--pdf-overlay)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
padding: '1rem',
|
||
}}
|
||
>
|
||
<form
|
||
onSubmit={onConfirm}
|
||
style={{
|
||
width: '100%',
|
||
maxWidth: '420px',
|
||
background: 'var(--pdf-surface-raised)',
|
||
color: 'var(--pdf-text)',
|
||
borderRadius: '0.75rem',
|
||
boxShadow: 'var(--pdf-dialog-shadow)',
|
||
padding: '1rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '0.75rem',
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'center',
|
||
gap: '0.75rem',
|
||
}}
|
||
>
|
||
<h2
|
||
id="copy-pages-dialog-title"
|
||
style={{
|
||
margin: 0,
|
||
fontSize: '1rem',
|
||
}}
|
||
>
|
||
Copy selected pages
|
||
</h2>
|
||
|
||
<button
|
||
type="button"
|
||
onClick={onCancel}
|
||
style={{
|
||
border: 'none',
|
||
borderRadius: '999px',
|
||
width: '1.8rem',
|
||
height: '1.8rem',
|
||
background: 'var(--pdf-control)',
|
||
color: 'var(--pdf-control-text)',
|
||
cursor: 'pointer',
|
||
fontSize: '1.1rem',
|
||
lineHeight: 1,
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
}}
|
||
aria-label="Close copy dialog"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
|
||
<p
|
||
style={{
|
||
margin: 0,
|
||
fontSize: '0.9rem',
|
||
color: 'var(--pdf-muted)',
|
||
}}
|
||
>
|
||
Copy{' '}
|
||
<strong>
|
||
{selectedCount === 1
|
||
? '1 selected page'
|
||
: `${selectedCount} selected pages`}
|
||
</strong>{' '}
|
||
to a new position.
|
||
</p>
|
||
|
||
<label
|
||
style={{
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '0.25rem',
|
||
fontSize: '0.9rem',
|
||
}}
|
||
>
|
||
Insert before position
|
||
<input
|
||
type="number"
|
||
min={1}
|
||
max={pageCount + 1}
|
||
value={targetPosition}
|
||
autoFocus
|
||
onChange={(e) => onTargetPositionChange(e.target.value)}
|
||
style={{
|
||
padding: '0.45rem 0.55rem',
|
||
borderRadius: '0.5rem',
|
||
border: '1px solid var(--pdf-border-strong)',
|
||
fontSize: '0.95rem',
|
||
}}
|
||
/>
|
||
</label>
|
||
|
||
<div
|
||
style={{
|
||
fontSize: '0.8rem',
|
||
color: 'var(--pdf-muted-soft)',
|
||
lineHeight: 1.4,
|
||
}}
|
||
>
|
||
<div>1 = before the first page</div>
|
||
<div>{pageCount + 1} = after the last page</div>
|
||
</div>
|
||
|
||
{error && (
|
||
<div
|
||
style={{
|
||
borderRadius: '0.5rem',
|
||
background: 'var(--pdf-danger-surface)',
|
||
border: '1px solid var(--pdf-danger-border)',
|
||
color: 'var(--pdf-danger-text)',
|
||
padding: '0.5rem',
|
||
fontSize: '0.85rem',
|
||
}}
|
||
>
|
||
{error}
|
||
</div>
|
||
)}
|
||
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
justifyContent: 'flex-end',
|
||
gap: '0.5rem',
|
||
marginTop: '0.25rem',
|
||
}}
|
||
>
|
||
<button
|
||
type="button"
|
||
onClick={onCancel}
|
||
style={{
|
||
border: 'none',
|
||
borderRadius: '0.5rem',
|
||
padding: '0.45rem 0.8rem',
|
||
background: 'var(--pdf-control)',
|
||
color: 'var(--pdf-control-text)',
|
||
cursor: 'pointer',
|
||
fontSize: '0.9rem',
|
||
}}
|
||
>
|
||
Cancel
|
||
</button>
|
||
|
||
<button
|
||
type="submit"
|
||
style={{
|
||
border: 'none',
|
||
borderRadius: '0.5rem',
|
||
padding: '0.45rem 0.8rem',
|
||
background: 'var(--pdf-success-text)',
|
||
color: 'var(--pdf-on-primary)',
|
||
cursor: 'pointer',
|
||
fontSize: '0.9rem',
|
||
}}
|
||
>
|
||
Copy pages
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default CopyPagesDialog;
|