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() {
)}
-