File
Blob: src/client/hooks/useInboxPageActions.ts
| 1 | import { useMemo, useState } from "react"; |
| 2 | import { useNavigate } from "react-router-dom"; |
| 3 | import { toast } from "@/client/components/toast"; |
| 4 | import { |
| 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 | |
| 16 | interface SessionTarget { |
| 17 | address: string; |
| 18 | auth: AuthDescriptor; |
| 19 | } |
| 20 | |
| 21 | interface 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 | |
| 31 | export 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 | } |