diff --git a/frontend/src/components/ui/DrawerSection.tsx b/frontend/src/components/ui/DrawerSection.tsx index c528297..c74df60 100644 --- a/frontend/src/components/ui/DrawerSection.tsx +++ b/frontend/src/components/ui/DrawerSection.tsx @@ -23,7 +23,7 @@ export function DrawerSection({ className={`join-item group flex flex-col transition-colors duration-3000 ease-in-out ${isOpen ? "bg-base-300/30" : ""}`} >
Promise; +} + +function PasskeyModal({ onUnlock }: PasskeyModalProps) { + return ( +
+
+ +

+ Authentication Required +

+

+ We need you to re-enter your passkey to open your letters +

+
+

+ P.S. We don't validate your input at the moment. +

+
+
) => { + e.preventDefault(); + const formData = new FormData(e.currentTarget); + const password = formData.get("password") as string; + if (!password) return; + await onUnlock(password); + }} + > + +
+ +
+
+
+
+ ); +} + export default function Drawer() { const { user, logout, unlock } = useAuth(); @@ -21,53 +72,6 @@ export default function Drawer() { if (!user) return null; - function PasskeyModal() { - return ( -
-
- -

- Authentication Required -

-

- We need your passkey to open your letters -

-
-

- P.S. We don't validate your input at the moment. -

-
-
) => { - e.preventDefault(); - const formData = new FormData(e.currentTarget); - const password = formData.get("password") as string; - if (!password) return; - await unlock(password); - }} - > - -
- -
-
-
-
- ); - } - const toggleSection = (id: string) => setOpenSection(openSection === id ? null : id); @@ -75,8 +79,8 @@ export default function Drawer() {
- {isAuthRequired && } -
+ {isAuthRequired && } +
Personal Archive @@ -94,7 +98,7 @@ export default function Drawer() {
-
+
{loading ? (
@@ -175,7 +179,7 @@ export default function Drawer() { id={letter.public_id} preview={letter.metadata?.recipient || "Future Self"} timestamp={formatRelativeDate(letter.updated_at)} - unlock_at={formateRelativeDateWithoutTime( + unlock_at={formatRelativeDateWithoutTime( letter.unlock_at || "", )} isLocked={letter.unlock_at > new Date().toISOString()} @@ -188,20 +192,20 @@ export default function Drawer() { + +
+
+
+ ); +} + +interface ToolBarProps { + fileInputRef: React.RefObject; + sealBtnClicked: boolean; + setSealBtnClicked: (v: boolean) => void; + onSave: (status: "SEALED" | "DRAFT" | "VAULT", date?: Date) => Promise; + setConfirmModal: (v: "VAULT" | "SEAL" | null) => void; +} + +function ToolBar({ + fileInputRef, + sealBtnClicked, + setSealBtnClicked, + onSave, + setConfirmModal, +}: ToolBarProps) { + return ( +
+
+ +
+ +
+ + +
+ + +
+ +
+ +
+ or +
+ +
+ +
+ ); +} + +function LetterHead() { + return ( +
+
+ + + Sealed & View Only + +
+
+ ); +} + +interface VaultConfirmProps { + onSave: (status: "SEALED" | "DRAFT" | "VAULT", date?: Date) => Promise; + setConfirmModal: (v: "VAULT" | "SEAL" | null) => void; + setUnlockDate: (d: Date | null) => void; +} + +function VaultConfirm({ + onSave, + setConfirmModal, + setUnlockDate, +}: VaultConfirmProps) { + return ( +
+
+ +

Vault this letter?

+

+ Vaulting locks the letter permanently and will be{" "} + mailed to you + automatically on the unlock date. +
+ + You cannot edit or view the contents of the letter until then. + +

+
{ + e.preventDefault(); + const formData = new FormData(e.currentTarget); + const unlockDateStr = formData.get("vault-date") as string; + const newUnlockDate = new Date(unlockDateStr); + setUnlockDate(newUnlockDate); + await onSave("VAULT", newUnlockDate); + setConfirmModal(null); + }} + id="vault-form" + > +
+ Set an unlock date +
+ + + + +
+
+
+ ); +} + export default function Editor() { const navigate = useNavigate(); const navigateRef = useRef(navigate); @@ -76,26 +311,17 @@ export default function Editor() { const [recipient, setRecipient] = useState(""); const [unlockDate, setUnlockDate] = useState(null); + const [placeholderIndex, setPlaceholderIndex] = useState(0); const { masterKey } = useKeyStore(); const canvasRef = useRef(null); const fileInputRef = useRef(null); - const recipientInputRef = useRef(null); + // Placeholder rotation useEffect(() => { const interval = setInterval(() => { - if (recipientInputRef.current) { - let currentOffset = parseInt( - recipientInputRef.current.dataset.offset || "0", - ); - recipientInputRef.current.dataset.offset = ( - (currentOffset + 1) % - toPlaceholderList.length - ).toString(); - recipientInputRef.current.placeholder = - toPlaceholderList[parseInt(recipientInputRef.current.dataset.offset)]; - } + setPlaceholderIndex((prev) => (prev + 1) % toPlaceholderList.length); }, 4000); return () => clearInterval(interval); @@ -312,218 +538,6 @@ export default function Editor() { } }; - function SealedModal() { - if (!sealedTargetId) return null; - return ( -
-
- -

Your letter is sealed

-

- It's encrypted and always safe in your drawer. -

-

- When you're ready, -
- you can{" "} - read{" "} - it, send{" "} - it to someone, or{" "} - burn it - to release -

-
- - -
-
-
- ); - } - - function ToolBar() { - return ( -
-
- - -
- -
- - -
- - -
- -
- -
- or -
- -
- -
- ); - } - - function LetterHead() { - return ( -
-
- - - Sealed & View Only - -
-
- ); - } - - function VaultConfirm() { - return ( -
-
- -

Vault this letter?

-

- Vaulting locks the letter permanently and will be{" "} - mailed to you - automatically on the unlock date. -
- - You cannot edit or view the contents of the letter until then. - -

-
{ - e.preventDefault(); - const formData = new FormData(e.currentTarget); - const unlockDateStr = formData.get("vault-date") as string; - const newUnlockDate = new Date(unlockDateStr); - setUnlockDate(newUnlockDate); - await handleSave("VAULT", newUnlockDate); - setConfirmModal(null); - }} - id="vault-form" - > -
- Set an unlock date -
- - - - -
-
-
- ); - } - return ( <> -

+

Last Save
{lastSaved} -

+
)} - {confirmModal === "VAULT" && } - {sealedTargetId && } + {confirmModal === "VAULT" && ( + + )} + {sealedTargetId && ( + + )}
@@ -646,9 +668,7 @@ export default function Editor() { setRecipient(e.target.value)} @@ -658,7 +678,25 @@ export default function Editor() {
- {status === "DRAFT" ? : } + {status === "DRAFT" ? ( + + ) : ( + + )} + +
diff --git a/frontend/src/utils/dateFormat.ts b/frontend/src/utils/dateFormat.ts index fc72e4a..2e7dcae 100644 --- a/frontend/src/utils/dateFormat.ts +++ b/frontend/src/utils/dateFormat.ts @@ -38,7 +38,7 @@ export function formatRelativeDate(input: Date | string | number) { return dateTimeFormatter.format(date); } -export function formateRelativeDateWithoutTime(input: Date | string | number) { +export function formatRelativeDateWithoutTime(input: Date | string | number) { if (!input) return ""; const date = new Date(input); const now = new Date();