'use client'; import React, { useEffect, useState } from 'react'; import { Save, Plus, Edit, Trash2, Settings as SettingsIcon, Palette, Globe, Lock, Mail } from 'lucide-react'; import { NewsCategory, NewsCategoryInfo } from '@/lib/types'; export default function SettingsPage() { const [activeTab, setActiveTab] = useState('categories'); const [isSubmitting, setIsSubmitting] = useState(false); const [categories, setCategories] = useState([]); const [newCategory, setNewCategory] = useState({ name: '', description: '', color: 'bg-blue-500' }); const [generalSettings, setGeneralSettings] = useState({ siteTitle: 'CKE Project', newsPerPage: 10, autoPublish: true, requireModeration: false, allowComments: false, emailNotifications: true }); const colorOptions = [ { value: 'bg-blue-500', label: 'Синий', color: 'bg-blue-500' }, { value: 'bg-green-500', label: 'Зеленый', color: 'bg-green-500' }, { value: 'bg-red-500', label: 'Красный', color: 'bg-red-500' }, { value: 'bg-yellow-500', label: 'Желтый', color: 'bg-yellow-500' }, { value: 'bg-purple-500', label: 'Фиолетовый', color: 'bg-purple-500' }, { value: 'bg-pink-500', label: 'Розовый', color: 'bg-pink-500' }, { value: 'bg-indigo-500', label: 'Индиго', color: 'bg-indigo-500' }, { value: 'bg-gray-500', label: 'Серый', color: 'bg-gray-500' } ]; const tabs = [ { id: 'categories', name: 'Категории', icon: Palette }, { id: 'general', name: 'Общие', icon: SettingsIcon }, { id: 'security', name: 'Безопасность', icon: Lock }, { id: 'seo', name: 'SEO', icon: Globe } ]; const [security, setSecurity] = useState({ email: 'admin@ckeproekt.ru', username: 'admin', currentPassword: '', newPassword: '', isSaving: false, message: '' as string | null, error: '' as string | null, }); useEffect(() => { (async () => { try { const res = await fetch('/api/admin/me', { cache: 'no-store' }); if (!res.ok) return; const data = await res.json(); if (data?.user) { setSecurity(prev => ({ ...prev, email: data.user.email, username: data.user.username })); } } catch {} })(); }, []); // загрузка категорий из БД useEffect(() => { (async () => { try { const res = await fetch('/api/categories', { cache: 'no-store' }); if (!res.ok) return; const data = await res.json(); const mapped: NewsCategoryInfo[] = (data.data || []).map((c: any) => ({ id: c.slug as NewsCategory, name: c.name, description: c.description || '', color: c.color || 'bg-blue-500' })); setCategories(mapped); } catch {} })(); }, []); const handleAddCategory = async () => { if (!newCategory.name.trim()) return; try { const res = await fetch('/api/categories', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: newCategory.name, description: newCategory.description, color: newCategory.color }) }); const data = await res.json(); if (!res.ok) throw new Error(data.error || 'Ошибка создания категории'); // Преобразуем к локальному типу const created: NewsCategoryInfo = { id: data.data.slug as NewsCategory, name: data.data.name, description: data.data.description || '', color: data.data.color || 'bg-blue-500' }; setCategories(prev => [...prev, created]); setNewCategory({ name: '', description: '', color: 'bg-blue-500' }); } catch (e) { alert(e instanceof Error ? e.message : 'Ошибка'); } }; const handleDeleteCategory = async (slug: string) => { if (!confirm('Вы уверены, что хотите удалить эту категорию?')) return; try { // нужно найти id категории по slug через /api/categories (у нас в списке нет db id), // поэтому запрашиваем полный список и ищем совпадение const resList = await fetch('/api/categories'); const list = await resList.json(); const match = (list.data || []).find((c: any) => c.slug === slug); if (!match) throw new Error('Категория не найдена'); const res = await fetch(`/api/categories/${match.id}`, { method: 'DELETE' }); const data = await res.json(); if (!res.ok) throw new Error(data.error || 'Ошибка удаления'); setCategories(prev => prev.filter(cat => cat.id !== slug)); } catch (e) { alert(e instanceof Error ? e.message : 'Ошибка'); } }; const handleSaveSettings = async () => { setIsSubmitting(true); try { // пока сохраняем только generalSettings (к примеру локально) console.log('Saving settings:', { generalSettings }); await new Promise(r => setTimeout(r, 500)); alert('Настройки сохранены'); } catch (error) { console.error('Error saving settings:', error); alert('Ошибка при сохранении настроек'); } finally { setIsSubmitting(false); } }; return (
{/* Header */}

Настройки

Управление настройками системы новостей

{/* Tabs */}
{/* Categories Tab */} {activeTab === 'categories' && (

Управление категориями

Категории синхронизируются с базой данных

{/* Add New Category */}

Добавить новую категорию

setNewCategory(prev => ({ ...prev, name: e.target.value }))} className="px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent" /> setNewCategory(prev => ({ ...prev, description: e.target.value }))} className="px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{/* Categories List */}
{categories.map((category) => (
{category.name}

{category.description}

{/* Редактирование можно добавить при необходимости */}
))}
)} {/* General Tab */} {activeTab === 'general' && (

Общие настройки

setGeneralSettings(prev => ({ ...prev, siteTitle: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
setGeneralSettings(prev => ({ ...prev, newsPerPage: parseInt(e.target.value) }))} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
setGeneralSettings(prev => ({ ...prev, autoPublish: e.target.checked }))} className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
setGeneralSettings(prev => ({ ...prev, requireModeration: e.target.checked }))} className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
setGeneralSettings(prev => ({ ...prev, allowComments: e.target.checked }))} className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
setGeneralSettings(prev => ({ ...prev, emailNotifications: e.target.checked }))} className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
)} {/* SEO Tab */} {activeTab === 'seo' && (

SEO настройки