mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 06:14:59 +00:00
Converted project from Vite SPA to Next.js 15 with App Router: **Dependencies:** - Installed Next.js 15.1.6 with React 19 - Added @next/third-parties and sharp for optimization - Updated package.json scripts for Next.js dev/build **App Structure:** - Created app/ directory with App Router - Setup root layout with font optimization (IBM Plex Sans, Space Grotesk, JetBrains Mono) - Created providers for ThemeProvider and QueryClient - Implemented file-based routing structure **Configuration:** - next.config.ts with standalone output for Docker - Image optimization config - Webpack config for DBAL and Lua (Fengari) support - Path aliases (@/, @/dbal) - CORS headers for API routes **Authentication:** - Created AuthProvider context for client-side auth - Middleware for route protection - Session cookie validation - Role-based redirects **Routing Structure:** ``` app/ ├── layout.tsx # Root layout ├── providers.tsx # Client providers ├── page.tsx # Home (Level 1) ├── level1-client.tsx # Client wrapper ├── login/ # Login page ├── (auth)/ # Protected routes │ ├── dashboard/ # Level 2 │ ├── admin/ # Level 3 │ ├── builder/ # Level 4 │ └── supergod/ # Level 5 ├── api/ # API routes └── _components/ # Shared components ``` **Features:** - Server-side rendering ready - Automatic code splitting - Font optimization with next/font - Image optimization configured - Auth middleware protection - Session management - Role-based access control **Migration Guide:** - Created NEXTJS_MIGRATION.md with complete roadmap - Phase 1 complete ✅ - Phase 2-5 in progress **Compatibility:** - All existing components preserved - DBAL integration maintained - Prisma unchanged - Docker deployment ready (pending Dockerfile update) - Tailwind CSS working - Shadcn/ui components compatible Next: Implement API routes, convert level components, update Docker. Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
import type { NextRequest } from 'next/server'
|
|
|
|
// Protected routes that require authentication
|
|
const protectedRoutes = [
|
|
'/(auth)/dashboard',
|
|
'/(auth)/admin',
|
|
'/(auth)/builder',
|
|
'/(auth)/supergod',
|
|
]
|
|
|
|
// Public routes that don't require authentication
|
|
const publicRoutes = ['/', '/login']
|
|
|
|
export function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl
|
|
|
|
// Check if current route is protected
|
|
const isProtectedRoute = protectedRoutes.some(route =>
|
|
pathname.startsWith(route.replace('/(auth)', ''))
|
|
)
|
|
|
|
// Check if current route is public
|
|
const isPublicRoute = publicRoutes.includes(pathname) || pathname.startsWith('/api')
|
|
|
|
// Get session cookie
|
|
const session = request.cookies.get('session')?.value
|
|
|
|
// Redirect to login if accessing protected route without session
|
|
if (isProtectedRoute && !session) {
|
|
const loginUrl = new URL('/login', request.url)
|
|
loginUrl.searchParams.set('from', pathname)
|
|
return NextResponse.redirect(loginUrl)
|
|
}
|
|
|
|
// Redirect to dashboard if accessing login with active session
|
|
if (pathname === '/login' && session) {
|
|
return NextResponse.redirect(new URL('/dashboard', request.url))
|
|
}
|
|
|
|
return NextResponse.next()
|
|
}
|
|
|
|
export const config = {
|
|
matcher: [
|
|
/*
|
|
* Match all request paths except for the ones starting with:
|
|
* - _next/static (static files)
|
|
* - _next/image (image optimization files)
|
|
* - favicon.ico (favicon file)
|
|
* - public folder
|
|
*/
|
|
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
],
|
|
}
|