feat: order creation page and link from player detail service cards

This commit is contained in:
zetaloop
2026-02-20 18:37:33 +08:00
parent 91d1694bcd
commit 10abe5309e
2 changed files with 181 additions and 1 deletions
+178
View File
@@ -0,0 +1,178 @@
"use client"
import { ArrowLeft, CheckCircle, CreditCard, ShieldCheck } from "lucide-react"
import Link from "next/link"
import { useSearchParams } from "next/navigation"
import { useState } from "react"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"
import { Textarea } from "@/components/ui/textarea"
import { mockPlayers, mockServices, walletBalance } from "@/lib/mock-data"
export default function NewOrderPage() {
const searchParams = useSearchParams()
const serviceId = searchParams.get("serviceId")
const service = mockServices.find((s) => s.id === serviceId)
const player = service ? mockPlayers.find((p) => p.id === service.playerId) : null
const [quantity, setQuantity] = useState(1)
const [note, setNote] = useState("")
const [submitted, setSubmitted] = useState(false)
if (!service || !player) {
return (
<div className="container mx-auto py-8 px-4 text-center text-muted-foreground">
</div>
)
}
const totalPrice = service.price * quantity
if (submitted) {
return (
<div className="container mx-auto py-8 px-4 max-w-lg text-center space-y-4">
<CheckCircle className="h-12 w-12 mx-auto text-green-500" />
<h2 className="text-xl font-bold"></h2>
<p className="text-sm text-muted-foreground">
</p>
<div className="flex gap-2 justify-center">
<Button asChild>
<Link href="/orders"></Link>
</Button>
<Button variant="outline" asChild>
<Link href={`/player/${player.id}`}></Link>
</Button>
</div>
</div>
)
}
return (
<div className="container mx-auto py-8 px-4 max-w-2xl">
<Link
href={`/player/${player.id}`}
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground mb-4"
>
<ArrowLeft className="h-4 w-4" />
</Link>
<h1 className="text-2xl font-bold mb-6"></h1>
<div className="space-y-6">
<Card>
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center gap-3">
<Avatar className="h-10 w-10">
<AvatarImage src={player.user.avatar} />
<AvatarFallback>{player.user.nickname[0]}</AvatarFallback>
</Avatar>
<div>
<p className="font-medium">{player.user.nickname}</p>
<p className="text-xs text-muted-foreground">
{player.shopName ? `${player.shopName} · ` : ""}
{service.gameName}
</p>
</div>
</div>
<Separator />
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-muted-foreground"></span>
<span>{service.title}</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground"></span>
<span>
¥{service.price}/{service.unit}
</span>
</div>
{service.rankRange && (
<div className="flex justify-between">
<span className="text-muted-foreground"></span>
<span>{service.rankRange}</span>
</div>
)}
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="quantity">{service.unit}</Label>
<Input
id="quantity"
type="number"
min={1}
max={99}
value={quantity}
onChange={(e) => setQuantity(Math.max(1, Number.parseInt(e.target.value, 10) || 1))}
/>
</div>
<div className="space-y-2">
<Label htmlFor="note"></Label>
<Textarea
id="note"
placeholder="例如:希望晚上8点后开始"
value={note}
onChange={(e) => setNote(e.target.value)}
rows={3}
/>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">
{service.title} × {quantity}
</span>
<span>¥{totalPrice}</span>
</div>
<Separator />
<div className="flex justify-between font-medium">
<span></span>
<span className="text-lg text-primary">¥{totalPrice}</span>
</div>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<CreditCard className="h-4 w-4" />
<span>: ¥{walletBalance}</span>
{walletBalance < totalPrice && <span className="text-destructive"></span>}
</div>
<div className="flex items-center gap-2 text-xs text-muted-foreground">
<ShieldCheck className="h-3.5 w-3.5" />
<span></span>
</div>
</CardContent>
</Card>
<Button
className="w-full"
size="lg"
disabled={walletBalance < totalPrice}
onClick={() => setSubmitted(true)}
>
¥{totalPrice}
</Button>
</div>
</div>
)
}