
This commit establishes the complete Next.js frontend foundation with comprehensive backend integration: ## Core Infrastructure ✅ - Next.js 14 with App Router and TypeScript configuration - Tailwind CSS with custom design system and dark mode - Complete project structure with proper imports and path aliases ## API Integration Layer ✅ - Full-featured API client with authentication, file upload, and WebSocket - Comprehensive TypeScript type definitions for all API responses - Axios-based HTTP client with interceptors and error handling - Socket.io integration for real-time progress updates ## Authentication System ✅ - useAuth hook with Google OAuth integration - JWT token management with automatic refresh - Protected route handling and session persistence - Login/logout flow with redirect management ## File Upload System ✅ - useUpload hook with drag & drop functionality - File validation (size, type, duplicates) - Progress tracking during upload - Batch creation and image processing workflow ## WebSocket Integration ✅ - useWebSocket hook for real-time updates - Progress subscription for batch processing - Reconnection logic with exponential backoff - Event-driven updates for batches, images, and user data ## UI Foundation ✅ - Responsive Header with user authentication state - Professional Footer with proper navigation - Error Boundary for graceful error handling - Toast notification system with multiple variants - Loading spinners and UI components ## Layout & Navigation ✅ - Main page component with authenticated/unauthenticated states - Dynamic content switching between landing and dashboard - Mobile-responsive design with proper accessibility This provides the complete foundation for a production-ready frontend that integrates seamlessly with the existing backend APIs, supporting all core workflows from authentication to file processing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
135 lines
No EOL
3 KiB
JavaScript
135 lines
No EOL
3 KiB
JavaScript
/** @type {import('next').NextConfig} */
|
|
const nextConfig = {
|
|
output: 'standalone',
|
|
experimental: {
|
|
appDir: true,
|
|
},
|
|
|
|
// Environment variables
|
|
env: {
|
|
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001',
|
|
NEXT_PUBLIC_WS_URL: process.env.NEXT_PUBLIC_WS_URL || 'ws://localhost:3001',
|
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
|
|
NEXT_PUBLIC_GOOGLE_CLIENT_ID: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
|
|
},
|
|
|
|
// Image configuration for external sources
|
|
images: {
|
|
remotePatterns: [
|
|
{
|
|
protocol: 'https',
|
|
hostname: 'lh3.googleusercontent.com',
|
|
port: '',
|
|
pathname: '/a/**',
|
|
},
|
|
{
|
|
protocol: 'http',
|
|
hostname: 'localhost',
|
|
port: '3001',
|
|
pathname: '/api/images/**',
|
|
},
|
|
],
|
|
dangerouslyAllowSVG: true,
|
|
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
|
|
},
|
|
|
|
// Headers for security
|
|
async headers() {
|
|
return [
|
|
{
|
|
source: '/(.*)',
|
|
headers: [
|
|
{
|
|
key: 'X-Frame-Options',
|
|
value: 'DENY',
|
|
},
|
|
{
|
|
key: 'X-Content-Type-Options',
|
|
value: 'nosniff',
|
|
},
|
|
{
|
|
key: 'Referrer-Policy',
|
|
value: 'strict-origin-when-cross-origin',
|
|
},
|
|
{
|
|
key: 'X-XSS-Protection',
|
|
value: '1; mode=block',
|
|
},
|
|
],
|
|
},
|
|
];
|
|
},
|
|
|
|
// Rewrites for API proxy in development
|
|
async rewrites() {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
return [
|
|
{
|
|
source: '/api/:path*',
|
|
destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001'}/api/:path*`,
|
|
},
|
|
];
|
|
}
|
|
return [];
|
|
},
|
|
|
|
// Webpack configuration
|
|
webpack: (config, { dev, isServer }) => {
|
|
// Optimization for production
|
|
if (!dev && !isServer) {
|
|
config.optimization.splitChunks.cacheGroups = {
|
|
...config.optimization.splitChunks.cacheGroups,
|
|
vendor: {
|
|
test: /[\\/]node_modules[\\/]/,
|
|
name: 'vendors',
|
|
chunks: 'all',
|
|
priority: 10,
|
|
},
|
|
common: {
|
|
name: 'common',
|
|
minChunks: 2,
|
|
chunks: 'all',
|
|
priority: 5,
|
|
reuseExistingChunk: true,
|
|
},
|
|
};
|
|
}
|
|
|
|
return config;
|
|
},
|
|
|
|
// TypeScript configuration
|
|
typescript: {
|
|
ignoreBuildErrors: false,
|
|
},
|
|
|
|
// ESLint configuration
|
|
eslint: {
|
|
ignoreDuringBuilds: false,
|
|
},
|
|
|
|
// Compression and optimization
|
|
compress: true,
|
|
poweredByHeader: false,
|
|
generateEtags: true,
|
|
|
|
// Redirects
|
|
async redirects() {
|
|
return [
|
|
{
|
|
source: '/dashboard',
|
|
destination: '/',
|
|
permanent: false,
|
|
has: [
|
|
{
|
|
type: 'cookie',
|
|
key: 'authenticated',
|
|
value: undefined,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
module.exports = nextConfig; |