- Add complete Next.js 16 frontend with TypeScript and Tailwind CSS - Implement API proxy route for CORS-free backend communication - Create UserContext for global authentication state management - Add authentication flow with JWT tokens - Implement real data integration for posts and employees pages - Add dynamic user avatars (with fallback to initials) - Update API types to match backend Employee serializer - Remove all hardcoded mock data - Add route protection with automatic redirect to /login - Configure Docker orchestration for full-stack setup
87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
// API Route для проксирования всех /api/* запросов на backend
|
|
// Это позволяет избежать CORS при локальной разработке
|
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL || 'https://corp.robotail.pro';
|
|
|
|
export async function GET(request: NextRequest) {
|
|
return proxyRequest(request, 'GET');
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
return proxyRequest(request, 'POST');
|
|
}
|
|
|
|
export async function PUT(request: NextRequest) {
|
|
return proxyRequest(request, 'PUT');
|
|
}
|
|
|
|
export async function PATCH(request: NextRequest) {
|
|
return proxyRequest(request, 'PATCH');
|
|
}
|
|
|
|
export async function DELETE(request: NextRequest) {
|
|
return proxyRequest(request, 'DELETE');
|
|
}
|
|
|
|
async function proxyRequest(request: NextRequest, method: string) {
|
|
try {
|
|
// Получаем путь из URL запроса
|
|
const url = new URL(request.url);
|
|
// Убираем /api из начала пути
|
|
const apiPath = url.pathname.replace(/^\/api\//, '');
|
|
|
|
// Формируем полный URL к backend
|
|
const backendUrl = `${BACKEND_URL}/api/${apiPath}`;
|
|
|
|
// Копируем query параметры
|
|
const searchParams = url.searchParams.toString();
|
|
const fullUrl = searchParams ? `${backendUrl}?${searchParams}` : backendUrl;
|
|
|
|
console.log(`[Proxy] ${method} ${fullUrl}`);
|
|
|
|
// Копируем заголовки из оригинального запроса
|
|
const headers = new Headers();
|
|
request.headers.forEach((value, key) => {
|
|
// Пропускаем заголовки, которые не нужно передавать
|
|
if (!['host', 'connection', 'content-length'].includes(key.toLowerCase())) {
|
|
headers.set(key, value);
|
|
}
|
|
});
|
|
|
|
// Получаем тело запроса если есть
|
|
const body = method !== 'GET' && method !== 'HEAD'
|
|
? await request.text()
|
|
: undefined;
|
|
|
|
// Делаем запрос к backend
|
|
const response = await fetch(fullUrl, {
|
|
method,
|
|
headers,
|
|
body,
|
|
});
|
|
|
|
// Копируем заголовки из ответа backend
|
|
const responseHeaders = new Headers();
|
|
response.headers.forEach((value, key) => {
|
|
responseHeaders.set(key, value);
|
|
});
|
|
|
|
// Возвращаем ответ от backend
|
|
const responseBody = await response.text();
|
|
|
|
return new NextResponse(responseBody, {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers: responseHeaders,
|
|
});
|
|
} catch (error: any) {
|
|
console.error('[Proxy Error]', error.message);
|
|
return NextResponse.json(
|
|
{ error: 'Ошибка при обращении к backend', message: error.message },
|
|
{ status: 502 }
|
|
);
|
|
}
|
|
}
|