feat: Implement robust error/not-found pages & UI components

- Introduce dedicated error pages for dashboard and video routes
- Add specific not-found pages for dashboard, projects, videos, and settings
- Implement global `not-found.tsx` for general unhandled routes
- Integrate root and dashboard layouts with ErrorBoundary and Suspense
- Add new UI components: Accordion, Hover Card, Menubar, Navigation Menu, Select, Tabs
- Update Navbar to utilize the new Navigation Menu component
- Enhance `button` component with a `link` variant for better styling
- Refine existing UI components (dialog, dropdown, input, etc.)
- Update Tailwind config with new colors and animation extensions
This commit is contained in:
Yusuf İpek
2026-02-07 15:53:31 +03:00
parent 48ddb03995
commit 373aab964c
30 changed files with 846 additions and 497 deletions
+6 -8
View File
@@ -1,6 +1,7 @@
import { NextRequest, NextResponse } from 'next/server';
import { NextRequest } from 'next/server';
import { db } from '@/lib/db';
import { auth } from '@/lib/auth';
import { apiErrors, successResponse } from '@/lib/api-response';
type RouteParams = { params: Promise<{ videoId: string }> };
@@ -43,7 +44,7 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
});
if (!video) {
return NextResponse.json({ error: 'Video not found' }, { status: 404 });
return apiErrors.notFound('Video');
}
// Check access
@@ -52,12 +53,12 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
const isPublic = video.project.visibility === 'PUBLIC';
if (!isOwner && !isMember && !isPublic) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
return apiErrors.forbidden('Access denied');
}
// Include auth context so the client knows if the viewer is a guest
const { project, ...videoData } = video;
return NextResponse.json({
return successResponse({
...videoData,
projectId: video.projectId,
project: {
@@ -70,9 +71,6 @@ export async function GET(request: NextRequest, { params }: RouteParams) {
});
} catch (error) {
console.error('Error fetching video:', error);
return NextResponse.json(
{ error: 'Failed to fetch video' },
{ status: 500 }
);
return apiErrors.internalError('Failed to fetch video');
}
}