feat: make dashboard service management actionable
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
|
||||
import { ArrowLeft } from "lucide-react"
|
||||
import Link from "next/link"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { useRouter, useSearchParams } from "next/navigation"
|
||||
import { useEffect } from "react"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
import { Button } from "@/components/ui/button"
|
||||
@@ -20,8 +21,12 @@ import {
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { GameIcon } from "@/lib/game-icons"
|
||||
import { mockGames } from "@/lib/mock"
|
||||
import type { PlayerService } from "@/lib/types"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
import { useServiceStore } from "@/store/services"
|
||||
|
||||
const serviceSchema = z.object({
|
||||
gameId: z.string().min(1, "请选择游戏"),
|
||||
title: z.string().min(2, "标题至少2个字符"),
|
||||
description: z.string().min(10, "描述至少10个字符"),
|
||||
price: z.string().min(1, "请输入价格"),
|
||||
@@ -32,17 +37,71 @@ const serviceSchema = z.object({
|
||||
|
||||
export default function NewServicePage() {
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const serviceId = searchParams.get("serviceId")
|
||||
const userId = useAuthStore((state) => state.user?.id)
|
||||
const services = useServiceStore((state) => state.services)
|
||||
const createService = useServiceStore((state) => state.createService)
|
||||
const updateService = useServiceStore((state) => state.updateService)
|
||||
const editingService = services.find((service) => service.id === serviceId)
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
watch,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm({
|
||||
} = useForm<z.infer<typeof serviceSchema>>({
|
||||
resolver: standardSchemaResolver(serviceSchema),
|
||||
defaultValues: {
|
||||
gameId: "",
|
||||
title: "",
|
||||
description: "",
|
||||
price: "",
|
||||
unit: "",
|
||||
rankRange: "",
|
||||
availability: "",
|
||||
},
|
||||
})
|
||||
|
||||
const onSubmit = async () => {
|
||||
await new Promise((r) => setTimeout(r, 500))
|
||||
useEffect(() => {
|
||||
if (!editingService) return
|
||||
setValue("gameId", editingService.gameId)
|
||||
setValue("title", editingService.title)
|
||||
setValue("description", editingService.description)
|
||||
setValue("price", editingService.price.toString())
|
||||
setValue("unit", editingService.unit)
|
||||
setValue("rankRange", editingService.rankRange ?? "")
|
||||
setValue("availability", editingService.availability.join("、"))
|
||||
}, [editingService, setValue])
|
||||
|
||||
const selectedGameId = watch("gameId")
|
||||
const selectedUnit = watch("unit")
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof serviceSchema>) => {
|
||||
const game = mockGames.find((item) => item.id === data.gameId)
|
||||
if (!game) return
|
||||
|
||||
const payload: Omit<PlayerService, "id"> = {
|
||||
playerId: editingService?.playerId ?? userId ?? "u5",
|
||||
gameId: game.id,
|
||||
gameName: game.name,
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
price: Number(data.price),
|
||||
unit: data.unit as PlayerService["unit"],
|
||||
rankRange: data.rankRange?.trim() ? data.rankRange.trim() : undefined,
|
||||
availability: data.availability
|
||||
.split("、")
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean),
|
||||
}
|
||||
|
||||
if (editingService) {
|
||||
updateService(editingService.id, payload)
|
||||
} else {
|
||||
createService(payload)
|
||||
}
|
||||
|
||||
router.push("/dashboard/services")
|
||||
}
|
||||
|
||||
@@ -64,7 +123,7 @@ export default function NewServicePage() {
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Label>游戏</Label>
|
||||
<Select>
|
||||
<Select value={selectedGameId} onValueChange={(value) => setValue("gameId", value)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择游戏" />
|
||||
</SelectTrigger>
|
||||
@@ -108,7 +167,7 @@ export default function NewServicePage() {
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="unit">单位</Label>
|
||||
<Select onValueChange={(value) => setValue("unit", value)}>
|
||||
<Select value={selectedUnit} onValueChange={(value) => setValue("unit", value)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择单位" />
|
||||
</SelectTrigger>
|
||||
|
||||
Reference in New Issue
Block a user