diff --git a/app/(dashboard)/dashboard/services/new/page.tsx b/app/(dashboard)/dashboard/services/new/page.tsx index fbcb538..2a762e7 100644 --- a/app/(dashboard)/dashboard/services/new/page.tsx +++ b/app/(dashboard)/dashboard/services/new/page.tsx @@ -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>({ 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) => { + const game = mockGames.find((item) => item.id === data.gameId) + if (!game) return + + const payload: Omit = { + 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() {
- setValue("gameId", value)}> @@ -108,7 +167,7 @@ export default function NewServicePage() {
- setValue("unit", value)}> diff --git a/app/(dashboard)/dashboard/services/page.tsx b/app/(dashboard)/dashboard/services/page.tsx index 90bffbb..dd87fa4 100644 --- a/app/(dashboard)/dashboard/services/page.tsx +++ b/app/(dashboard)/dashboard/services/page.tsx @@ -1,3 +1,5 @@ +"use client" + import { Edit, Plus, Trash2 } from "lucide-react" import Link from "next/link" import { Badge } from "@/components/ui/badge" @@ -11,9 +13,12 @@ import { TableHeader, TableRow, } from "@/components/ui/table" -import { mockServices } from "@/lib/mock" +import { useServiceStore } from "@/store/services" export default function ServicesPage() { + const services = useServiceStore((state) => state.services) + const deleteService = useServiceStore((state) => state.deleteService) + return (
@@ -43,7 +48,7 @@ export default function ServicesPage() { - {mockServices.map((service) => ( + {services.map((service) => ( {service.title} @@ -63,11 +68,11 @@ export default function ServicesPage() {
-
diff --git a/store/services.ts b/store/services.ts new file mode 100644 index 0000000..c949693 --- /dev/null +++ b/store/services.ts @@ -0,0 +1,34 @@ +import { create } from "zustand" +import { mockServices } from "@/lib/mock" +import type { PlayerService } from "@/lib/types" + +interface ServiceState { + services: PlayerService[] + createService: (service: Omit) => void + updateService: (serviceId: string, patch: Partial>) => void + deleteService: (serviceId: string) => void +} + +export const useServiceStore = create((set) => ({ + services: mockServices, + createService: (service) => + set((state) => ({ + services: [ + ...state.services, + { + ...service, + id: `s${Date.now()}`, + }, + ], + })), + updateService: (serviceId, patch) => + set((state) => ({ + services: state.services.map((service) => + service.id === serviceId ? { ...service, ...patch } : service, + ), + })), + deleteService: (serviceId) => + set((state) => ({ + services: state.services.filter((service) => service.id !== serviceId), + })), +}))