90 lines
3.0 KiB
TypeScript
90 lines
3.0 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import Link from "next/link";
|
||
import { api } from "@/lib/api";
|
||
import { useAuth } from "@/lib/auth";
|
||
import { useToast } from "@/lib/toast";
|
||
import { useI18n } from "@/lib/i18n";
|
||
import RingNext from "@/components/RingNext";
|
||
import { useRingSteps } from "@/lib/rings";
|
||
|
||
export default function FeedbackClient() {
|
||
const { token } = useAuth();
|
||
const { toast } = useToast();
|
||
const { t } = useI18n();
|
||
const rings = useRingSteps();
|
||
const [content, setContent] = useState("");
|
||
const [category, setCategory] = useState("general");
|
||
const [loading, setLoading] = useState(false);
|
||
const [done, setDone] = useState(false);
|
||
|
||
const submit = async () => {
|
||
if (!content.trim() || content.trim().length < 5) {
|
||
toast("请至少写 5 个字", "info");
|
||
return;
|
||
}
|
||
setLoading(true);
|
||
try {
|
||
await api.submitFeedback(content.trim(), token || undefined, category);
|
||
toast(t.feedback.ok, "success");
|
||
setContent("");
|
||
setDone(true);
|
||
} catch {
|
||
toast(t.feedback.fail, "error");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="community-page">
|
||
<div className="container">
|
||
<nav className="detail-nav">
|
||
<Link href="/">{t.common.backHome}</Link>
|
||
</nav>
|
||
<div className="section-header reveal">
|
||
<span className="section-tag">{t.feedback.tag}</span>
|
||
<h1>{t.feedback.title}</h1>
|
||
<p>{t.feedback.subtitle}</p>
|
||
</div>
|
||
{done ? (
|
||
<div className="dating-gate reveal">
|
||
<h2>已收到,谢谢</h2>
|
||
<p>我们会认真阅读每一条反馈</p>
|
||
<div className="dating-empty-actions">
|
||
<button type="button" className="btn btn-primary" onClick={() => setDone(false)}>
|
||
再写一条
|
||
</button>
|
||
<Link href="/community" className="btn">
|
||
去社区
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<div className="community-compose reveal">
|
||
<select value={category} onChange={(e) => setCategory(e.target.value)}>
|
||
<option value="general">{t.feedback.catGeneral}</option>
|
||
<option value="bug">{t.feedback.catBug}</option>
|
||
<option value="feature">{t.feedback.catFeature}</option>
|
||
<option value="safety">{t.feedback.catSafety}</option>
|
||
</select>
|
||
<textarea
|
||
rows={6}
|
||
placeholder={t.feedback.placeholder}
|
||
value={content}
|
||
onChange={(e) => setContent(e.target.value)}
|
||
maxLength={2000}
|
||
/>
|
||
<button type="button" className="btn btn-primary" disabled={loading} onClick={submit}>
|
||
{loading ? "提交中…" : t.feedback.submit}
|
||
</button>
|
||
{!token && <p className="section-desc">未登录也可提交;登录后便于我们回复你</p>}
|
||
</div>
|
||
)}
|
||
<RingNext steps={rings.afterGigs} />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|