'use client'; import React, { useState, useEffect } from 'react'; import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; import { StatsGrid } from '@/components/dashboard/StatsGrid'; import { QRCodeCard } from '@/components/dashboard/QRCodeCard'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { useTranslation } from '@/hooks/useTranslation'; import { useCsrf } from '@/hooks/useCsrf'; import { showToast } from '@/components/ui/Toast'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/Dialog'; interface QRCodeData { id: string; title: string; type: 'STATIC' | 'DYNAMIC'; contentType: string; content?: any; slug: string; status: 'ACTIVE' | 'PAUSED'; createdAt: string; scans: number; style?: any; } export default function DashboardPage() { const { t } = useTranslation(); const router = useRouter(); const searchParams = useSearchParams(); const { fetchWithCsrf } = useCsrf(); const [qrCodes, setQrCodes] = useState([]); const [loading, setLoading] = useState(true); const [userPlan, setUserPlan] = useState('FREE'); const [showUpgradeDialog, setShowUpgradeDialog] = useState(false); const [upgradedPlan, setUpgradedPlan] = useState(''); const [deletingAll, setDeletingAll] = useState(false); const [stats, setStats] = useState({ totalScans: 0, activeQRCodes: 0, conversionRate: 0, }); const mockQRCodes = [ { id: '1', title: 'Support Phone', type: 'DYNAMIC' as const, contentType: 'PHONE', slug: 'support-phone-demo', status: 'ACTIVE' as const, createdAt: '2025-08-07T10:00:00Z', scans: 0, }, { id: '2', title: 'Event Details', type: 'DYNAMIC' as const, contentType: 'URL', slug: 'event-details-demo', status: 'ACTIVE' as const, createdAt: '2025-08-07T10:01:00Z', scans: 0, }, { id: '3', title: 'Product Demo', type: 'DYNAMIC' as const, contentType: 'URL', slug: 'product-demo-qr', status: 'ACTIVE' as const, createdAt: '2025-08-07T10:02:00Z', scans: 0, }, { id: '4', title: 'Company Website', type: 'DYNAMIC' as const, contentType: 'URL', slug: 'company-website-qr', status: 'ACTIVE' as const, createdAt: '2025-08-07T10:03:00Z', scans: 0, }, { id: '5', title: 'Contact Email', type: 'DYNAMIC' as const, contentType: 'EMAIL', slug: 'contact-email-qr', status: 'ACTIVE' as const, createdAt: '2025-08-07T10:04:00Z', scans: 0, }, { id: '6', title: 'Event Details', type: 'DYNAMIC' as const, contentType: 'URL', slug: 'event-details-dup', status: 'ACTIVE' as const, createdAt: '2025-08-07T10:05:00Z', scans: 0, }, ]; const blogPosts = [ { title: 'QR-Codes im Restaurant: Die digitale Revolution der Speisekarte', excerpt: 'Erfahren Sie, wie QR-Codes die Gastronomie revolutionieren...', readTime: '5 Min', slug: 'qr-codes-im-restaurant', }, { title: 'Dynamische vs. Statische QR-Codes: Was ist der Unterschied?', excerpt: 'Ein umfassender Vergleich zwischen dynamischen und statischen QR-Codes...', readTime: '3 Min', slug: 'dynamische-vs-statische-qr-codes', }, { title: 'QR-Code Marketing-Strategien für 2025', excerpt: 'Die besten Marketing-Strategien mit QR-Codes für Ihr Unternehmen...', readTime: '7 Min', slug: 'qr-code-marketing-strategien', }, ]; // Check for successful payment and verify session useEffect(() => { const success = searchParams.get('success'); if (success === 'true') { const verifySession = async () => { try { const response = await fetch('/api/stripe/verify-session', { method: 'POST', }); if (response.ok) { const data = await response.json(); setUserPlan(data.plan); setUpgradedPlan(data.plan); setShowUpgradeDialog(true); // Remove success parameter from URL router.replace('/dashboard'); } else { console.error('Failed to verify session:', await response.text()); } } catch (error) { console.error('Error verifying session:', error); } }; verifySession(); } }, [searchParams, router]); useEffect(() => { // Load real QR codes and user plan from API const fetchData = async () => { try { // Fetch QR codes const qrResponse = await fetch('/api/qrs'); if (qrResponse.ok) { const data = await qrResponse.json(); setQrCodes(data); // Calculate real stats const totalScans = data.reduce((sum: number, qr: QRCodeData) => sum + (qr.scans || 0), 0); const activeQRCodes = data.filter((qr: QRCodeData) => qr.status === 'ACTIVE').length; const conversionRate = activeQRCodes > 0 ? Math.round((totalScans / (activeQRCodes * 100)) * 100) : 0; setStats({ totalScans, activeQRCodes, conversionRate: Math.min(conversionRate, 100), // Cap at 100% }); } else { // If not logged in, show zeros setQrCodes([]); setStats({ totalScans: 0, activeQRCodes: 0, conversionRate: 0, }); } // Fetch user plan (using cookie-based auth, no session needed) const userResponse = await fetch('/api/user/plan'); if (userResponse.ok) { const userData = await userResponse.json(); setUserPlan(userData.plan || 'FREE'); } } catch (error) { console.error('Error fetching data:', error); setQrCodes([]); setStats({ totalScans: 0, activeQRCodes: 0, conversionRate: 0, }); } finally { setLoading(false); } }; fetchData(); }, []); const handleEdit = (id: string) => { // Redirect to edit page router.push(`/qr/${id}/edit`); }; const handlePause = async (id: string) => { try { const qr = qrCodes.find(q => q.id === id); if (!qr) return; const newStatus = qr.status === 'ACTIVE' ? 'PAUSED' : 'ACTIVE'; const response = await fetch(`/api/qrs/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ status: newStatus }), }); if (response.ok) { // Update local state setQrCodes(qrCodes.map(q => q.id === id ? { ...q, status: newStatus } : q )); showToast(`QR code ${newStatus === 'ACTIVE' ? 'resumed' : 'paused'}!`, 'success'); } else { throw new Error('Failed to update status'); } } catch (error) { console.error('Error updating QR status:', error); showToast('Failed to update QR code status', 'error'); } }; const handleDelete = async (id: string) => { if (!confirm('Are you sure you want to delete this QR code? This action cannot be undone.')) { return; } try { const response = await fetch(`/api/qrs/${id}`, { method: 'DELETE', }); if (response.ok) { // Remove from local state setQrCodes(qrCodes.filter(q => q.id !== id)); showToast('QR code deleted successfully!', 'success'); } else { throw new Error('Failed to delete'); } } catch (error) { console.error('Error deleting QR:', error); showToast('Failed to delete QR code', 'error'); } }; const handleDeleteAll = async () => { if (!confirm('Are you sure you want to delete ALL QR codes? This action cannot be undone.')) { return; } // Double confirmation if (!confirm('This will permanently delete ALL your QR codes. Are you absolutely sure?')) { return; } setDeletingAll(true); try { const response = await fetchWithCsrf('/api/qrs/delete-all', { method: 'DELETE', }); if (response.ok) { const data = await response.json(); setQrCodes([]); setStats({ totalScans: 0, activeQRCodes: 0, conversionRate: 0, }); showToast(`Successfully deleted ${data.deletedCount} QR code${data.deletedCount !== 1 ? 's' : ''}`, 'success'); } else { throw new Error('Failed to delete all QR codes'); } } catch (error) { console.error('Error deleting all QR codes:', error); showToast('Failed to delete QR codes', 'error'); } finally { setDeletingAll(false); } }; const getPlanBadgeColor = (plan: string) => { switch (plan) { case 'PRO': return 'info'; case 'BUSINESS': return 'warning'; default: return 'default'; } }; const getPlanEmoji = (plan: string) => { // No emojis anymore return ''; }; return (
{/* Header with Plan Badge */}

