feat: integrate luckysheet inline and fullscreen

This commit is contained in:
liaibo
2025-11-23 17:22:35 +08:00
parent c8e479aeab
commit 994dd4e67c
529 changed files with 403413 additions and 201 deletions
@@ -0,0 +1,51 @@
import { NextResponse } from "next/server";
import { createSupabaseRouteClient } from "@/lib/supabase/server";
interface RouteContext {
params: {
tableId: string;
};
}
export async function GET(request: Request, context: RouteContext) {
const supabase = await createSupabaseRouteClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// 强制 await params,以解决 Next.js 16/Turbopack 错误。
// 必须忽略类型检查,因为 Next.js 16/Turbopack 在运行时将 params 视为 Promise。
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tableId = (await (context as any).params).tableId;
if (!tableId) {
return NextResponse.json({ error: "Missing tableId" }, { status: 400 });
}
try {
// 假设 RLS 确保了用户只能访问其有权限的表格
const { data: tableData, error } = await supabase
.from("document_tables")
.select("*")
.eq("id", tableId)
.single();
if (error) {
console.error("Error fetching table:", error);
return NextResponse.json({ error: "Failed to fetch table data" }, { status: 500 });
}
if (!tableData) {
return NextResponse.json({ error: "Table not found" }, { status: 404 });
}
return NextResponse.json(tableData, { status: 200 });
} catch (error) {
console.error("API error:", error);
return NextResponse.json({ error: "Internal Server Error" }, { status: 500 });
}
}
@@ -0,0 +1,70 @@
import { NextResponse } from "next/server";
import { createSupabaseRouteClient } from "@/lib/supabase/server";
import { DocumentTableSnapshot, TableSchema } from "@/types/online-table";
// 定义请求体类型
interface CreateTableRequestBody {
documentId: string;
title: string;
schema: TableSchema;
snapshot?: DocumentTableSnapshot | null;
}
export async function POST(request: Request) {
const supabase = await createSupabaseRouteClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
try {
const { documentId, title, schema, snapshot } = await request.json() as CreateTableRequestBody;
if (!documentId || !title || !schema) {
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
}
// 1. 获取 document 所在的 workspace_id
const { data: documentData, error: documentError } = await supabase
.from("documents")
.select("workspace_id")
.eq("id", documentId)
.single();
if (documentError || !documentData?.workspace_id) {
console.error("Error fetching document or workspace:", documentError);
return NextResponse.json({ error: "Document not found or missing workspace_id" }, { status: 404 });
}
const workspaceId = documentData.workspace_id;
// 2. 插入新的 document_tables 记录
const { data: newTable, error: insertError } = await supabase
.from("document_tables")
.insert({
workspace_id: workspaceId,
document_id: documentId,
title: title,
schema: schema,
created_by: user.id,
updated_by: user.id,
snapshot: snapshot ?? {},
})
.select()
.single();
if (insertError) {
console.error("Error inserting table:", insertError);
return NextResponse.json({ error: "Failed to create table in database" }, { status: 500 });
}
// 假设 document_tables 返回的结构与 DocumentTable 接口兼容
return NextResponse.json(newTable, { status: 201 });
} catch (error) {
console.error("API error:", error);
return NextResponse.json({ error: "Internal Server Error" }, { status: 500 });
}
}