feat: implement vaulting functionality with unlock dates and locked UI states for letters

This commit is contained in:
ramvignesh-b
2026-04-19 01:20:55 +05:30
parent e68dcb068b
commit 1c1b5ea14e
8 changed files with 340 additions and 48 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ export function DrawerSection({
<div
className={`transition-normal duration-1000 ease-in-out bg-neutral/10 ${
isOpen
? "max-h-125 opacity-100 py-3 border-b border-base-content/5"
? "opacity-100 py-3 border-b border-base-content/5"
: "max-h-0 opacity-0 pointer-events-none"
}`}
>
+26 -5
View File
@@ -1,3 +1,4 @@
import { LockIcon, LockKeyOpenIcon, LockOpenIcon } from "@phosphor-icons/react";
import { useNavigate } from "react-router-dom";
import { PATHS } from "../../config/routes";
@@ -6,14 +7,19 @@ export function LetterItem({
timestamp,
id,
status,
unlock_at,
isLocked = false,
}: {
preview: string;
timestamp: string;
id: string;
status: "DRAFT" | "SEALED" | "BURNED";
unlock_at?: string;
isLocked?: boolean;
}) {
const navigate = useNavigate();
function handleNavigate(): void {
if (isLocked) return;
if (status === "SEALED") {
navigate(PATHS.read(id));
} else {
@@ -25,14 +31,29 @@ export function LetterItem({
<button
type="button"
onClick={handleNavigate}
className="p-4 border-base-content/3 flex items-start gap-4 hover:bg-base-300 transition-all duration-100 group text-left cursor-pointer w-9/12 mx-auto hover:scale-120 hover:h-24 hover:-translate-y-3 hover:pb-4 hover:border-x-5 hover:border-t-5 border-t-2 hover:-mb-2"
className={`${isLocked ? "pointer-events-none" : ""} p-4 border-base-content/3 flex items-start gap-4 hover:bg-base-300 transition-all duration-100 group text-left cursor-pointer w-9/12 mx-auto hover:scale-120 hover:h-24 hover:-translate-y-3 hover:pb-4 hover:border-x-5 hover:border-t-5 border-t-2 hover:-mb-2`}
>
<div className="text-[0.85rem] italic text-base-content/40 flex-1 truncate group-hover:text-base-content/60 transition-none">
<div className="text-[0.85rem] italic text-base-content/40 flex-1 truncate group-hover:text-base-content/60 transition-none animate-[opacity_200ms_linear_forwards]">
{preview}
</div>
<div className="font-sans text-[0.6rem] text-base-content/20 transition-none">
{timestamp}
</div>
{unlock_at ? (
<div className="flex flex-col items-end">
{isLocked ? (
<div className="font-sans text-xs badge badge-accent badge-soft rounded-2xl">
<LockIcon weight="duotone" size={16} />
Locked Until {unlock_at}
</div>
) : (
<div className="font-sans text-xs badge badge-primary badge-soft rounded-2xl">
<LockKeyOpenIcon weight="duotone" size={16} /> Unlocked
</div>
)}
</div>
) : (
<div className="font-sans text-[0.6rem] text-base-content/20 transition-none">
{timestamp}
</div>
)}
</button>
);
}