WebVNWrite/src/app/editor/[projectId]/page.tsx

123 lines
3.4 KiB
TypeScript

import { createClient } from '@/lib/supabase/server'
import { notFound } from 'next/navigation'
import Link from 'next/link'
import FlowchartEditor from './FlowchartEditor'
import type { FlowchartData } from '@/types/flowchart'
type PageProps = {
params: Promise<{ projectId: string }>
}
export default async function EditorPage({ params }: PageProps) {
const { projectId } = await params
const supabase = await createClient()
const {
data: { user },
} = await supabase.auth.getUser()
if (!user) {
return null
}
// Fetch user's display name for presence
const { data: profile } = await supabase
.from('profiles')
.select('display_name')
.eq('id', user.id)
.single()
const userDisplayName = profile?.display_name || user.email || 'Anonymous'
// Try to load as owner first
const { data: ownedProject } = await supabase
.from('projects')
.select('id, name, flowchart_data')
.eq('id', projectId)
.eq('user_id', user.id)
.single()
let project = ownedProject
let isOwner = true
// If not the owner, check if the user is a collaborator
if (!project) {
// RLS on projects allows collaborators to SELECT shared projects
const { data: collab } = await supabase
.from('project_collaborators')
.select('id, role')
.eq('project_id', projectId)
.eq('user_id', user.id)
.single()
if (!collab) {
notFound()
}
const { data: sharedProject } = await supabase
.from('projects')
.select('id, name, flowchart_data')
.eq('id', projectId)
.single()
if (!sharedProject) {
notFound()
}
project = sharedProject
isOwner = false
}
const rawData = project.flowchart_data || {}
const flowchartData: FlowchartData = {
nodes: rawData.nodes || [],
edges: rawData.edges || [],
characters: rawData.characters || [],
variables: rawData.variables || [],
}
// Migration flag: if the raw data doesn't have characters/variables arrays,
// the project was created before these features existed and may need auto-migration
const needsMigration = !rawData.characters && !rawData.variables
return (
<div className="flex h-screen flex-col">
<header className="flex items-center justify-between border-b border-zinc-200 bg-white px-4 py-3 dark:border-zinc-700 dark:bg-zinc-900">
<div className="flex items-center gap-4">
<Link
href="/dashboard"
className="text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-50"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z"
clipRule="evenodd"
/>
</svg>
</Link>
<h1 className="text-lg font-semibold text-zinc-900 dark:text-zinc-50">
{project.name}
</h1>
</div>
</header>
<div className="flex-1">
<FlowchartEditor
projectId={project.id}
userId={user.id}
userDisplayName={userDisplayName}
isOwner={isOwner}
initialData={flowchartData}
needsMigration={needsMigration}
/>
</div>
</div>
)
}