diff --git a/frontend/src/pages/PdfProtect.tsx b/frontend/src/pages/PdfProtect.tsx index 7fafd60..0dfeb8e 100644 --- a/frontend/src/pages/PdfProtect.tsx +++ b/frontend/src/pages/PdfProtect.tsx @@ -1,18 +1,39 @@ import { useState, useCallback } from "react"; import { useFileUpload } from "../hooks/useFileUpload"; import FileUploadArea from "../components/FileUploadArea"; -import { FileText, Lock, Eye, EyeOff, AlertTriangle } from "lucide-react"; +import { FileText, Lock, Eye, EyeOff, AlertTriangle, Check, X } from "lucide-react"; import { toastError, toastSuccess, toastLoading, toastDismiss, parseApiError } from "../utils/toast"; import { useHistory } from "../context/HistoryContext"; const BACKEND_URL = import.meta.env.VITE_API_URL || "http://localhost:5000"; +function Rule({ + ok, + text, +}: { + ok: boolean; + text: string; +}) { + return ( +
+ {ok ? ( + + ) : ( + + )} + + {text} +
+ ); +} + function PdfProtect() { const { addToHistory } = useHistory(); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); + const [showPasswordRules, setShowPasswordRules] = useState(false); const validateFile = useCallback(async (selectedFile: any) => { if (selectedFile && selectedFile.type === "application/pdf") { @@ -36,9 +57,36 @@ function PdfProtect() { setConfirmPassword(""); }; + const passwordChecks = { + uppercase: /[A-Z]/.test(password), + lowercase: /[a-z]/.test(password), + number: /\d/.test(password), + special: /[!@#$%^&*(),.?":{}|<>]/.test(password), + length: password.length >= 8, + }; + + const isPasswordValid = + passwordChecks.uppercase && + passwordChecks.lowercase && + passwordChecks.number && + passwordChecks.special && + passwordChecks.length && + password === confirmPassword; + + const strength = + Object.values(passwordChecks).filter(Boolean).length; + + const strengthColor = + strength <= 2 + ? "bg-red-500" + : strength <= 4 + ? "bg-yellow-500" + : "bg-green-500"; + + const strengthWidth = `${(strength / 5) * 100}%`; + const validatePassword = () => { if (!password) return "Password is required."; - if (password.length < 4) return "Password must be at least 4 characters long."; if (password !== confirmPassword) return "Passwords do not match."; return null; }; @@ -155,6 +203,32 @@ function PdfProtect() { +
setShowPasswordRules(true)} + onMouseLeave={() => setShowPasswordRules(false)} + > + +
+
+
+ + {showPasswordRules && ( +
+ + + + + + + +
+ )} + +
@@ -164,7 +238,7 @@ function PdfProtect() {
)} -