This commit is contained in:
2026-02-06 02:55:46 +03:00
parent bbb453826b
commit 9e5e9ddca4
5 changed files with 95 additions and 2 deletions

View File

@ -3,6 +3,11 @@ const nextConfig = {
reactStrictMode: true,
eslint: { ignoreDuringBuilds: true },
transpilePackages: ['@coursecraft/shared'],
// Проксируем /api на бэкенд — в браузере запросы идут на тот же хост, без localhost
async rewrites() {
const apiUrl = process.env.API_URL || 'http://127.0.0.1:3125';
return [{ source: '/api/:path*', destination: `${apiUrl}/api/:path*` }];
},
images: {
remotePatterns: [
{

View File

@ -0,0 +1,29 @@
'use client';
import Link from 'next/link';
import { Sparkles } from 'lucide-react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
export default function ForgotPasswordPage() {
return (
<Card>
<CardHeader className="text-center">
<Link href="/" className="flex items-center justify-center gap-2 mb-4">
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary">
<Sparkles className="h-5 w-5 text-primary-foreground" />
</div>
<span className="text-xl font-bold">CourseCraft</span>
</Link>
<CardTitle>Восстановление пароля</CardTitle>
<CardDescription>
Функция восстановления пароля настраивается через Supabase (Email). Пока используйте вход через поставщика или обратитесь в поддержку.
</CardDescription>
</CardHeader>
<CardContent className="text-center">
<Link href="/login" className="text-primary hover:underline text-sm">
Вернуться к входу
</Link>
</CardContent>
</Card>
);
}

View File

@ -0,0 +1,29 @@
'use client';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Search } from 'lucide-react';
export default function DashboardSearchPage() {
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold">Поиск курсов</h1>
<p className="text-muted-foreground">Поиск по каталогу курсов (скоро)</p>
</div>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Search className="h-5 w-5" />
Поиск
</CardTitle>
<CardDescription>
Здесь будет поиск по курсам через Meilisearch. Пока используйте раздел «Мои курсы».
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">Функция в разработке.</p>
</CardContent>
</Card>
</div>
);
}

28
apps/web/src/app/icon.tsx Normal file
View File

@ -0,0 +1,28 @@
import { ImageResponse } from 'next/og';
export const size = { width: 32, height: 32 };
export const contentType = 'image/png';
export default function Icon() {
return new ImageResponse(
(
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
borderRadius: 8,
fontSize: 18,
color: 'white',
fontWeight: 'bold',
}}
>
C
</div>
),
{ ...size }
);
}

View File

@ -1,5 +1,7 @@
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3125';
const API_URL = `${API_BASE}/api`;
// В браузере — относительный URL (запросы на тот же хост, Next проксирует /api на бэкенд)
const API_BASE =
typeof window !== 'undefined' ? '' : (process.env.API_URL || 'http://localhost:3125');
const API_URL = API_BASE ? `${API_BASE.replace(/\/$/, '')}/api` : '/api';
const STORAGE_KEY = 'coursecraft_api_token';