fix: 0 票最佳匹配时展示"都不太满意"引导页,替代尴尬的 Trophy 展示
This commit is contained in:
@@ -32,9 +32,15 @@ export async function GET(
|
|||||||
matchLikes = data.users.length;
|
matchLikes = data.users.length;
|
||||||
} else if (allFinished && data.restaurants.length > 0) {
|
} else if (allFinished && data.restaurants.length > 0) {
|
||||||
const best = findBestMatch(data.likes, data.restaurants);
|
const best = findBestMatch(data.likes, data.restaurants);
|
||||||
|
if (best.likes > 0) {
|
||||||
match = best.id;
|
match = best.id;
|
||||||
matchType = "best";
|
matchType = "best";
|
||||||
matchLikes = best.likes;
|
matchLikes = best.likes;
|
||||||
|
} else {
|
||||||
|
match = best.id;
|
||||||
|
matchType = "no_match";
|
||||||
|
matchLikes = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const likeCounts: Record<string, number> = {};
|
const likeCounts: Record<string, number> = {};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import {
|
import {
|
||||||
MapPin,
|
MapPin,
|
||||||
Star,
|
Star,
|
||||||
@@ -10,6 +11,8 @@ import {
|
|||||||
Clock,
|
Clock,
|
||||||
Trophy,
|
Trophy,
|
||||||
RotateCcw,
|
RotateCcw,
|
||||||
|
SearchX,
|
||||||
|
Home,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Restaurant, MatchType } from "@/types";
|
import { Restaurant, MatchType } from "@/types";
|
||||||
|
|
||||||
@@ -30,6 +33,77 @@ function buildNavUrl(restaurant: Restaurant): string {
|
|||||||
return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(restaurant.name)}`;
|
return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(restaurant.name)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NoMatchResult({
|
||||||
|
onReset,
|
||||||
|
resetting,
|
||||||
|
}: {
|
||||||
|
onReset: () => Promise<void>;
|
||||||
|
resetting: boolean;
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-linear-to-b from-zinc-600 to-zinc-800 px-6 py-10"
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.4 }}
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
initial={{ scale: 0, rotate: -20 }}
|
||||||
|
animate={{ scale: 1, rotate: 0 }}
|
||||||
|
transition={{ type: "spring", stiffness: 200, damping: 12, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<SearchX size={56} className="text-zinc-400" />
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.h1
|
||||||
|
className="mt-4 text-3xl font-black text-white"
|
||||||
|
initial={{ y: 30, opacity: 0 }}
|
||||||
|
animate={{ y: 0, opacity: 1 }}
|
||||||
|
transition={{ delay: 0.35 }}
|
||||||
|
>
|
||||||
|
都不太满意
|
||||||
|
</motion.h1>
|
||||||
|
|
||||||
|
<motion.p
|
||||||
|
className="mt-2 max-w-[16rem] text-center text-sm leading-relaxed text-zinc-400"
|
||||||
|
initial={{ y: 20, opacity: 0 }}
|
||||||
|
animate={{ y: 0, opacity: 1 }}
|
||||||
|
transition={{ delay: 0.45 }}
|
||||||
|
>
|
||||||
|
这一轮没有餐厅被选中,换个范围或菜系再试试?
|
||||||
|
</motion.p>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="mt-8 flex w-full max-w-xs flex-col gap-3"
|
||||||
|
initial={{ y: 30, opacity: 0 }}
|
||||||
|
animate={{ y: 0, opacity: 1 }}
|
||||||
|
transition={{ delay: 0.55 }}
|
||||||
|
>
|
||||||
|
<motion.button
|
||||||
|
onClick={onReset}
|
||||||
|
disabled={resetting}
|
||||||
|
className="flex items-center justify-center gap-2 rounded-full bg-white px-8 py-3 text-sm font-bold text-zinc-800 shadow-lg transition-colors hover:bg-zinc-100 disabled:opacity-50"
|
||||||
|
whileTap={{ scale: 0.95 }}
|
||||||
|
>
|
||||||
|
<RotateCcw size={15} className={resetting ? "animate-spin" : ""} />
|
||||||
|
{resetting ? "重置中..." : "再来一轮"}
|
||||||
|
</motion.button>
|
||||||
|
|
||||||
|
<motion.button
|
||||||
|
onClick={() => router.push("/")}
|
||||||
|
className="flex items-center justify-center gap-2 rounded-full bg-white/15 px-8 py-3 text-sm font-bold text-white backdrop-blur-sm transition-colors hover:bg-white/25"
|
||||||
|
whileTap={{ scale: 0.95 }}
|
||||||
|
>
|
||||||
|
<Home size={15} />
|
||||||
|
换个条件重新搜
|
||||||
|
</motion.button>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function MatchResult({
|
export default function MatchResult({
|
||||||
restaurant,
|
restaurant,
|
||||||
matchType,
|
matchType,
|
||||||
@@ -38,6 +112,10 @@ export default function MatchResult({
|
|||||||
onReset,
|
onReset,
|
||||||
resetting,
|
resetting,
|
||||||
}: MatchResultProps) {
|
}: MatchResultProps) {
|
||||||
|
if (matchType === "no_match") {
|
||||||
|
return <NoMatchResult onReset={onReset} resetting={resetting} />;
|
||||||
|
}
|
||||||
|
|
||||||
const isUnanimous = matchType === "unanimous";
|
const isUnanimous = matchType === "unanimous";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ export interface Restaurant {
|
|||||||
|
|
||||||
export type SwipeDirection = "left" | "right";
|
export type SwipeDirection = "left" | "right";
|
||||||
|
|
||||||
export type MatchType = "unanimous" | "best" | null;
|
export type MatchType = "unanimous" | "best" | "no_match" | null;
|
||||||
|
|
||||||
export interface RoomStatus {
|
export interface RoomStatus {
|
||||||
roomId: string;
|
roomId: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user