diff --git a/ROADMAP.md b/ROADMAP.md
index 7b8d538..3b2197d 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -39,7 +39,7 @@
- `viewport-fit=cover` 适配刘海屏
### 首次体验引导优化
-- 极速救场完成一轮后引导注册("注册保存记录")
+- ~~极速救场完成一轮后引导注册("注册保存记录")~~(已完成,匹配成功页展示注册卡片,注册后自动保存记录)
- 盲盒模式先展示 demo / 动画,让用户看到价值再引导注册
- 统一两个模式的登录体验(目前极速救场不需登录,盲盒必须登录)
diff --git a/src/components/MatchResult.tsx b/src/components/MatchResult.tsx
index 2d84eb3..4be47f0 100644
--- a/src/components/MatchResult.tsx
+++ b/src/components/MatchResult.tsx
@@ -20,11 +20,13 @@ import {
Share2,
Zap,
Heart,
+ UserPlus,
} from "lucide-react";
-import { Restaurant, MatchType, RunnerUp, SceneType } from "@/types";
+import { Restaurant, MatchType, RunnerUp, SceneType, UserProfile } from "@/types";
import { fireCelebration, playChime } from "@/lib/celebrate";
import { isRegistered } from "@/lib/userId";
import ShareCardModal from "@/components/ShareCardModal";
+import AuthModal from "@/components/AuthModal";
interface MatchResultProps {
restaurant: Restaurant;
@@ -193,6 +195,8 @@ export default function MatchResult({
const isUnanimous = matchType === "unanimous";
const [favorited, setFavorited] = useState(false);
const [favLoading, setFavLoading] = useState(false);
+ const [registered, setRegistered] = useState(() => isRegistered());
+ const [showAuth, setShowAuth] = useState(false);
const showToast = useCallback((msg: string) => {
setToast(msg);
@@ -212,7 +216,7 @@ export default function MatchResult({
useEffect(() => {
if (historySavedRef.current) return;
- if (!isRegistered()) return;
+ if (!registered) return;
if (matchType === "no_match") return;
historySavedRef.current = true;
@@ -227,14 +231,20 @@ export default function MatchResult({
participants: userCount,
}),
}).catch(() => {});
- }, [userId, roomId, restaurant, matchType, userCount]);
+ }, [registered, userId, roomId, restaurant, matchType, userCount]);
const handleOpenShareCard = useCallback(() => {
setShowShareCard(true);
}, []);
+ const handleAuth = useCallback((profile: UserProfile) => {
+ setRegistered(true);
+ setShowAuth(false);
+ showToast(`欢迎,${profile.username}!记录已保存`);
+ }, [showToast]);
+
const handleFavorite = useCallback(async () => {
- if (!isRegistered() || favorited || favLoading) return;
+ if (!registered || favorited || favLoading) return;
setFavLoading(true);
try {
const res = await fetch("/api/user/favorite", {
@@ -250,7 +260,7 @@ export default function MatchResult({
/* ignore */
}
setFavLoading(false);
- }, [userId, restaurant, favorited, favLoading, showToast]);
+ }, [registered, userId, restaurant, favorited, favLoading, showToast]);
if (matchType === "no_match") {
return ;
@@ -344,7 +354,7 @@ export default function MatchResult({
animate={{ y: 0, opacity: 1 }}
transition={{ type: "spring", stiffness: 180, damping: 18, delay: 0.5 }}
>
- {isRegistered() && (
+ {registered && (
+ {/* Registration nudge */}
+ {!registered && (
+
+
+ 注册后,决策记录和收藏不会丢失
+
+
+ 仅需用户名 + 密码,10 秒完成
+
+ setShowAuth(true)}
+ className="mt-3 flex h-10 w-full items-center justify-center gap-2 rounded-xl bg-accent text-sm font-bold text-white shadow-lg shadow-accent/20 transition-colors hover:bg-accent-hover"
+ whileTap={{ scale: 0.95 }}
+ >
+
+ 注册保存记录
+
+
+ )}
+
{/* Runner ups */}
{!isUnanimous && runnerUpRestaurants.length > 0 && (
+ setShowAuth(false)}
+ onAuth={handleAuth}
+ defaultTab="register"
+ />
+
setShowShareCard(false)}