feat: 添加分享结果卡片功能,形成用户增长闭环
- 新增 ShareCardModal 组件,支持餐厅匹配和盲盒契约两种分享卡片 - 卡片包含品牌标识、匹配结果、餐厅/想法详情、二维码 - 使用 html-to-image 生成高清 PNG,支持保存图片和 Web Share API 分享 - 餐厅图片通过 canvas 转 data URL 处理跨域 - 集成到 MatchResult(极速救场)和 BlindBox reveal(周末契约)
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
} from "lucide-react";
|
||||
import confetti from "canvas-confetti";
|
||||
import { getCachedProfile, isRegistered } from "@/lib/userId";
|
||||
import ShareCardModal from "@/components/ShareCardModal";
|
||||
import type { UserProfile } from "@/types";
|
||||
|
||||
interface RoomInfo {
|
||||
@@ -57,6 +58,7 @@ export default function BlindboxRoomPage() {
|
||||
const [submitFlash, setSubmitFlash] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [showInvite, setShowInvite] = useState(false);
|
||||
const [showShareCard, setShowShareCard] = useState(false);
|
||||
const [toast, setToast] = useState("");
|
||||
|
||||
const boxControls = useAnimation();
|
||||
@@ -522,13 +524,23 @@ export default function BlindboxRoomPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<motion.button
|
||||
onClick={() => { setPhase("pool"); setRevealedIdea(null); }}
|
||||
className="flex h-10 items-center gap-2 rounded-full bg-surface px-5 text-xs font-semibold text-muted ring-1 ring-border transition-colors hover:bg-elevated"
|
||||
whileTap={{ scale: 0.96 }}
|
||||
>
|
||||
继续投入想法
|
||||
</motion.button>
|
||||
<div className="flex items-center gap-3">
|
||||
<motion.button
|
||||
onClick={() => setShowShareCard(true)}
|
||||
className="flex h-10 items-center gap-2 rounded-full bg-purple-600 px-5 text-xs font-bold text-white shadow-lg shadow-purple-900/30 transition-colors hover:bg-purple-500"
|
||||
whileTap={{ scale: 0.96 }}
|
||||
>
|
||||
<Share2 size={14} />
|
||||
分享契约
|
||||
</motion.button>
|
||||
<motion.button
|
||||
onClick={() => { setPhase("pool"); setRevealedIdea(null); setShowShareCard(false); }}
|
||||
className="flex h-10 items-center gap-2 rounded-full bg-surface px-5 text-xs font-semibold text-muted ring-1 ring-border transition-colors hover:bg-elevated"
|
||||
whileTap={{ scale: 0.96 }}
|
||||
>
|
||||
继续投入想法
|
||||
</motion.button>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
@@ -590,6 +602,24 @@ export default function BlindboxRoomPage() {
|
||||
</>
|
||||
)}
|
||||
|
||||
{revealedIdea && room && (
|
||||
<ShareCardModal
|
||||
open={showShareCard}
|
||||
onClose={() => setShowShareCard(false)}
|
||||
data={{
|
||||
type: "blindbox",
|
||||
idea: revealedIdea.content,
|
||||
submitter: revealedIdea.user ?? undefined,
|
||||
drawer: revealedIdea.drawnBy ?? undefined,
|
||||
roomName: room.name,
|
||||
}}
|
||||
onToast={(msg) => {
|
||||
setToast(msg);
|
||||
setTimeout(() => setToast(""), 2200);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Toast */}
|
||||
<AnimatePresence>
|
||||
{toast && (
|
||||
|
||||
Reference in New Issue
Block a user