diff --git a/app/api/admin/blog-topics/[id]/route.js b/app/api/admin/blog-topics/[id]/route.js
new file mode 100644
index 0000000..94d12a3
--- /dev/null
+++ b/app/api/admin/blog-topics/[id]/route.js
@@ -0,0 +1,13 @@
+import { NextResponse } from 'next/server';
+import { requireUser } from '@/lib/session';
+
+const ENGINE_URL = process.env.ENGINE_URL || 'http://127.0.0.1:3030';
+const ENGINE_SECRET = process.env.ENGINE_SECRET || '';
+const h = (uid) => ({ 'x-internal-secret': ENGINE_SECRET, 'x-user-id': String(uid) });
+
+export async function DELETE(req, { params }) {
+ const user = await requireUser();
+ if (!user?.isAdmin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
+ const res = await fetch(`${ENGINE_URL}/api/admin/blog-topics/${params.id}`, { method: 'DELETE', headers: h(user.id) });
+ return NextResponse.json(await res.json());
+}
diff --git a/app/api/admin/blog-topics/generate/route.js b/app/api/admin/blog-topics/generate/route.js
new file mode 100644
index 0000000..b25e58c
--- /dev/null
+++ b/app/api/admin/blog-topics/generate/route.js
@@ -0,0 +1,16 @@
+import { NextResponse } from 'next/server';
+import { requireUser } from '@/lib/session';
+
+const ENGINE_URL = process.env.ENGINE_URL || 'http://127.0.0.1:3030';
+const ENGINE_SECRET = process.env.ENGINE_SECRET || '';
+const h = (uid) => ({ 'x-internal-secret': ENGINE_SECRET, 'x-user-id': String(uid) });
+
+export async function POST(req) {
+ const user = await requireUser();
+ if (!user?.isAdmin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
+ const body = await req.json();
+ const res = await fetch(`${ENGINE_URL}/api/admin/blog-topics/generate`, {
+ method: 'POST', headers: { ...h(user.id), 'Content-Type': 'application/json' }, body: JSON.stringify(body),
+ });
+ return NextResponse.json(await res.json());
+}
diff --git a/app/api/admin/blog-topics/route.js b/app/api/admin/blog-topics/route.js
new file mode 100644
index 0000000..3d850e8
--- /dev/null
+++ b/app/api/admin/blog-topics/route.js
@@ -0,0 +1,26 @@
+import { NextResponse } from 'next/server';
+import { requireUser } from '@/lib/session';
+
+const ENGINE_URL = process.env.ENGINE_URL || 'http://127.0.0.1:3030';
+const ENGINE_SECRET = process.env.ENGINE_SECRET || '';
+const h = (uid) => ({ 'x-internal-secret': ENGINE_SECRET, 'x-user-id': String(uid) });
+
+// GET — список тем
+export async function GET(req) {
+ const user = await requireUser();
+ if (!user?.isAdmin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
+ const { searchParams } = new URL(req.url);
+ const res = await fetch(`${ENGINE_URL}/api/admin/blog-topics?${searchParams}`, { headers: h(user.id), cache: 'no-store' });
+ return NextResponse.json(await res.json());
+}
+
+// POST — добавить тему
+export async function POST(req) {
+ const user = await requireUser();
+ if (!user?.isAdmin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
+ const body = await req.json();
+ const res = await fetch(`${ENGINE_URL}/api/admin/blog-topics`, {
+ method: 'POST', headers: { ...h(user.id), 'Content-Type': 'application/json' }, body: JSON.stringify(body),
+ });
+ return NextResponse.json(await res.json(), { status: res.status });
+}
diff --git a/app/api/admin/email/test/route.js b/app/api/admin/email/test/route.js
new file mode 100644
index 0000000..49c6fee
--- /dev/null
+++ b/app/api/admin/email/test/route.js
@@ -0,0 +1,16 @@
+import { NextResponse } from 'next/server';
+import { requireUser } from '@/lib/session';
+
+const ENGINE_URL = process.env.ENGINE_URL || 'http://127.0.0.1:3030';
+const ENGINE_SECRET = process.env.ENGINE_SECRET || '';
+const h = (uid) => ({ 'x-internal-secret': ENGINE_SECRET, 'x-user-id': String(uid) });
+
+export async function POST(req) {
+ const user = await requireUser();
+ if (!user?.isAdmin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
+ const body = await req.json();
+ const res = await fetch(`${ENGINE_URL}/api/admin/email/test`, {
+ method: 'POST', headers: { ...h(user.id), 'Content-Type': 'application/json' }, body: JSON.stringify(body),
+ });
+ return NextResponse.json(await res.json(), { status: res.status });
+}
diff --git a/components/AdminPanel.js b/components/AdminPanel.js
index bdc4d90..cd3486b 100644
--- a/components/AdminPanel.js
+++ b/components/AdminPanel.js
@@ -1,6 +1,6 @@
'use client';
import { useState } from 'react';
-import { Settings2, CreditCard, TrendingUp, Users, ChevronRight, Loader2, Eye, EyeOff, Save, RefreshCw, Check, AlertCircle, BarChart3, ArrowLeft, Zap, Tag, AlertTriangle, BookOpen, Sliders } from 'lucide-react';
+import { Settings2, CreditCard, TrendingUp, Users, ChevronRight, Loader2, Eye, EyeOff, Save, RefreshCw, Check, AlertCircle, BarChart3, ArrowLeft, Zap, Tag, AlertTriangle, BookOpen, Sliders, Mail } from 'lucide-react';
import Link from 'next/link';
import AdminBilling from './admin/AdminBilling';
import AdminUsers from './admin/AdminUsers';
@@ -8,7 +8,8 @@ import AdminPromos from './admin/AdminPromos';
import AdminQueue from './admin/AdminQueue';
import AdminLogs from './admin/AdminLogs';
import AdminAutogen from './admin/AdminAutogen';
-import AdminContent from './admin/AdminContent';
+import AdminContent from './admin/AdminContent';
+import AdminTopicBank from './admin/AdminTopicBank';
// ──────────────────────────────────────────────────────────────
// Sidebar navigation
@@ -22,8 +23,10 @@ const SECTIONS = [
{ id: 'queue', label: 'Очередь', icon: Zap, desc: 'Задачи генерации, ошибки' },
{ id: 'logs', label: 'Логи ошибок', icon: AlertTriangle, desc: 'Последние сбои и проблемы' },
{ id: 'autogen', label: 'Автогенерация', icon: BookOpen, desc: 'Расписание статей блога' },
- { id: 'content', label: 'Контент-дефолты', icon: Sliders, desc: 'Настройки для новых каналов' },
- { id: 'plans', label: 'Тарифы', icon: BarChart3, desc: 'Планы, кредиты, операции' },
+ { id: 'content', label: 'Контент-дефолты', icon: Sliders, desc: 'Настройки для новых каналов' },
+ { id: 'topicbank', label: 'Банк тем блога', icon: BookOpen, desc: 'Темы для zeropost.ru' },
+ { id: 'smtp', label: 'Email / SMTP', icon: Mail, desc: 'Уведомления пользователям' },
+ { id: 'plans', label: 'Тарифы', icon: BarChart3, desc: 'Планы, кредиты, операции' },
{ id: 'promos', label: 'Промокоды', icon: Tag, desc: 'Коды для кредитов и скидок' },
{ id: 'billing', label: 'Пользователи', icon: Users, desc: 'Балансы и кредиты' },
];
@@ -76,8 +79,10 @@ export default function AdminPanel({ initialSection = 'settings' }) {
{section === 'queue' &&
{msg}
} +Темы для автогенерации статей на zeropost.ru
+