added about modal for the pdf

This commit is contained in:
azeeee05
2026-06-10 15:29:00 +05:30
parent bda4f3925b
commit 5dfbfe6d26
4 changed files with 94 additions and 3 deletions
+8
View File
@@ -5,6 +5,7 @@ import { Toolbar } from './components/Toolbar';
import { InspectorPanel } from './components/InspectorPanel';
import type { InspectorTab } from './components/InspectorPanel';
import { SignatureModal } from './components/SignatureModal';
import { AboutModal } from './components/AboutModal';
import { ToastViewport } from './components/ui';
import { CustomConfirmationModal } from './components/custom/CustomConfirmationModal';
import type { CustomConfirmationOptions } from './components/custom/CustomConfirmationModal';
@@ -55,6 +56,7 @@ function App() {
// Tool aux state
const [pendingSignature, setPendingSignature] = useState<{ url: string; aspect: number } | null>(null);
const [signatureModalOpen, setSignatureModalOpen] = useState(false);
const [aboutModalOpen, setAboutModalOpen] = useState(false);
const [activeStamp, setActiveStamp] = useState<{ label: string; color: string } | null>(null);
const [confirmState, setConfirmState] = useState<(CustomConfirmationOptions & { onConfirm: () => void }) | null>(null);
@@ -439,6 +441,7 @@ function App() {
onToolChange={setActiveTool}
hasSignature={!!pendingSignature}
onOpenSignature={() => setSignatureModalOpen(true)}
onOpenAbout={() => setAboutModalOpen(true)}
/>
<div className="flex min-w-0 flex-1 flex-col">
@@ -542,6 +545,11 @@ function App() {
toast('Signature ready — click on the page to place it', 'info');
}}
/>
<AboutModal
open={aboutModalOpen}
onClose={() => setAboutModalOpen(false)}
/>
<CustomConfirmationModal state={confirmState} onClose={() => setConfirmState(null)} />
<ToastViewport />
+77
View File
@@ -0,0 +1,77 @@
import React, { useEffect, useRef } from 'react';
import { XIcon } from './icons';
interface AboutModalProps {
open: boolean;
onClose: () => void;
}
export const AboutModal: React.FC<AboutModalProps> = ({ open, onClose }) => {
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape' && open) onClose();
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [open, onClose]);
useEffect(() => {
if (open) {
modalRef.current?.focus();
}
}, [open]);
if (!open) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
<div
ref={modalRef}
tabIndex={-1}
className="relative flex w-[480px] max-w-[90vw] flex-col items-center overflow-hidden rounded-[8px] bg-[#222222] p-8 text-center text-white shadow-2xl outline-none"
>
<button
onClick={onClose}
className="absolute right-4 top-4 rounded-[4px] p-1 text-white/50 transition-colors hover:bg-white/10 hover:text-white"
>
<XIcon size={20} />
</button>
<div className="mb-6 flex flex-col items-center">
<div className="flex items-center justify-center gap-3">
<div className="flex h-10 w-10 items-center justify-center rounded-[9px] bg-[#2563eb] text-white shadow-sm">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round">
<path d="M7 3h7l5 5v13H7a2 2 0 01-2-2V5a2 2 0 012-2z" /><path d="M14 3v5h5" />
</svg>
</div>
<span className="text-[26px] font-bold tracking-tight">MASKAN PDF</span>
</div>
<div className="mt-4 text-[14px] text-white/80">
PDF EDITOR
</div>
<div className="text-[14px] text-white/60">
Version 1.0.0
</div>
</div>
<div className="flex w-full flex-col gap-2 border-t border-white/10 pt-6">
<div className="text-[18px] font-bold">
Maskan Technologies
</div>
<div className="mt-2 text-[14px] leading-relaxed text-white/80">
<p>address: Bangalore, Karnataka, India</p>
<p>email: contact@maskantechnologies.com</p>
<p>tel.: +91 000-000-0000</p>
</div>
<div className="mt-4 text-[14px] font-medium text-white/80">
www.maskantechnologies.com
</div>
</div>
</div>
</div>
);
};
+8 -3
View File
@@ -4,7 +4,7 @@ import type { ToolId } from '../lib/tools';
import { Popover } from './ui';
import {
SelectIcon, PanIcon, HighlightIcon, DrawIcon, CommentIcon, TextBoxIcon,
SignatureIcon, StampIcon, RedactIcon, InfoIcon,
SignatureIcon, StampIcon, RedactIcon, InfoIcon, HelpIcon,
} from './icons';
interface ToolDef { id: ToolId; label: string; shortcut: string; icon: React.ReactNode; danger?: boolean }
@@ -28,6 +28,7 @@ interface ToolRailProps {
onToolChange: (t: ToolId) => void;
hasSignature: boolean;
onOpenSignature: () => void;
onOpenAbout: () => void;
}
const RailButton: React.FC<{ t: ToolDef; active: boolean; onClick: () => void }> = ({ t, active, onClick }) => (
@@ -48,7 +49,7 @@ const RailButton: React.FC<{ t: ToolDef; active: boolean; onClick: () => void }>
</CustomButton>
);
export const ToolRail: React.FC<ToolRailProps> = ({ activeTool, onToolChange, hasSignature, onOpenSignature }) => {
export const ToolRail: React.FC<ToolRailProps> = ({ activeTool, onToolChange, hasSignature, onOpenSignature, onOpenAbout }) => {
const pickTool = (id: ToolId) => {
onToolChange(id);
if (id === 'signature' && !hasSignature) onOpenSignature();
@@ -64,12 +65,16 @@ export const ToolRail: React.FC<ToolRailProps> = ({ activeTool, onToolChange, ha
<div className="flex-1" />
<CustomButton variant="unstyled" title="About Maskan PDF Editor" onClick={onOpenAbout} className="flex h-9 w-9 items-center justify-center rounded-[10px] text-[#98a1ad] transition-colors hover:bg-[#edeff2] hover:text-[#18212e]">
<InfoIcon size={19} />
</CustomButton>
<Popover
align="left"
width={210}
trigger={(open) => (
<CustomButton variant="unstyled" title="Keyboard shortcuts" className={`flex h-9 w-9 items-center justify-center rounded-[10px] transition-colors ${open ? 'bg-[#edeff2] text-[#18212e]' : 'text-[#98a1ad] hover:bg-[#edeff2] hover:text-[#18212e]'}`}>
<InfoIcon size={19} />
<HelpIcon size={19} />
</CustomButton>
)}
>
+1
View File
@@ -75,5 +75,6 @@ export const CopyIcon: IC = mk(<><rect x="9" y="9" width="11" height="11" rx="2"
export const PlusIcon: IC = mk(<path d="M12 5v14M5 12h14" />);
export const UploadIcon: IC = mk(<path d="M12 16V4m0 0L8 8m4-4l4 4M4 17v2a2 2 0 002 2h12a2 2 0 002-2v-2" />);
export const InfoIcon: IC = mk(<><circle cx="12" cy="12" r="9" /><path d="M12 11v5M12 8h.01" /></>);
export const HelpIcon: IC = mk(<><circle cx="12" cy="12" r="9" /><path d="M9 10a3 3 0 116 0c0 1.5-2 2-2 3M12 17h.01" /></>);
export const SpinnerIcon: IC = ({ size = 18, className }) =>
base(size, `${className ?? ''} animate-spin`, 2, <><path d="M12 3a9 9 0 109 9" opacity="0.85" /><path d="M21 12a9 9 0 00-9-9" opacity="0.25" /></>);