112 lines
2.8 KiB
TypeScript
112 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { Suspense, useEffect, useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { apiMe, apiGetSnippet } from "@/lib/api";
|
|
import SnippetEditor from "@/components/SnippetEditor";
|
|
|
|
function EditSnippetInner({ id }: { id: number }) {
|
|
const router = useRouter();
|
|
const [ready, setReady] = useState(false);
|
|
const [snippet, setSnippet] = useState<{
|
|
title: string;
|
|
language: string;
|
|
description: string;
|
|
code: string;
|
|
visibility: "public" | "private";
|
|
user_id: number;
|
|
} | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
(async () => {
|
|
const me = await apiMe().catch(() => null);
|
|
if (cancelled) return;
|
|
if (!me?.user) {
|
|
router.push(`/login?redirect=/snippets/${id}/edit`);
|
|
return;
|
|
}
|
|
try {
|
|
const data = await apiGetSnippet(id);
|
|
if (cancelled) return;
|
|
if (!data) {
|
|
router.push("/snippets");
|
|
return;
|
|
}
|
|
// 仅 owner 或 staff 可编辑(后端会再次校验)
|
|
setSnippet({
|
|
title: data.snippet.title,
|
|
language: data.snippet.language,
|
|
description: data.snippet.description,
|
|
code: data.snippet.code,
|
|
visibility: data.snippet.visibility,
|
|
user_id: data.snippet.user_id,
|
|
});
|
|
setReady(true);
|
|
} catch {
|
|
if (!cancelled) router.push("/snippets");
|
|
}
|
|
})();
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [router, id]);
|
|
|
|
if (!ready || !snippet) {
|
|
return (
|
|
<div className="j13-compose-stage is-studio px-8 py-16 text-center">
|
|
<p className="meta">正在加载片段…</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<SnippetEditor
|
|
mode="edit"
|
|
snippetId={id}
|
|
initialTitle={snippet.title}
|
|
initialLanguage={snippet.language}
|
|
initialDescription={snippet.description}
|
|
initialCode={snippet.code}
|
|
initialVisibility={snippet.visibility}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export default function EditSnippetPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ id: string }>;
|
|
}) {
|
|
const [id, setId] = useState<number | null>(null);
|
|
|
|
useEffect(() => {
|
|
params.then((p) => {
|
|
const numId = Number(p.id);
|
|
if (Number.isInteger(numId) && numId > 0) setId(numId);
|
|
});
|
|
}, [params]);
|
|
|
|
if (id === null) {
|
|
return (
|
|
<div className="j13-compose-stage is-studio px-8 py-16 text-center">
|
|
<p className="meta">正在加载…</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="j13-compose-page">
|
|
<Suspense
|
|
fallback={
|
|
<div className="j13-compose-stage is-studio px-8 py-16 text-center">
|
|
<p className="meta">正在加载片段…</p>
|
|
</div>
|
|
}
|
|
>
|
|
<EditSnippetInner id={id} />
|
|
</Suspense>
|
|
</div>
|
|
);
|
|
}
|