import React, { useState, useEffect } from 'react'; import { useAuth } from '../context/AuthContext'; import { useNavigate } from 'react-router-dom'; import { ChevronLeft, RefreshCw, BarChart2, Users, ShoppingCart, Package, FileText, Globe, Sparkles, MessageSquare, AlertCircle, CheckCircle, XCircle, Clock, Activity, Save, Mail, Rocket, Edit3, Bell, AlertTriangle, Archive, Send, Layout, History } from 'lucide-react'; import { Button } from '../components/Button'; import { supabase, isSupabaseConfigured } from '../lib/supabaseClient'; import { ProductPackage } from '../types'; import { defaultPlans } from '../lib/defaultPlans'; import { generateOrderPrompts, PromptResult } from '../lib/promptGenerator'; interface AdminUser { id: string; email: string; first_name?: string; last_name?: string; created_at: string; role: string; } interface OrderHistoryEntry { id: string; status: string; changed_at: string; } interface EmailLogEntry { id: string; email_type: string; sent_at: string; } interface AdminOrder { id: string; user_id: string; displayId: string; customer: string; email: string; package: string; status: string; date: string; amount: string; details?: any; history?: OrderHistoryEntry[]; emailLogs?: EmailLogEntry[]; } export const Admin: React.FC = () => { const { user, isAdmin, loading } = useAuth(); const navigate = useNavigate(); const [activeTab, setActiveTab] = useState<'overview' | 'users' | 'orders' | 'plans'>('overview'); const [users, setUsers] = useState([]); const [orders, setOrders] = useState([]); const [plans, setPlans] = useState([]); const [loadingData, setLoadingData] = useState(false); const [visitorStats, setVisitorStats] = useState({ month: 0, week: 0 }); const [statusUpdating, setStatusUpdating] = useState(null); const [planSaving, setPlanSaving] = useState(null); const [errorMsg, setErrorMsg] = useState(null); const [viewOrder, setViewOrder] = useState(null); const [generatedPrompts, setGeneratedPrompts] = useState([]); const [copiedIndex, setCopiedIndex] = useState(null); const [demoUrlInput, setDemoUrlInput] = useState(''); const [savingDemoUrl, setSavingDemoUrl] = useState(false); const [emailSending, setEmailSending] = useState(null); useEffect(() => { if (!loading && !isAdmin) { navigate('/dashboard'); } }, [isAdmin, loading, navigate]); useEffect(() => { if (isAdmin) fetchAdminData(); }, [isAdmin]); const fetchAdminData = async () => { setLoadingData(true); setErrorMsg(null); if (!isSupabaseConfigured) { setPlans(defaultPlans); setLoadingData(false); return; } try { const { data: profiles, error: pErr } = await supabase.from('profiles').select('*'); if (pErr) throw pErr; let rolesData: any[] = []; try { const { data: roles } = await supabase.from('roles').select('*'); rolesData = roles || []; } catch (e) { console.warn("Could not fetch roles table."); } setUsers(profiles.map(p => ({ id: p.id, email: p.email || 'N/A', first_name: p.first_name, last_name: p.last_name, created_at: p.created_at, role: rolesData.find(r => r.id === p.id)?.role || (p.email === 'motionstudiohq@gmail.com' ? 'admin' : 'user') }))); const { data: oData, error: oErr } = await supabase.from('orders').select('*').order('created_at', { ascending: false }); if (oErr) throw oErr; setOrders(oData.map(o => ({ ...o, displayId: o.id.substring(0, 8).toUpperCase(), customer: o.customer_name, email: o.customer_email }))); const { data: plData } = await supabase.from('plans').select('*').order('price', { ascending: true }); setPlans(plData && plData.length > 0 ? plData : defaultPlans); const { count: mCount } = await supabase.from('page_visits').select('*', { count: 'exact', head: true }); setVisitorStats({ month: mCount || 0, week: Math.floor((mCount || 0) / 4) }); } catch (err: any) { setErrorMsg(err.message || "Hiba történt az adatok lekérésekor."); } finally { setLoadingData(false); } }; const fetchOrderHistory = async (orderId: string) => { if (!isSupabaseConfigured) return []; try { const { data } = await supabase .from('order_status_history') .select('*') .eq('order_id', orderId) .order('changed_at', { ascending: false }); return data || []; } catch (e) { return []; } }; const fetchEmailLogs = async (orderId: string) => { if (!isSupabaseConfigured) return []; try { const { data } = await supabase .from('email_log') .select('*') .eq('order_id', orderId) .order('sent_at', { ascending: false }); return data || []; } catch (e) { console.warn("Could not fetch email_log table."); return []; } }; const handleStatusChange = async (orderId: string, newStatus: string) => { if (statusUpdating) return; setStatusUpdating(orderId); try { if (isSupabaseConfigured) { const { error } = await supabase.from('orders').update({ status: newStatus }).eq('id', orderId); if (error) throw error; await supabase.from('order_status_history').insert({ order_id: orderId, status: newStatus }); const newHist = await fetchOrderHistory(orderId); setOrders(prev => prev.map(o => o.id === orderId ? { ...o, status: newStatus } : o)); if (viewOrder && viewOrder.id === orderId) { setViewOrder({ ...viewOrder, status: newStatus, history: newHist }); } } else { setOrders(prev => prev.map(o => o.id === orderId ? { ...o, status: newStatus } : o)); if (viewOrder && viewOrder.id === orderId) { setViewOrder({ ...viewOrder, status: newStatus }); } } } catch (e: any) { alert("Hiba: " + e.message); } finally { setStatusUpdating(null); } }; const handleUpdateDemoUrl = async () => { if (!viewOrder || savingDemoUrl) return; setSavingDemoUrl(true); const orderId = viewOrder.id; const targetStatus = 'pending_feedback'; const updatedDetails = { ...(viewOrder.details || {}), demoUrl: demoUrlInput }; try { if (isSupabaseConfigured) { const { error } = await supabase.from('orders').update({ details: updatedDetails, status: targetStatus }).eq('id', orderId); if (error) throw error; await supabase.from('order_status_history').insert({ order_id: orderId, status: targetStatus }); const newHist = await fetchOrderHistory(orderId); setOrders(prev => prev.map(o => o.id === orderId ? { ...o, status: targetStatus, details: updatedDetails } : o)); setViewOrder({ ...viewOrder, status: targetStatus, details: updatedDetails, history: newHist }); alert(`Sikeres mentés és visszajelzés kérése!`); } else { setViewOrder({ ...viewOrder, details: updatedDetails }); alert("Demo URL mentve."); } } catch (e: any) { alert("Hiba: " + e.message); } finally { setSavingDemoUrl(false); } }; const handleViewDetails = async (order: AdminOrder) => { setLoadingData(true); const history = await fetchOrderHistory(order.id); const emailLogs = await fetchEmailLogs(order.id); setViewOrder({ ...order, history, emailLogs }); setDemoUrlInput(order.details?.demoUrl || ''); setGeneratedPrompts([]); setLoadingData(false); }; const handleSendEmail = async (emailType: string) => { if (!viewOrder || emailSending) return; setEmailSending(emailType); try { console.log(`Email notification trigger: ${emailType}`); if (isSupabaseConfigured) { const { error } = await supabase.from('email_log').insert({ order_id: viewOrder.id, email_type: emailType }); if (error) throw error; const newLogs = await fetchEmailLogs(viewOrder.id); setViewOrder({ ...viewOrder, emailLogs: newLogs }); alert(`E-mail ("${emailType}") naplózva és kiküldve (szimulált).`); } else { alert(`E-mail értesítő előkészítve: "${emailType}"\n\nJelenleg ez a funkció csak placeholder.`); } } catch (e: any) { alert("Hiba az e-mail naplózásakor: " + e.message); } finally { setEmailSending(null); } }; const StatusBadge = ({ status }: { status: string }) => { const configs: any = { new: { label: 'Új', color: 'bg-blue-100 text-blue-800' }, in_progress: { label: 'Folyamatban', color: 'bg-yellow-100 text-yellow-800' }, pending_feedback: { label: 'Visszajelzés', color: 'bg-purple-100 text-purple-800' }, completed: { label: 'Kész', color: 'bg-green-100 text-green-800' }, cancelled: { label: 'Törölve', color: 'bg-gray-100 text-gray-800' } }; const c = configs[status] || configs.new; return {c.label}; }; if (loading) return
Admin felület...
; if (!isAdmin) return null; return (
Admin Access

Vezérlőpult

{[ { id: 'overview', label: 'Statisztika', icon: BarChart2 }, { id: 'users', label: 'Felhasználók', icon: Users }, { id: 'orders', label: 'Rendelések', icon: ShoppingCart }, { id: 'plans', label: 'Csomagok', icon: Package } ].map((tab) => ( ))}
{activeTab === 'overview' && (

Látogatók

{visitorStats.month}

Rendelések

{orders.length}

Regisztrációk

{users.length}

)} {activeTab === 'users' && (
{users.map(u => ( ))}
Felhasználó Neve E-mail Szint Regisztráció
{u.last_name || ''} {u.first_name || ''} {(!u.last_name && !u.first_name) && Nincs megadva} {u.email} {u.role} {new Date(u.created_at).toLocaleDateString('hu-HU')}
)} {activeTab === 'orders' && (
{orders.map(o => ( ))}
Ügyfél Csomag Státusz Művelet

{o.customer}

{o.email}

{o.package}
)} {activeTab === 'plans' && (
{plans.map((p, i) => (
{ const n = [...plans]; n[i].name = e.target.value; setPlans(n); }} className="text-xl font-black border-b border-gray-200 focus:border-primary outline-none w-full pb-1 text-black bg-white mb-6" />