'use client' import { useEffect, useState, useCallback, useRef } from 'react' import type { ComponentType, SVGProps } from 'react' import Link from 'next/link' import { useRouter } from 'next/navigation' import useAuthStore from '../store/authStore' import PageLayout from '../components/PageLayout' import Waves from '../components/background/waves' import BlueBlurryBackground from '../components/background/blueblurry' import { useUserStatus } from '../hooks/useUserStatus' import { ShoppingBagIcon, UsersIcon, UserCircleIcon, StarIcon, LinkIcon } from '@heroicons/react/24/outline' import { DEFAULT_DASHBOARD_PLATFORMS, loadDashboardPlatforms, subscribeDashboardPlatformsUpdated, type DashboardPlatform, type DashboardPlatformIconName } from '../utils/dashboardPlatforms' export default function DashboardPage() { const router = useRouter() const user = useAuthStore(state => state.user) const isAuthReady = useAuthStore(state => state.isAuthReady) const isShopEnabled = process.env.NEXT_PUBLIC_SHOW_SHOP !== 'false' const [platforms, setPlatforms] = useState(DEFAULT_DASHBOARD_PLATFORMS) const [isMobile, setIsMobile] = useState(false) const [latestNews, setLatestNews] = useState>([]) const [newsLoading, setNewsLoading] = useState(false) const [newsError, setNewsError] = useState(null) const { userStatus, loading: statusLoading } = useUserStatus() // NEW: smooth redirect helper const [redirectTo, setRedirectTo] = useState(null) const redirectOnceRef = useRef(false) const smoothReplace = useCallback((to: string) => { if (redirectOnceRef.current) return redirectOnceRef.current = true setRedirectTo(to) window.setTimeout(() => router.replace(to), 200) }, [router]) useEffect(() => { const mq = window.matchMedia('(max-width: 768px)') const apply = () => setIsMobile(mq.matches) apply() mq.addEventListener?.('change', apply) window.addEventListener('resize', apply, { passive: true }) return () => { mq.removeEventListener?.('change', apply) window.removeEventListener('resize', apply) } }, []) useEffect(() => { setPlatforms(loadDashboardPlatforms()) return subscribeDashboardPlatformsUpdated(() => setPlatforms(loadDashboardPlatforms())) }, []) useEffect(() => { let active = true ;(async () => { setNewsLoading(true) setNewsError(null) try { const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001' const res = await fetch(`${BASE_URL}/api/news/active`) if (!res.ok) throw new Error('Failed to fetch news') const json = await res.json() const data = Array.isArray(json.data) ? json.data : [] if (active) setLatestNews(data.slice(0, 3)) } catch (e: any) { if (active) setNewsError(e?.message || 'Failed to load news') } finally { if (active) setNewsLoading(false) } })() return () => { active = false } }, []) // Redirect if not logged in (only after auth is ready) useEffect(() => { if (isAuthReady && !user) { router.push('/login') } }, [isAuthReady, user, router]) // NEW: block dashboard unless all quickaction steps are completed // For guest users: only email verification is required // For regular users: all 4 steps must be completed useEffect(() => { if (!isAuthReady || !user) return if (statusLoading || !userStatus) return const isGuest = user?.role === 'guest' const allDone = isGuest ? !!userStatus.email_verified : !!userStatus.email_verified && !!userStatus.documents_uploaded && !!userStatus.profile_completed && !!userStatus.contract_signed if (!allDone) smoothReplace('/quickaction-dashboard') }, [isAuthReady, user, statusLoading, userStatus, smoothReplace]) // Show loading until auth is ready, user is confirmed, and (if logged in) status is loaded if (!isAuthReady || !user || (statusLoading && user)) { return (

Loading...

) } // If redirecting away, avoid rendering dashboard content if (redirectTo) { return (
Redirecting…
Please wait
) } // Final guard (don't render dashboard if not all done) if (!userStatus) return null const isGuestUser = user?.role === 'guest' const allDone = isGuestUser ? !!userStatus.email_verified : !!userStatus.email_verified && !!userStatus.documents_uploaded && !!userStatus.profile_completed && !!userStatus.contract_signed if (!allDone) return null // Get user name const getUserName = () => { if (user.firstName && user.lastName) { return `${user.firstName} ${user.lastName}` } if (user.firstName) return user.firstName if (user.email) return user.email.split('@')[0] return 'User' } const icons: Record>> = { ShoppingBagIcon, LinkIcon, UsersIcon, UserCircleIcon } const content = (
{/* Welcome Section */}

Welcome back, {getUserName()}! đź‘‹

Here's what's happening with your Profit Planet account

{/* Quick Actions */}

Platforms

{platforms.filter(p => p.isActive).map((platform) => { const Icon = icons[platform.icon] const disabledByEnv = platform.href === '/shop' && !isShopEnabled const isDisabled = Boolean(platform.disabled) || disabledByEnv const disabledText = disabledByEnv ? 'This is currently disabled.' : platform.disabledText return ( ) })}
{/* Gold Member Status */}

Gold Member Status

Enjoy exclusive benefits and discounts

{/* Latest News */}

Latest News

View all
{newsLoading && (
{Array.from({ length: 3 }).map((_, i) => (
))}
)} {newsError && !newsLoading && (
{newsError}
)} {!newsLoading && !newsError && latestNews.length === 0 && (
No news yet.
)} {!newsLoading && !newsError && latestNews.length > 0 && (
    {latestNews.map(item => (
  • {item.published_at ? new Date(item.published_at).toLocaleDateString('de-DE') : 'Recent'}
    {item.title}
    {item.summary && (
    {item.summary}
    )}
  • ))}
)}
) return isMobile ? ( {content} ) : (
{content}
) }