From a5d5209dc53ac0b0677e867f0c78bb48a3ea993b Mon Sep 17 00:00:00 2001 From: arsam Date: Fri, 18 Sep 2026 23:17:49 +0330 Subject: [PATCH] Import source: vault/components/password-gate Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality. --- vault/components/password-gate.tsx | 98 ++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 vault/components/password-gate.tsx diff --git a/vault/components/password-gate.tsx b/vault/components/password-gate.tsx new file mode 100644 index 0000000..8ca0aa8 --- /dev/null +++ b/vault/components/password-gate.tsx @@ -0,0 +1,98 @@ +"use client"; + +import { useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { Lock, Eye, EyeOff } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; + +interface PasswordGateProps { + onUnlock: (password: string) => void | Promise; + errorMessage?: string; +} + +export function PasswordGate({ onUnlock, errorMessage }: PasswordGateProps) { + const [password, setPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + const [localError, setLocalError] = useState(""); + const [submitting, setSubmitting] = useState(false); + + const handleUnlock = async () => { + if (!password.trim()) { + setLocalError("Enter the password to continue."); + return; + } + + setSubmitting(true); + setLocalError(""); + try { + await onUnlock(password); + } finally { + setSubmitting(false); + } + }; + + return ( + +
+
+
+ +
+

Password required

+

+ This snippet is password-protected. Enter the password to view it. +

+
+ +
+
+ { + setPassword(e.target.value); + setLocalError(""); + }} + onKeyDown={(e) => e.key === "Enter" && handleUnlock()} + className="pr-10 h-11 bg-muted/50 border-border/50 focus:border-amber-500/50" + /> + +
+ + + {(localError || errorMessage) && ( + + {localError || errorMessage} + + )} + + + +
+
+
+ ); +}