{t('dashboard.title')}

{t('dashboard.subtitle')}

{userPlan} Plan {userPlan === 'FREE' && ( )}
{/* Stats Grid */} {/* Recent QR Codes */}

{t('dashboard.recent_codes')}

{qrCodes.length > 0 && ( )}
{loading ? (
{[1, 2, 3, 4, 5, 6].map((i) => (
))}
) : (
{qrCodes.map((qr) => ( ))}
)}
{/* Blog & Resources */}

{t('dashboard.blog_resources')}

{blogPosts.map((post) => (
{post.readTime}
{post.title}

{post.excerpt}

Read more →
))}
{/* Upgrade Success Dialog */} Upgrade erfolgreich! Willkommen im {upgradedPlan} Plan! Ihr Konto wurde erfolgreich aktualisiert.

Ihre neuen Features:

    {upgradedPlan === 'PRO' && ( <>
  • 50 dynamische QR-Codes
  • Branding (Farben anpassen)
  • Detaillierte Analytics (Devices, Locations, Time-Series)
  • CSV-Export
  • SVG/PNG Download
  • )} {upgradedPlan === 'BUSINESS' && ( <>
  • 500 dynamische QR-Codes
  • Alles von Pro
  • Bulk QR-Generierung (bis 1,000)
  • Prioritäts-Support
  • )}
); }