65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
import { Loader2 } from "lucide-react";
|
|
|
|
// 默认进入最近画布,避免误触直接新建
|
|
export default function CanvasRedirectPage() {
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
|
|
useEffect(() => {
|
|
const shouldCreateNew = searchParams.get("new") === "1";
|
|
const passthroughParams = new URLSearchParams(searchParams.toString());
|
|
passthroughParams.delete("new");
|
|
const passthroughQuery = passthroughParams.toString();
|
|
const buildCanvasUrl = (canvasId: string) =>
|
|
`/canvas/${canvasId}${passthroughQuery ? `?${passthroughQuery}` : ""}`;
|
|
|
|
const openCanvas = async () => {
|
|
if (shouldCreateNew) {
|
|
const newId = crypto.randomUUID();
|
|
router.replace(buildCanvasUrl(newId));
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch("/api/canvas", { cache: "no-store" });
|
|
if (response.ok) {
|
|
const result = await response.json();
|
|
const items = result?.data || [];
|
|
if (Array.isArray(items) && items.length > 0) {
|
|
const sorted = [...items].sort((a, b) => {
|
|
const aTime = new Date(a.updatedAt || a.createdAt || 0).getTime();
|
|
const bTime = new Date(b.updatedAt || b.createdAt || 0).getTime();
|
|
return bTime - aTime;
|
|
});
|
|
const latest = sorted[0];
|
|
if (latest?.id) {
|
|
router.replace(buildCanvasUrl(latest.id));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
} catch (_error) {
|
|
// ignore and fallback
|
|
}
|
|
|
|
const newId = crypto.randomUUID();
|
|
router.replace(buildCanvasUrl(newId));
|
|
};
|
|
|
|
void openCanvas();
|
|
}, [router, searchParams]);
|
|
|
|
return (
|
|
<div className="flex items-center justify-center h-full">
|
|
<div className="flex flex-col items-center gap-3">
|
|
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
|
|
<span className="text-sm text-muted-foreground">正在打开画布...</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|