feat: 类型帖互动、积分经济与发帖体验
补齐问答采纳/重开、投票匿名与有票禁编、悬赏过期退回、抽奖回帖开奖,并接入积分账本与发帖附件可见性。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
92
frontend/components/ContentLockGate.tsx
Normal file
92
frontend/components/ContentLockGate.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import { Lock } from "lucide-react";
|
||||
import { apiUnlockPost } from "@/lib/api";
|
||||
import { toast } from "@/lib/toast";
|
||||
|
||||
export default function ContentLockGate({
|
||||
postId,
|
||||
hint,
|
||||
access,
|
||||
points,
|
||||
loggedIn,
|
||||
}: {
|
||||
postId: number;
|
||||
hint?: string;
|
||||
access?: string;
|
||||
points?: number;
|
||||
loggedIn: boolean;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
const unlock = async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
const res = await apiUnlockPost(String(postId));
|
||||
if (res.post) {
|
||||
toast("已解锁全文", "ok");
|
||||
router.refresh();
|
||||
} else {
|
||||
toast(res.error || "解锁失败", "error");
|
||||
}
|
||||
} catch {
|
||||
toast("解锁失败", "error");
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="rounded-[14px] px-6 py-10 text-center my-4"
|
||||
style={{
|
||||
background: "var(--accent-soft)",
|
||||
border: "1px solid color-mix(in srgb, var(--accent) 20%, transparent)",
|
||||
}}
|
||||
>
|
||||
<Lock size={28} className="mx-auto mb-3" style={{ color: "var(--accent)" }} />
|
||||
<p className="font-bold text-[16px] mb-1" style={{ color: "var(--ink)" }}>
|
||||
{hint || "正文暂不可见"}
|
||||
</p>
|
||||
<p className="meta text-[13px] mb-5">
|
||||
{access === "points"
|
||||
? `支付 ${points || 0} 积分后可阅读全文`
|
||||
: access === "reply"
|
||||
? "发表一条回复后即可阅读全文"
|
||||
: access === "login"
|
||||
? "登录后即可阅读全文"
|
||||
: null}
|
||||
</p>
|
||||
{access === "login" && !loggedIn && (
|
||||
<Link
|
||||
href={`/login?redirect=${encodeURIComponent(`/post/${postId}`)}`}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
去登录
|
||||
</Link>
|
||||
)}
|
||||
{access === "points" && loggedIn && (
|
||||
<button type="button" className="btn btn-primary" disabled={busy} onClick={() => void unlock()}>
|
||||
{busy ? "解锁中…" : `支付 ${points || 0} 积分解锁`}
|
||||
</button>
|
||||
)}
|
||||
{access === "points" && !loggedIn && (
|
||||
<Link
|
||||
href={`/login?redirect=${encodeURIComponent(`/post/${postId}`)}`}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
登录后解锁
|
||||
</Link>
|
||||
)}
|
||||
{access === "reply" && (
|
||||
<a href="#comments" className="btn btn-primary">
|
||||
去回复
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user