Skip to content
File

Blob: src/client/hooks/useInboxPageActions.ts

typescript126 lines
1import { useMemo, useState } from "react";
2import { useNavigate } from "react-router-dom";
3import { toast } from "@/client/components/toast";
4import {
5 TEMP_MAILBOX_TTL_HOURS,
6 deleteInbox,
7 extendInbox,
8 getErrorMessage,
9 removeInboxSession,
10 updateInboxSession,
11 type AuthDescriptor,
12 type InboxInfo,
13 type TempMailboxTtlHours,
14} from "@/client/lib/api";
15 
16interface SessionTarget {
17 address: string;
18 auth: AuthDescriptor;
19}
20 
21interface UseInboxPageActionsOptions {
22 address: string;
23 adminMode: boolean;
24 inbox: InboxInfo | null;
25 onDeleted: (address: string) => void;
26 refreshInbox: () => Promise<InboxInfo | null>;
27 selectEmail: (emailId: string) => Promise<void> | void;
28 session: SessionTarget | null;
29}
30 
31export function useInboxPageActions({
32 address,
33 adminMode,
34 inbox,
35 onDeleted,
36 refreshInbox,
37 selectEmail,
38 session,
39}: UseInboxPageActionsOptions) {
40 const navigate = useNavigate();
41 const [extendingTo, setExtendingTo] = useState<TempMailboxTtlHours | null>(null);
42 
43 const availableExtensions = useMemo(() => {
44 if (!inbox || inbox.isPermanent || !inbox.ttlHours) {
45 return [] as TempMailboxTtlHours[];
46 }
47 
48 const currentTtlHours = inbox.ttlHours;
49 return TEMP_MAILBOX_TTL_HOURS.filter((hours) => hours > currentTtlHours);
50 }, [inbox]);
51 
52 const isAdminInspectingTemporaryInbox = adminMode && inbox !== null && !inbox.isPermanent;
53 const canDeleteEmail = !adminMode || inbox?.isPermanent === true;
54 
55 const handleCopy = async () => {
56 try {
57 await navigator.clipboard.writeText(address);
58 toast.success("Address copied to clipboard");
59 } catch {
60 toast.error("Could not copy the inbox address.");
61 }
62 };
63 
64 const handleDeleteInbox = async () => {
65 if (!session || !inbox || inbox.isPermanent) {
66 return;
67 }
68 
69 const confirmed = window.confirm(
70 adminMode
71 ? `Admin delete ${address} and all stored email? This cannot be undone.`
72 : `Delete ${address} and all stored email?`,
73 );
74 if (!confirmed) {
75 return;
76 }
77 
78 try {
79 await deleteInbox(address, session.auth);
80 removeInboxSession(address);
81 onDeleted(address);
82 toast.success("Inbox deleted");
83 navigate(adminMode ? "/admin" : "/");
84 } catch (error) {
85 toast.error(getErrorMessage(error));
86 }
87 };
88 
89 const handleExtendInbox = async (ttlHours: TempMailboxTtlHours) => {
90 if (!session || !inbox || inbox.isPermanent) {
91 return;
92 }
93 
94 setExtendingTo(ttlHours);
95 
96 try {
97 const updated = await extendInbox(address, session.auth, ttlHours);
98 updateInboxSession(address, {
99 expiresAt: updated.expiresAt,
100 ttlHours: updated.ttlHours,
101 });
102 await refreshInbox();
103 toast.success(`Inbox extended to ${ttlHours}h`);
104 } catch (error) {
105 toast.error(getErrorMessage(error));
106 } finally {
107 setExtendingTo(null);
108 }
109 };
110 
111 const handleBackToList = () => {
112 void selectEmail("");
113 };
114 
115 return {
116 availableExtensions,
117 canDeleteEmail,
118 extendingTo,
119 isAdminInspectingTemporaryInbox,
120 handleBackToList,
121 handleCopy,
122 handleDeleteInbox,
123 handleExtendInbox,
124 };
125}