Files
juwan-frontend/app/(main)/page.tsx
T

190 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ArrowRight, Search, ShoppingBag, Star } from "lucide-react"
import Link from "next/link"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { listGames, listPlayers, listShops } from "@/lib/api"
import { GameIcon } from "@/lib/game-icons"
export default function HomePage() {
const games = listGames()
const players = listPlayers()
const shops = listShops()
return (
<div className="container mx-auto py-8 px-4 space-y-12">
<section className="relative overflow-hidden rounded-3xl bg-linear-to-b from-primary/10 via-primary/5 to-transparent px-6 py-16 md:py-24 text-center">
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-10">
<div className="absolute top-[-10%] left-[-10%] w-[40%] h-[40%] rounded-full bg-primary/10 blur-[100px]" />
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] rounded-full bg-primary/10 blur-[100px]" />
</div>
<div className="relative z-10 space-y-8 max-w-3xl mx-auto">
<div className="space-y-4">
<h1 className="text-4xl md:text-6xl font-bold tracking-tighter leading-tight"></h1>
<p className="text-lg md:text-xl text-muted-foreground leading-relaxed">
</p>
</div>
<div id="discover-search" className="w-full max-w-2xl mx-auto">
<form method="get" action="/search" className="relative flex items-center w-full">
<Search className="absolute left-4 h-5 w-5 text-muted-foreground z-10" />
<Input
type="text"
name="q"
placeholder="搜索陪玩、店铺、游戏..."
className="w-full h-14 pl-12 pr-32 rounded-full text-base shadow-sm bg-background"
/>
<Button type="submit" size="lg" className="absolute right-1.5 rounded-full px-8 h-11">
</Button>
</form>
</div>
</div>
</section>
<section>
<div className="flex items-center justify-between mb-4">
<h2 className="text-xl font-semibold"></h2>
<Button variant="ghost" size="sm" asChild>
<Link href="/search">
<ArrowRight className="ml-1 h-4 w-4" />
</Link>
</Button>
</div>
<div className="flex flex-wrap gap-3">
{games.map((game) => (
<Link
key={game.id}
href={`/search?game=${encodeURIComponent(game.name)}`}
className="flex items-center gap-2 rounded-full border bg-card px-4 py-2 hover:bg-accent/50 hover:shadow-sm transition-all"
>
<GameIcon name={game.icon} className="h-5 w-5" />
<span className="text-sm font-medium">{game.name}</span>
</Link>
))}
</div>
</section>
<section className="space-y-6">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<h2 className="text-xl font-semibold"></h2>
<div className="flex flex-wrap items-center gap-2 text-sm">
<Link href="/search?sort=composite" className="text-primary font-medium"></Link>
<span className="text-muted-foreground/30">|</span>
<Link href="/search?sort=rating" className="text-muted-foreground hover:text-foreground transition-colors"></Link>
<span className="text-muted-foreground/30">|</span>
<Link href="/search?sort=orders" className="text-muted-foreground hover:text-foreground transition-colors"></Link>
<span className="text-muted-foreground/30">|</span>
<Link href="/search?sort=price_asc" className="text-muted-foreground hover:text-foreground transition-colors"></Link>
<span className="text-muted-foreground/30">|</span>
<Link href="/search?sort=price_desc" className="text-muted-foreground hover:text-foreground transition-colors"></Link>
</div>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{/* Players */}
{players.map((player) => (
<Card
key={player.id}
className="hover:shadow-md transition-shadow flex flex-col h-full"
>
<CardHeader className="flex flex-row items-center gap-3 space-y-0 pb-3">
<Avatar className="h-12 w-12">
<AvatarImage src={player.user.avatar} />
<AvatarFallback>{player.user.nickname[0]}</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<CardTitle className="text-base">{player.user.nickname}</CardTitle>
<div className="flex items-center gap-2 mt-1">
<div className="flex items-center text-sm">
<Star className="h-3.5 w-3.5 fill-yellow-400 text-yellow-400 mr-0.5" />
{player.rating}
</div>
<span className="text-xs text-muted-foreground">{player.totalOrders} </span>
<Badge
variant={player.status === "available" ? "default" : "secondary"}
className="text-[10px] px-1.5 py-0"
>
{player.status === "available"
? "可接单"
: player.status === "busy"
? "忙碌"
: "离线"}
</Badge>
</div>
</div>
</CardHeader>
<CardContent className="pb-3 flex-grow">
<div className="flex flex-wrap gap-1">
{player.tags.map((tag) => (
<Badge key={tag} variant="outline" className="text-xs">
{tag}
</Badge>
))}
</div>
{player.shopName && (
<p className="text-xs text-muted-foreground mt-2">: {player.shopName}</p>
)}
</CardContent>
<CardFooter className="pt-0">
<Button variant="outline" size="sm" className="w-full" asChild>
<Link href={`/player/${player.id}`}></Link>
</Button>
</CardFooter>
</Card>
))}
{/* Community Teaser */}
<Card className="hover:shadow-md transition-shadow flex flex-col h-full bg-primary/5 border-primary/20">
<CardHeader>
<CardTitle className="text-lg"></CardTitle>
<p className="text-sm text-muted-foreground"></p>
</CardHeader>
<CardContent className="flex-grow flex items-center justify-center">
<div className="w-24 h-24 rounded-full bg-primary/10 flex items-center justify-center">
<Star className="h-10 w-10 text-primary" />
</div>
</CardContent>
<CardFooter>
<Button className="w-full" asChild>
<Link href="/community"></Link>
</Button>
</CardFooter>
</Card>
{/* Shops */}
{shops.map((shop) => (
<Card key={shop.id} className="hover:shadow-md transition-shadow flex flex-col h-full">
<CardHeader>
<CardTitle className="text-lg">{shop.name}</CardTitle>
<p className="text-sm text-muted-foreground">{shop.description}</p>
</CardHeader>
<CardContent className="flex-grow">
<div className="flex items-center gap-4 text-sm">
<div className="flex items-center">
<Star className="h-3.5 w-3.5 fill-yellow-400 text-yellow-400 mr-0.5" />
{shop.rating}
</div>
<div className="flex items-center text-muted-foreground">
<ShoppingBag className="h-3.5 w-3.5 mr-0.5" />
{shop.totalOrders}
</div>
<span className="text-muted-foreground">{shop.playerCount} </span>
</div>
</CardContent>
<CardFooter>
<Button variant="outline" size="sm" className="w-full" asChild>
<Link href={`/shop/${shop.id}`}></Link>
</Button>
</CardFooter>
</Card>
))}
</div>
</section>
</div>
)
}