feat: make dashboard service management actionable

This commit is contained in:
zetaloop
2026-02-21 15:47:30 +08:00
parent 3a1f9c2b7f
commit 94b96ac577
3 changed files with 108 additions and 10 deletions
@@ -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>