From 503856a8a8e0a333c525ac4ddaf9a5e3f957c1e8 Mon Sep 17 00:00:00 2001 From: beilunyang <786220806@qq.com> Date: Sat, 18 Oct 2025 22:03:27 +0800 Subject: [PATCH] fix(shared-email): Improve date handling and error resilience in shared email page --- app/[locale]/shared/[token]/page-client.tsx | 130 ++++++++++++++---- app/[locale]/shared/[token]/page.tsx | 18 +-- app/components/emails/share-dialog.tsx | 4 +- .../emails/share-message-dialog.tsx | 4 +- 4 files changed, 110 insertions(+), 46 deletions(-) diff --git a/app/[locale]/shared/[token]/page-client.tsx b/app/[locale]/shared/[token]/page-client.tsx index 8d52598..5625a95 100644 --- a/app/[locale]/shared/[token]/page-client.tsx +++ b/app/[locale]/shared/[token]/page-client.tsx @@ -11,8 +11,8 @@ import { EMAIL_CONFIG } from "@/config" interface Email { id: string address: string - createdAt: string - expiresAt: string + createdAt: Date + expiresAt: Date } interface Message { @@ -20,8 +20,8 @@ interface Message { from_address?: string to_address?: string subject: string - received_at?: string - sent_at?: string + received_at?: Date + sent_at?: Date } interface MessageDetail extends Message { @@ -37,16 +37,16 @@ interface SharedEmailPageClientProps { token: string } -export function SharedEmailPageClient({ - email, - initialMessages, +export function SharedEmailPageClient({ + email, + initialMessages, initialNextCursor, initialTotal, - token + token }: SharedEmailPageClientProps) { const t = useTranslations("emails") const tShared = useTranslations("emails.shared") - + const [messages, setMessages] = useState(initialMessages) const [selectedMessage, setSelectedMessage] = useState(null) const [messageLoading, setMessageLoading] = useState(false) @@ -75,12 +75,12 @@ export function SharedEmailPageClient({ const messagesResponse = await fetch(url) if (messagesResponse.ok) { - const messagesData = await messagesResponse.json() as { + const messagesData = await messagesResponse.json() as { messages: Message[] nextCursor: string | null total: number } - + if (!cursor) { // 刷新时:合并新消息和旧消息,避免重复 const newMessages = messagesData.messages @@ -144,7 +144,7 @@ export function SharedEmailPageClient({ return () => { stopPolling() } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [token]) const handleLoadMore = () => { @@ -156,13 +156,13 @@ export function SharedEmailPageClient({ const fetchMessageDetail = async (messageId: string) => { try { setMessageLoading(true) - + const response = await fetch(`/api/shared/${token}/messages/${messageId}`) - + if (!response.ok) { throw new Error("Failed to load message") } - + const data = await response.json() as { message: MessageDetail } setSelectedMessage(data.message) } catch (err) { @@ -175,23 +175,47 @@ export function SharedEmailPageClient({ return (
- { + try { + const expiresDate = new Date(email.expiresAt) + if (isNaN(expiresDate.getTime())) return tShared("sharedMailbox") + return expiresDate.getFullYear() === 9999 + ? tShared("permanent") + : `${tShared("expiresAt")}: ${expiresDate.toLocaleDateString()} ${expiresDate.toLocaleTimeString()}` + } catch { + return tShared("sharedMailbox") + } + })()} showCta={true} ctaText={tShared("createOwnEmail")} /> - + {/* 桌面端双栏布局 */}
({ ...msg, - received_at: msg.received_at ? new Date(msg.received_at as string).getTime() : undefined, - sent_at: msg.sent_at ? new Date(msg.sent_at as string).getTime() : undefined + received_at: (() => { + if (!msg.received_at) return undefined + try { + const date = new Date(msg.received_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })(), + sent_at: (() => { + if (!msg.sent_at) return undefined + try { + const date = new Date(msg.sent_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })() }))} selectedMessageId={selectedMessage?.id} onMessageSelect={fetchMessageDetail} @@ -216,8 +240,24 @@ export function SharedEmailPageClient({ { + if (!selectedMessage.received_at) return undefined + try { + const date = new Date(selectedMessage.received_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })(), + sent_at: (() => { + if (!selectedMessage.sent_at) return undefined + try { + const date = new Date(selectedMessage.sent_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })() } : null} loading={messageLoading} t={{ @@ -243,8 +283,24 @@ export function SharedEmailPageClient({ ({ ...msg, - received_at: msg.received_at ? new Date(msg.received_at as string).getTime() : undefined, - sent_at: msg.sent_at ? new Date(msg.sent_at as string).getTime() : undefined + received_at: (() => { + if (!msg.received_at) return undefined + try { + const date = new Date(msg.received_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })(), + sent_at: (() => { + if (!msg.sent_at) return undefined + try { + const date = new Date(msg.sent_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })() }))} selectedMessageId={null} onMessageSelect={fetchMessageDetail} @@ -279,8 +335,24 @@ export function SharedEmailPageClient({ { + if (!selectedMessage.received_at) return undefined + try { + const date = new Date(selectedMessage.received_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })(), + sent_at: (() => { + if (!selectedMessage.sent_at) return undefined + try { + const date = new Date(selectedMessage.sent_at) + return isNaN(date.getTime()) ? undefined : date.getTime() + } catch { + return undefined + } + })() }} loading={messageLoading} t={{ @@ -301,7 +373,7 @@ export function SharedEmailPageClient({
- +
) diff --git a/app/[locale]/shared/[token]/page.tsx b/app/[locale]/shared/[token]/page.tsx index 627c16c..960d4f1 100644 --- a/app/[locale]/shared/[token]/page.tsx +++ b/app/[locale]/shared/[token]/page.tsx @@ -13,10 +13,10 @@ interface PageProps { export default async function SharedEmailPage({ params }: PageProps) { const { token } = await params const tShared = await getTranslations("emails.shared") - + // 服务端获取数据 const email = await getSharedEmail(token) - + if (!email) { return ( ({ - ...msg, - received_at: msg.received_at?.toISOString(), - sent_at: msg.sent_at?.toISOString() - }))} + -
+
diff --git a/app/components/emails/share-message-dialog.tsx b/app/components/emails/share-message-dialog.tsx index 4afc543..a50b4b7 100644 --- a/app/components/emails/share-message-dialog.tsx +++ b/app/components/emails/share-message-dialog.tsx @@ -265,7 +265,7 @@ export function ShareMessageDialog({ emailId, messageId, messageSubject, trigger } }} className={cn( - "flex-1 text-xs p-1 rounded truncate font-mono transition-colors", + "flex-1 text-xs p-1 rounded font-mono transition-colors break-all", isExpired ? "bg-destructive/10 text-destructive/70 cursor-not-allowed pointer-events-none" : "bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:text-primary dark:hover:text-primary cursor-pointer" @@ -290,7 +290,7 @@ export function ShareMessageDialog({ emailId, messageId, messageSubject, trigger
-
+