Files
juwan-frontend/app/(order)/order/new/page.tsx
T
2026-02-20 22:45:38 +08:00

202 lines
7.2 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.
"use client"
import { ArrowLeft, CheckCircle, CreditCard, ShieldCheck } from "lucide-react"
import Link from "next/link"
import { useRouter, 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 { mockOrders, mockPlayers, mockServices, walletBalance } from "@/lib/mock-data"
import { useRequireAuth } from "@/lib/use-require-auth"
function showFeedback(message: string) {
if (typeof window === "undefined") return
window.alert(message)
}
export default function NewOrderPage() {
const router = useRouter()
const searchParams = useSearchParams()
const { requireAuth } = useRequireAuth()
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
const redirectOrderId =
mockOrders.find((order) => order.service.id === service.id)?.id ?? mockOrders[0]?.id
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={() =>
requireAuth(async () => {
await new Promise((resolve) => setTimeout(resolve, 500))
setSubmitted(true)
showFeedback("下单成功")
if (redirectOrderId) {
setTimeout(() => {
router.push(`/order/${redirectOrderId}`)
}, 800)
return
}
router.push("/orders")
})
}
>
¥{totalPrice}
</Button>
</div>
</div>
)
}