diff --git a/apps/web/next.config.js b/apps/web/next.config.js
index ac40550..d6f7446 100644
--- a/apps/web/next.config.js
+++ b/apps/web/next.config.js
@@ -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: [
{
diff --git a/apps/web/src/app/(auth)/forgot-password/page.tsx b/apps/web/src/app/(auth)/forgot-password/page.tsx
new file mode 100644
index 0000000..85a0c44
--- /dev/null
+++ b/apps/web/src/app/(auth)/forgot-password/page.tsx
@@ -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 (
+
+
+
+
+
+
+ CourseCraft
+
+ Восстановление пароля
+
+ Функция восстановления пароля настраивается через Supabase (Email). Пока используйте вход через поставщика или обратитесь в поддержку.
+
+
+
+
+ ← Вернуться к входу
+
+
+
+ );
+}
diff --git a/apps/web/src/app/(dashboard)/dashboard/search/page.tsx b/apps/web/src/app/(dashboard)/dashboard/search/page.tsx
new file mode 100644
index 0000000..73e3bec
--- /dev/null
+++ b/apps/web/src/app/(dashboard)/dashboard/search/page.tsx
@@ -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 (
+
+
+
Поиск курсов
+
Поиск по каталогу курсов (скоро)
+
+
+
+
+
+ Поиск
+
+
+ Здесь будет поиск по курсам через Meilisearch. Пока используйте раздел «Мои курсы».
+
+
+
+ Функция в разработке.
+
+
+
+ );
+}
diff --git a/apps/web/src/app/icon.tsx b/apps/web/src/app/icon.tsx
new file mode 100644
index 0000000..47aa118
--- /dev/null
+++ b/apps/web/src/app/icon.tsx
@@ -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(
+ (
+
+ C
+
+ ),
+ { ...size }
+ );
+}
diff --git a/apps/web/src/lib/api.ts b/apps/web/src/lib/api.ts
index 933545e..5e00760 100644
--- a/apps/web/src/lib/api.ts
+++ b/apps/web/src/lib/api.ts
@@ -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';