mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 17:46:06 +00:00
refactor: eslint and prettier conflict will be resolved and formatted
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
import { Card, CardHeader, CardContent } from "@/components/ui/card"
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { Card, CardHeader, CardContent } from '@/components/ui/card';
|
||||
|
||||
function ProjectCardSkeleton() {
|
||||
return (
|
||||
@@ -24,7 +24,7 @@ function ProjectCardSkeleton() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default function DashboardLoading() {
|
||||
@@ -44,5 +44,5 @@ export default function DashboardLoading() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
+134
-134
@@ -2,162 +2,162 @@ import { auth } from '@/lib/auth';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { db } from '@/lib/db';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { hasCollaboratorBillingBackedAccess, requireBillingAccessOrRedirect } from '@/lib/route-access';
|
||||
import {
|
||||
hasCollaboratorBillingBackedAccess,
|
||||
requireBillingAccessOrRedirect,
|
||||
} from '@/lib/route-access';
|
||||
import { DashboardClient } from './dashboard-client';
|
||||
import { buildBillingAccessWhereInput } from '@/lib/billing';
|
||||
import { isBunnyUploadsEnabled } from '@/lib/feature-flags';
|
||||
|
||||
export default async function DashboardPage({
|
||||
searchParams,
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Promise<{ ws?: string; sort?: string; page?: string }>
|
||||
searchParams: Promise<{ ws?: string; sort?: string; page?: string }>;
|
||||
}) {
|
||||
const session = await auth();
|
||||
if (!session?.user?.id) {
|
||||
redirect('/login');
|
||||
}
|
||||
const session = await auth();
|
||||
if (!session?.user?.id) {
|
||||
redirect('/login');
|
||||
}
|
||||
|
||||
const hasCollaboratorAccess = await hasCollaboratorBillingBackedAccess(session.user.id);
|
||||
if (!hasCollaboratorAccess) {
|
||||
await requireBillingAccessOrRedirect({ userId: session.user.id });
|
||||
}
|
||||
const hasCollaboratorAccess = await hasCollaboratorBillingBackedAccess(session.user.id);
|
||||
if (!hasCollaboratorAccess) {
|
||||
await requireBillingAccessOrRedirect({ userId: session.user.id });
|
||||
}
|
||||
|
||||
const userOnboarding = await db.user.findUnique({
|
||||
where: { id: session.user.id },
|
||||
select: { onboardingCompletedAt: true },
|
||||
});
|
||||
if (!userOnboarding?.onboardingCompletedAt) {
|
||||
redirect('/onboarding');
|
||||
}
|
||||
const userOnboarding = await db.user.findUnique({
|
||||
where: { id: session.user.id },
|
||||
select: { onboardingCompletedAt: true },
|
||||
});
|
||||
if (!userOnboarding?.onboardingCompletedAt) {
|
||||
redirect('/onboarding');
|
||||
}
|
||||
|
||||
const resolvedSearchParams = await searchParams;
|
||||
const { ws, sort, page: pageParam } = resolvedSearchParams || {};
|
||||
const resolvedSearchParams = await searchParams;
|
||||
const { ws, sort, page: pageParam } = resolvedSearchParams || {};
|
||||
|
||||
const page = Number(pageParam) || 1;
|
||||
const pageSize = 20;
|
||||
const skip = (page - 1) * pageSize;
|
||||
const orderByDirection = sort === 'asc' ? 'asc' : 'desc';
|
||||
const page = Number(pageParam) || 1;
|
||||
const pageSize = 20;
|
||||
const skip = (page - 1) * pageSize;
|
||||
const orderByDirection = sort === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
// Base permission where clause
|
||||
const baseWhere: Prisma.ProjectWhereInput = {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id } } },
|
||||
{
|
||||
workspace: {
|
||||
owner: buildBillingAccessWhereInput(),
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id } } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
// Base permission where clause
|
||||
const baseWhere: Prisma.ProjectWhereInput = {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id } } },
|
||||
{
|
||||
workspace: {
|
||||
owner: buildBillingAccessWhereInput(),
|
||||
owner: buildBillingAccessWhereInput(),
|
||||
OR: [{ ownerId: session.user.id }, { members: { some: { userId: session.user.id } } }],
|
||||
},
|
||||
};
|
||||
},
|
||||
],
|
||||
workspace: {
|
||||
owner: buildBillingAccessWhereInput(),
|
||||
},
|
||||
};
|
||||
|
||||
// Build unique workspace list for filter (Needs an unbounded list of accessible workspaces)
|
||||
const accessibleProjects = await db.project.findMany({
|
||||
where: baseWhere,
|
||||
select: {
|
||||
// Build unique workspace list for filter (Needs an unbounded list of accessible workspaces)
|
||||
const accessibleProjects = await db.project.findMany({
|
||||
where: baseWhere,
|
||||
select: {
|
||||
workspace: {
|
||||
select: { id: true, name: true },
|
||||
},
|
||||
},
|
||||
distinct: ['workspaceId'],
|
||||
});
|
||||
|
||||
const [creatableWorkspaces, editableProject] = await Promise.all([
|
||||
db.workspace.count({
|
||||
where: {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id, role: 'ADMIN' } } },
|
||||
],
|
||||
},
|
||||
}),
|
||||
db.project.findFirst({
|
||||
where: {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id, role: 'ADMIN' } } },
|
||||
{
|
||||
workspace: {
|
||||
select: { id: true, name: true }
|
||||
}
|
||||
},
|
||||
distinct: ['workspaceId']
|
||||
});
|
||||
|
||||
const [creatableWorkspaces, editableProject] = await Promise.all([
|
||||
db.workspace.count({
|
||||
where: {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id, role: 'ADMIN' } } },
|
||||
],
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id, role: 'ADMIN' } } },
|
||||
],
|
||||
},
|
||||
}),
|
||||
db.project.findFirst({
|
||||
where: {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id, role: 'ADMIN' } } },
|
||||
{
|
||||
workspace: {
|
||||
OR: [
|
||||
{ ownerId: session.user.id },
|
||||
{ members: { some: { userId: session.user.id, role: 'ADMIN' } } },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
select: { id: true },
|
||||
}),
|
||||
]);
|
||||
const canCreateProjects = creatableWorkspaces > 0;
|
||||
const canUploadVideos = Boolean(editableProject);
|
||||
},
|
||||
],
|
||||
},
|
||||
select: { id: true },
|
||||
}),
|
||||
]);
|
||||
const canCreateProjects = creatableWorkspaces > 0;
|
||||
const canUploadVideos = Boolean(editableProject);
|
||||
|
||||
const workspaceMap = new Map<string, string>();
|
||||
for (const project of accessibleProjects) {
|
||||
if (project.workspace) {
|
||||
workspaceMap.set(project.workspace.id, project.workspace.name);
|
||||
}
|
||||
const workspaceMap = new Map<string, string>();
|
||||
for (const project of accessibleProjects) {
|
||||
if (project.workspace) {
|
||||
workspaceMap.set(project.workspace.id, project.workspace.name);
|
||||
}
|
||||
const workspaces = Array.from(workspaceMap, ([id, name]) => ({ id, name }));
|
||||
}
|
||||
const workspaces = Array.from(workspaceMap, ([id, name]) => ({ id, name }));
|
||||
|
||||
// Final query constraints
|
||||
const queryWhere: Prisma.ProjectWhereInput = {
|
||||
...baseWhere,
|
||||
...(ws && ws !== 'all' ? { workspaceId: ws } : {})
|
||||
};
|
||||
// Final query constraints
|
||||
const queryWhere: Prisma.ProjectWhereInput = {
|
||||
...baseWhere,
|
||||
...(ws && ws !== 'all' ? { workspaceId: ws } : {}),
|
||||
};
|
||||
|
||||
const [projects, totalProjects] = await Promise.all([
|
||||
db.project.findMany({
|
||||
skip,
|
||||
take: pageSize,
|
||||
where: queryWhere,
|
||||
include: {
|
||||
workspace: {
|
||||
select: { id: true, name: true },
|
||||
},
|
||||
_count: {
|
||||
select: {
|
||||
videos: true,
|
||||
members: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { updatedAt: orderByDirection },
|
||||
}),
|
||||
db.project.count({
|
||||
where: queryWhere
|
||||
})
|
||||
]);
|
||||
const [projects, totalProjects] = await Promise.all([
|
||||
db.project.findMany({
|
||||
skip,
|
||||
take: pageSize,
|
||||
where: queryWhere,
|
||||
include: {
|
||||
workspace: {
|
||||
select: { id: true, name: true },
|
||||
},
|
||||
_count: {
|
||||
select: {
|
||||
videos: true,
|
||||
members: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { updatedAt: orderByDirection },
|
||||
}),
|
||||
db.project.count({
|
||||
where: queryWhere,
|
||||
}),
|
||||
]);
|
||||
|
||||
const totalPages = Math.ceil(totalProjects / pageSize);
|
||||
const totalPages = Math.ceil(totalProjects / pageSize);
|
||||
|
||||
const serializedProjects = projects.map((p) => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
description: p.description,
|
||||
visibility: p.visibility,
|
||||
updatedAt: p.updatedAt.toISOString(),
|
||||
workspaceId: p.workspace?.id ?? null,
|
||||
workspaceName: p.workspace?.name ?? null,
|
||||
memberCount: p._count.members + 1,
|
||||
videoCount: p._count.videos,
|
||||
}));
|
||||
const serializedProjects = projects.map((p) => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
description: p.description,
|
||||
visibility: p.visibility,
|
||||
updatedAt: p.updatedAt.toISOString(),
|
||||
workspaceId: p.workspace?.id ?? null,
|
||||
workspaceName: p.workspace?.name ?? null,
|
||||
memberCount: p._count.members + 1,
|
||||
videoCount: p._count.videos,
|
||||
}));
|
||||
|
||||
return (
|
||||
<DashboardClient
|
||||
serializedProjects={serializedProjects}
|
||||
workspaces={workspaces}
|
||||
totalPages={totalPages}
|
||||
canCreateProjects={canCreateProjects}
|
||||
canUploadVideos={canUploadVideos}
|
||||
bunnyUploadsEnabled={isBunnyUploadsEnabled()}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<DashboardClient
|
||||
serializedProjects={serializedProjects}
|
||||
workspaces={workspaces}
|
||||
totalPages={totalPages}
|
||||
canCreateProjects={canCreateProjects}
|
||||
canUploadVideos={canUploadVideos}
|
||||
bunnyUploadsEnabled={isBunnyUploadsEnabled()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,18 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { Plus, FolderOpen, Clock, Users, Globe, Lock, UserPlus, Building2, ArrowUp, ArrowDown } from 'lucide-react';
|
||||
import {
|
||||
Plus,
|
||||
FolderOpen,
|
||||
Clock,
|
||||
Users,
|
||||
Globe,
|
||||
Lock,
|
||||
UserPlus,
|
||||
Building2,
|
||||
ArrowUp,
|
||||
ArrowDown,
|
||||
} from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
@@ -62,13 +73,18 @@ function VisibilityIcon({ visibility }: { visibility: string }) {
|
||||
|
||||
type SortOrder = 'desc' | 'asc';
|
||||
|
||||
export function ProjectFilter({ projects, workspaces, totalPages, canCreateProjects }: ProjectFilterProps) {
|
||||
export function ProjectFilter({
|
||||
projects,
|
||||
workspaces,
|
||||
totalPages,
|
||||
canCreateProjects,
|
||||
}: ProjectFilterProps) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const selectedWorkspace = searchParams.get('ws') || 'all';
|
||||
const sortOrder = searchParams.get('sort') as SortOrder || 'desc';
|
||||
const sortOrder = (searchParams.get('sort') as SortOrder) || 'desc';
|
||||
const page = Number(searchParams.get('page')) || 1;
|
||||
|
||||
const createQueryString = useCallback(
|
||||
|
||||
Reference in New Issue
Block a user