fix(ui): unify layout wrappers and simplify player/shop detail pages

This commit is contained in:
zetaloop
2026-02-23 11:05:29 +08:00
parent c986539954
commit 4fce328ef1
11 changed files with 79 additions and 79 deletions
+18 -10
View File
@@ -14,7 +14,7 @@ import {
} from "lucide-react"
import Link from "next/link"
import { useRouter, useSearchParams } from "next/navigation"
import { Suspense, useEffect, useMemo, useState } from "react"
import { Suspense, useEffect, useMemo, useState, useDeferredValue } from "react"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
@@ -309,7 +309,14 @@ function FilterSection({
<Separator />
<div className="space-y-3">
<h3 className="font-medium text-sm"> ()</h3>
<h3 className="font-medium text-sm flex items-center gap-2">
()
{(priceRange.min || priceRange.max) && (
<Badge variant="secondary" className="text-[10px] px-1.5 py-0 font-normal">
¥{priceRange.min || "-"} - ¥{priceRange.max || "-"}
</Badge>
)}
</h3>
<div className="flex items-center gap-2">
<Input
type="number"
@@ -381,6 +388,7 @@ function SearchPageContent() {
min: "",
max: "",
})
const deferredPriceRange = useDeferredValue(priceRange)
const [onlyOnline, setOnlyOnline] = useState(false)
const [minRating, setMinRating] = useState("0")
const [sortBy, setSortBy] = useState("composite")
@@ -445,12 +453,12 @@ function SearchPageContent() {
if (!hasGame) return false
}
const minP = priceRange.min ? Number(priceRange.min) : 0
const maxP = priceRange.max ? Number(priceRange.max) : Infinity
const minP = deferredPriceRange.min ? Number(deferredPriceRange.min) : 0
const maxP = deferredPriceRange.max ? Number(deferredPriceRange.max) : Infinity
const playerMinPrice = Math.min(...player.services.map((s) => s.price))
if (playerMinPrice < minP) return false
if (priceRange.max && playerMinPrice > maxP) return false
if (deferredPriceRange.max && playerMinPrice > maxP) return false
if (onlyOnline && player.status !== "available") return false
@@ -458,7 +466,7 @@ function SearchPageContent() {
return true
})
}, [minRating, onlyOnline, players, priceRange, searchQuery, selectedGames])
}, [minRating, onlyOnline, players, deferredPriceRange, searchQuery, selectedGames])
const filteredShops = useMemo(() => {
return shopResultItems.filter((item) => {
@@ -475,17 +483,17 @@ function SearchPageContent() {
if (!hasGame) return false
}
const minP = priceRange.min ? Number(priceRange.min) : 0
const maxP = priceRange.max ? Number(priceRange.max) : Infinity
const minP = deferredPriceRange.min ? Number(deferredPriceRange.min) : 0
const maxP = deferredPriceRange.max ? Number(deferredPriceRange.max) : Infinity
if (item.minPrice < minP) return false
if (priceRange.max && item.minPrice > maxP) return false
if (deferredPriceRange.max && item.minPrice > maxP) return false
if (onlyOnline && !item.hasAvailable) return false
if (item.shop.rating < Number(minRating)) return false
return true
})
}, [shopResultItems, searchQuery, selectedGames, priceRange, onlyOnline, minRating])
}, [shopResultItems, searchQuery, selectedGames, deferredPriceRange, onlyOnline, minRating])
const sortedResults = useMemo<SearchResult[]>(() => {
const playerResults: SearchResult[] = filteredPlayers.map((player) => ({