86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import { createClient } from '@/lib/supabase/server'
|
|
import NewProjectButton from '@/components/NewProjectButton'
|
|
import ProjectList from '@/components/ProjectList'
|
|
import ProjectCard from '@/components/ProjectCard'
|
|
|
|
export default async function DashboardPage() {
|
|
const supabase = await createClient()
|
|
|
|
const {
|
|
data: { user },
|
|
} = await supabase.auth.getUser()
|
|
|
|
if (!user) {
|
|
return null
|
|
}
|
|
|
|
const { data: projects, error } = await supabase
|
|
.from('projects')
|
|
.select('id, name, updated_at')
|
|
.eq('user_id', user.id)
|
|
.order('updated_at', { ascending: false })
|
|
|
|
// Fetch shared projects (projects where this user is a collaborator)
|
|
const { data: collaborations } = await supabase
|
|
.from('project_collaborators')
|
|
.select('role, projects(id, name, updated_at)')
|
|
.eq('user_id', user.id)
|
|
|
|
const sharedProjects = (collaborations || [])
|
|
.filter((c) => c.projects)
|
|
.map((c) => ({
|
|
...(c.projects as unknown as { id: string; name: string; updated_at: string }),
|
|
shared: true,
|
|
role: c.role,
|
|
}))
|
|
.sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime())
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="rounded-lg border border-red-200 bg-red-50 p-4 dark:border-red-800 dark:bg-red-900/20">
|
|
<p className="text-red-700 dark:text-red-400">
|
|
Failed to load projects. Please try again.
|
|
</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<div className="mb-8 flex items-start justify-between">
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-zinc-900 dark:text-zinc-50">
|
|
Your Projects
|
|
</h1>
|
|
<p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
|
Select a project to open the flowchart editor
|
|
</p>
|
|
</div>
|
|
<NewProjectButton />
|
|
</div>
|
|
|
|
<ProjectList initialProjects={projects || []} />
|
|
|
|
{sharedProjects.length > 0 && (
|
|
<div className="mt-10">
|
|
<h2 className="mb-4 text-xl font-bold text-zinc-900 dark:text-zinc-50">
|
|
Shared with me
|
|
</h2>
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
{sharedProjects.map((project) => (
|
|
<ProjectCard
|
|
key={project.id}
|
|
id={project.id}
|
|
name={project.name}
|
|
updatedAt={project.updated_at}
|
|
shared
|
|
sharedRole={project.role}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|