'use client' import { useEffect, useState, type CSSProperties } from 'react' import { useSearchParams, useRouter } from 'next/navigation' import useAuthStore from '../store/authStore' import RegisterForm from './components/RegisterForm' import PageLayout from '../components/PageLayout' import SessionDetectedModal from './components/SessionDetectedModal' import InvalidRefLinkModal from './components/invalidRefLinkModal' import { ToastProvider, useToast } from '../components/toast/toastComponent' import Waves from '../components/background/waves' import BlueBlurryBackground from '../components/background/blueblurry' // NEW // NEW: inner component that actually uses useToast and all the logic function RegisterPageInner() { const searchParams = useSearchParams() const refToken = searchParams.get('ref') const [registered, setRegistered] = useState(false) const [mode, setMode] = useState<'personal' | 'company'>('personal') const router = useRouter() const { showToast } = useToast() // Auth state const user = useAuthStore(state => state.user) const logout = useAuthStore(state => state.logout) // Session management const [showSessionModal, setShowSessionModal] = useState(false) const [sessionCleared, setSessionCleared] = useState(false) // Referral validation state const [isRefChecked, setIsRefChecked] = useState(false) const [invalidRef, setInvalidRef] = useState(false) const [refInfo, setRefInfo] = useState<{ referrerName?: string referrerEmail?: string isUnlimited?: boolean usesRemaining?: number } | null>(null) // Redirect after registration useEffect(() => { if (registered) { const t = setTimeout(() => router.push('/login'), 4000) return () => clearTimeout(t) } }, [registered, router]) // Validate referral token useEffect(() => { let cancelled = false const validateRef = async () => { if (!refToken) { if (!cancelled) { setInvalidRef(true) setIsRefChecked(true) } showToast({ variant: 'error', title: 'Invitation error', message: 'No invitation token found in the link.' }) return } const base = process.env.NEXT_PUBLIC_API_BASE_URL || '' const url = `${base}/api/referral/info/${encodeURIComponent(refToken)}` try { const res = await fetch(url, { method: 'GET', credentials: 'include' }) const body = await res.json().catch(() => null) const success = !!body?.success const isUnlimited = !!body?.isUnlimited const usesRemaining = typeof body?.usesRemaining === 'number' ? body.usesRemaining : 0 const isActive = success && (isUnlimited || usesRemaining > 0) if (!cancelled) { if (isActive) { setRefInfo({ referrerName: body?.referrerName, referrerEmail: body?.referrerEmail, isUnlimited, usesRemaining }) setInvalidRef(false) showToast({ variant: 'success', title: 'Invitation verified', message: 'Your invitation link is valid. You can register now.' }) } else { setInvalidRef(true) showToast({ variant: 'error', title: 'Invalid invitation', message: 'This invitation link is invalid or no longer active.' }) } setIsRefChecked(true) } } catch { if (!cancelled) { setInvalidRef(true) setIsRefChecked(true) } showToast({ variant: 'error', title: 'Network error', message: 'Could not validate the invitation link. Please try again.' }) } } validateRef() return () => { cancelled = true } // showToast intentionally omitted to avoid effect re-run loops (provider value can change) }, [refToken]) // note: showToast intentionally omitted to avoid effect re-run loops // Detect existing logged-in session useEffect(() => { if (isRefChecked && !invalidRef && user && !sessionCleared) { setShowSessionModal(true) } }, [isRefChecked, invalidRef, user, sessionCleared]) const handleLogout = async () => { await logout() setSessionCleared(true) setShowSessionModal(false) } const handleCancel = () => { setShowSessionModal(false) router.push('/dashboard') } const [isMobile, setIsMobile] = useState(false) 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) } }, []) const mainStyle: CSSProperties = { paddingTop: isMobile ? 'calc(var(--pp-header-spacer, 0px) + clamp(1.25rem, 3.5vh, 2.25rem))' : 'calc(var(--pp-header-spacer, 0px) + clamp(5rem, 8vh, 7rem))', transition: 'padding-top 260ms ease, opacity 260ms ease', willChange: 'padding-top, opacity', opacity: 'var(--pp-page-shift-opacity, 1)', } const BackgroundShell = ({ children }: { children: React.ReactNode }) => { return isMobile ? ( {children} ) : (
{children}
) } // --- Render branches (unchanged except classNames) --- if (!isRefChecked) { return (

Checking invitation link…

) } if (invalidRef) { return (
router.push('/')} onClose={() => router.push('/')} />
) } // normal register return (

Register now

Create your personal or company account with Profit Planet.

{showSessionModal ? (
) : ( <> {(!user || sessionCleared) && ( setRegistered(true)} referrerEmail={refInfo?.referrerEmail} /> )} {registered && (
Registration successful – redirecting...
)} )}
) } // NEW: default export only provides the ToastProvider wrapper export default function RegisterPage() { return ( ) }