feat(sharing): add email and message sharing functionality

This commit is contained in:
beilunyang
2025-10-18 20:08:42 +08:00
parent 47d555eaf5
commit dbe8c42b11
45 changed files with 5669 additions and 38 deletions
@@ -0,0 +1,72 @@
"use client"
import { useTranslations } from "next-intl"
import { BrandHeader } from "@/components/ui/brand-header"
import { FloatingLanguageSwitcher } from "@/components/layout/floating-language-switcher"
import { SharedMessageDetail } from "@/components/emails/shared-message-detail"
interface MessageDetail {
id: string
from_address?: string
to_address?: string
subject: string
content?: string
html?: string
received_at?: Date
sent_at?: Date
expiresAt?: Date
emailAddress?: string
emailExpiresAt?: Date
}
interface SharedMessagePageClientProps {
message: MessageDetail
}
export function SharedMessagePageClient({ message }: SharedMessagePageClientProps) {
const t = useTranslations("emails")
const tShared = useTranslations("emails.shared")
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
<div className="container mx-auto p-4 max-w-7xl">
<BrandHeader
title={message.emailAddress || message.to_address || message.subject}
subtitle={message.emailExpiresAt && new Date(message.emailExpiresAt).getFullYear() === 9999
? tShared("permanent")
: message.emailExpiresAt
? `${tShared("expiresAt")}: ${new Date(message.emailExpiresAt).toLocaleString()}`
: tShared("sharedMessage")}
showCta={true}
ctaText={tShared("createOwnEmail")}
/>
<div className="mt-6">
<div className="border-2 border-primary/20 bg-background rounded-lg overflow-hidden h-[calc(100vh-260px)] lg:h-[calc(100vh-280px)]">
<SharedMessageDetail
message={{
...message,
received_at: message.received_at ? new Date(message.received_at).getTime() : undefined,
sent_at: message.sent_at ? new Date(message.sent_at).getTime() : undefined
}}
loading={false}
t={{
messageContent: t("layout.messageContent"),
selectMessage: t("layout.selectMessage"),
loading: tShared("loading"),
from: t("messageView.from"),
to: t("messageView.to"),
subject: t("messages.subject"),
time: t("messageView.time"),
htmlFormat: t("messageView.htmlFormat"),
textFormat: t("messageView.textFormat")
}}
/>
</div>
</div>
</div>
<FloatingLanguageSwitcher />
</div>
)
}
@@ -0,0 +1,33 @@
import { getTranslations } from "next-intl/server"
import { getSharedMessage } from "@/lib/shared-data"
import { SharedErrorPage } from "@/components/emails/shared-error-page"
import { SharedMessagePageClient } from "./page-client"
interface PageProps {
params: Promise<{
token: string
locale: string
}>
}
export default async function SharedMessagePage({ params }: PageProps) {
const { token } = await params
const tShared = await getTranslations("emails.shared")
// 服务端获取数据
const message = await getSharedMessage(token)
if (!message) {
return (
<SharedErrorPage
title={tShared("messageNotFound")}
subtitle={tShared("linkExpired")}
error={tShared("linkInvalid")}
description={tShared("linkInvalidDescription")}
ctaText={tShared("createOwnEmail")}
/>
)
}
return <SharedMessagePageClient message={message} />
}