"use client"; import { FormEvent, useEffect, useMemo, useState } from "react"; import { useTranslation } from "@/i18n/navigation"; import Footer from "@/app/components/Footer"; import { apiFetch } from "@/app/lib/api-client"; interface Gig { id: string; title: string; category: string; budget: number; location: string; description: string; status: "open" | "in_progress" | "done" | string; } const INITIAL_FORM = { title: "", category: "内容", budget: 500, location: "远程", description: "", }; const STATUS_LABELS: Record = { open: "可接单", in_progress: "进行中", done: "已完成", }; export default function GigsPage() { const { t } = useTranslation("gigs"); const [gigs, setGigs] = useState([]); const [form, setForm] = useState(INITIAL_FORM); const [showForm, setShowForm] = useState(false); const [status, setStatus] = useState(""); const [submitting, setSubmitting] = useState(false); const [applyingId, setApplyingId] = useState(null); const openGigs = useMemo(() => gigs.filter((gig) => gig.status === "open"), [gigs]); const activeGigs = useMemo(() => gigs.filter((gig) => gig.status !== "open"), [gigs]); const loadGigs = () => { apiFetch<{ items: Gig[] }>("/api/gigs") .then((data) => setGigs(data.items || [])) .catch(() => setGigs([])); }; useEffect(() => { loadGigs(); }, []); const submitGig = async (event: FormEvent) => { event.preventDefault(); if (!form.title.trim()) { setStatus("请先填写任务标题"); return; } setSubmitting(true); setStatus(""); try { const data = await apiFetch<{ record: Gig }>("/api/gigs", { method: "POST", body: JSON.stringify(form), }); setGigs((prev) => [data.record, ...prev]); setForm(INITIAL_FORM); setShowForm(false); setStatus("任务已发布,已写入 PocketBase。"); } catch (error) { setStatus(error instanceof Error ? error.message : "发布失败"); } finally { setSubmitting(false); } }; const applyGig = async (gig: Gig) => { setApplyingId(gig.id); setStatus(""); try { const data = await apiFetch<{ record: Gig; message: string }>(`/api/gigs/${gig.id}/apply`, { method: "POST", }); setGigs((prev) => prev.map((item) => (item.id === gig.id ? data.record : item))); setStatus(`${gig.title}:${data.message}`); } catch (error) { setStatus(error instanceof Error ? error.message : "接单失败"); } finally { setApplyingId(null); } }; const renderGig = (gig: Gig) => (
{gig.category} {STATUS_LABELS[gig.status] || gig.status}

{gig.title}

📍 {gig.location} · ¥{Number(gig.budget || 0).toLocaleString()}

{gig.description || "需求方暂未填写详细说明,接单后可继续沟通。"}

); return (

{t("title")}

{t("subtitle")} · {t("platformFee")}

{showForm && (