'use client' import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline' import { useLogin } from '../hooks/useLogin' export default function LoginForm() { const [showPassword, setShowPassword] = useState(false) const [showBall, setShowBall] = useState(true) const [formData, setFormData] = useState({ email: '', password: '', rememberMe: false }) const [viewportWidth, setViewportWidth] = useState( typeof window !== 'undefined' ? window.innerWidth : 1200 ) const router = useRouter() const { login, error, setError, loading } = useLogin() // Responsive ball visibility useEffect(() => { const handleResizeBall = () => setShowBall(window.innerWidth >= 768) handleResizeBall() window.addEventListener('resize', handleResizeBall) return () => window.removeEventListener('resize', handleResizeBall) }, []) // Track viewport width for dynamic scaling useEffect(() => { const handleResize = () => setViewportWidth(window.innerWidth) window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) const handleInputChange = (e: React.ChangeEvent) => { const { name, value, type, checked } = e.target setFormData(prev => ({ ...prev, [name]: type === 'checkbox' ? checked : value })) setError('') // Clear error when user starts typing } const validateForm = (): boolean => { if (!formData.email.trim()) { setError('E-Mail-Adresse ist erforderlich') return false } if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) { setError('Bitte gib eine gültige E-Mail-Adresse ein') return false } if (!formData.password.trim()) { setError('Passwort ist erforderlich') return false } if (formData.password.length < 6) { setError('Passwort muss mindestens 6 Zeichen lang sein') return false } return true } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!validateForm()) return await login({ email: formData.email, password: formData.password, rememberMe: formData.rememberMe }) } // Dynamic breakpoints const isMobile = viewportWidth < 640 const isTablet = viewportWidth >= 640 && viewportWidth < 1024 const isSmallLaptop = viewportWidth >= 1024 && viewportWidth < 1366 // Dynamic width & scale const formWidth = isMobile ? '98vw' : isTablet ? '85vw' : isSmallLaptop ? '50vw' : '40vw' const formMaxWidth = isMobile ? 'none' : isTablet ? '620px' : isSmallLaptop ? '660px' : '720px' const formScale = (() => { if (isMobile) return 1 if (isTablet) return 0.95 if (isSmallLaptop) return 0.9 if (viewportWidth >= 1366 && viewportWidth < 1680) return 0.85 return 0.82 })() return (
{/* Animated Ball - Desktop Only */} {showBall && !isMobile && (
{/* Inner small circle with cartoony Earth */}
{/* Land masses (stylized) */} {/* Atmospheric rim */} {/* Light sheen */} {/* Subtle gloss overlay */}
{/* Orbiting balls (unchanged) */}
)} {/* Content */}

Profit Planet

Welcome back! Login to continue.

{/* Email Field */}
{/* Password Field */}
{/* Remember Me & Show Password */}
setShowPassword(e.target.checked)} />
{/* Error Message */} {error && (
{error}
)} {/* Submit Button */}
{/* Forgot Password */}
{/* Registration Section */}

Profit Planet is available by invitation only.

Contact us for an invitation!

{/* CSS Animations */}
) }