mirror of
https://github.com/kccleoc/seedpgp-web.git
synced 2026-03-07 09:57:50 +08:00
ux: clean security warnings modal and overlays
This commit is contained in:
58
src/App.tsx
58
src/App.tsx
@@ -612,62 +612,68 @@ function App() {
|
||||
|
||||
{/* Security Modal */}
|
||||
{showSecurityModal && (
|
||||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
|
||||
<div className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl">
|
||||
<div
|
||||
className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50"
|
||||
onClick={() => setShowSecurityModal(false)}
|
||||
>
|
||||
<div
|
||||
className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">Security Limitations</h3>
|
||||
<div className="text-sm text-slate-300 space-y-2">
|
||||
<SecurityWarnings />
|
||||
</div>
|
||||
<button
|
||||
className="mt-4 w-full py-2 bg-slate-700 hover:bg-slate-600 rounded-lg"
|
||||
onClick={() => setShowSecurityModal(false)}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Storage Modal */}
|
||||
{showStorageModal && (
|
||||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
|
||||
<div className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl">
|
||||
<div
|
||||
className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50"
|
||||
onClick={() => setShowStorageModal(false)}
|
||||
>
|
||||
<div
|
||||
className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">Storage Details</h3>
|
||||
<div className="text-sm text-slate-300 space-y-2">
|
||||
<StorageDetails localItems={localItems} sessionItems={sessionItems} />
|
||||
</div>
|
||||
<button
|
||||
className="mt-4 w-full py-2 bg-slate-700 hover:bg-slate-600 rounded-lg"
|
||||
onClick={() => setShowStorageModal(false)}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Clipboard Modal */}
|
||||
{showClipboardModal && (
|
||||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
|
||||
<div className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl">
|
||||
<div
|
||||
className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50"
|
||||
onClick={() => setShowClipboardModal(false)}
|
||||
>
|
||||
<div
|
||||
className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-white mb-4">Clipboard Activity</h3>
|
||||
<div className="text-sm text-slate-300 space-y-2">
|
||||
<ClipboardDetails events={clipboardEvents} onClear={clearClipboard} />
|
||||
</div>
|
||||
<button
|
||||
className="mt-4 w-full py-2 bg-slate-700 hover:bg-slate-600 rounded-lg"
|
||||
onClick={() => setShowClipboardModal(false)}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Lock Confirmation Modal */}
|
||||
{showLockConfirm && (
|
||||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
|
||||
<div className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl">
|
||||
<div
|
||||
className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50"
|
||||
onClick={() => setShowLockConfirm(false)}
|
||||
>
|
||||
<div
|
||||
className="bg-slate-800 rounded-xl border border-slate-700 p-6 max-w-md w-full mx-4 shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
|
||||
<Lock className="w-5 h-5 text-amber-500" />
|
||||
Lock Sensitive Data?
|
||||
|
||||
@@ -1,28 +1,8 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
export const SecurityWarnings = () => {
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
import React from 'react';
|
||||
|
||||
export const SecurityWarnings: React.FC = () => {
|
||||
return (
|
||||
<div className="fixed top-4 left-4 z-50 max-w-sm">
|
||||
<div className="bg-yellow-50 border-2 border-yellow-400 rounded-lg shadow-lg">
|
||||
|
||||
{/* Header */}
|
||||
<div
|
||||
className="px-4 py-3 cursor-pointer flex items-center justify-between hover:bg-yellow-100 transition-colors rounded-t-lg"
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-lg">⚠️</span>
|
||||
<span className="font-semibold text-sm text-yellow-900">Security Limitations</span>
|
||||
</div>
|
||||
<span className="text-yellow-600 text-sm">{isExpanded ? '▼' : '▶'}</span>
|
||||
</div>
|
||||
|
||||
{/* Expanded Content */}
|
||||
{isExpanded && (
|
||||
<div className="px-4 py-3 border-t border-yellow-300 space-y-3 max-h-96 overflow-y-auto">
|
||||
|
||||
<div className="space-y-3">
|
||||
<Warning
|
||||
icon="🧵"
|
||||
title="JavaScript Strings are Immutable"
|
||||
@@ -59,23 +39,28 @@ export const SecurityWarnings = () => {
|
||||
description="If hosted online: DNS, HTTPS, CDN, and browser can see usage patterns. Use offline/local for maximum security."
|
||||
/>
|
||||
|
||||
<div className="pt-2 border-t border-yellow-300 text-xs text-yellow-800">
|
||||
<strong>Recommendation:</strong> Use this tool on a dedicated offline device.
|
||||
Clear browser data after each use. Never use on shared/public computers.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="pt-3 border-t border-slate-600 text-xs text-slate-400">
|
||||
<strong className="text-slate-300">Recommendation:</strong>{' '}
|
||||
Use this tool on a dedicated offline device. Clear browser data after each use. Never use on shared/public computers.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Warning = ({ icon, title, description }: { icon: string; title: string; description: string }) => (
|
||||
<div className="flex gap-2 text-xs">
|
||||
<span className="text-base flex-shrink-0">{icon}</span>
|
||||
const Warning = ({
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
}: {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}) => (
|
||||
<div className="flex gap-2 text-sm">
|
||||
<span className="text-lg flex-shrink-0">{icon}</span>
|
||||
<div>
|
||||
<div className="font-semibold text-yellow-900 mb-0.5">{title}</div>
|
||||
<div className="text-yellow-800 leading-relaxed">{description}</div>
|
||||
<div className="font-semibold text-slate-200 mb-1">{title}</div>
|
||||
<div className="text-slate-400 leading-relaxed">{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user