/** * @license * SPDX-License-Identifier: Apache-2.0 */ import React, { useState, useEffect } from 'react'; import { Navbar } from './components/Navbar'; import { AnalysisView } from './components/AnalysisView'; import { AutoTradingView } from './components/AutoTradingView'; import { SignalHistory } from './components/SignalHistory'; import { DashboardStats } from './components/DashboardStats'; import { PlansView } from './components/PlansView'; import { AdminDashboard } from './components/AdminDashboard'; import { LandingPage } from './components/LandingPage'; import { ProfileView } from './components/ProfileView'; import { NotificationManager } from './components/NotificationManager'; import { MaintenancePage } from './components/MaintenancePage'; import { LiveMarketTicker } from './components/LiveMarketTicker'; import { TrendingUp, ShieldAlert, Ghost, Mail, Lock, UserPlus, LogIn, Loader2, ArrowLeft, User as UserIcon, Eye, EyeOff } from 'lucide-react'; import { motion, AnimatePresence } from 'motion/react'; import { onAuthStateChanged, signInWithEmailAndPassword, createUserWithEmailAndPassword, updateProfile, signOut, sendEmailVerification, sendPasswordResetEmail, User, setPersistence, browserLocalPersistence, browserSessionPersistence } from 'firebase/auth'; import { doc, setDoc, getDoc, updateDoc, onSnapshot } from 'firebase/firestore'; import { auth, db, handleFirestoreError, OperationType } from './lib/firebase'; import { cn } from './lib/utils'; declare global { interface Window { OneSignalDeferred: any[]; } } export default function App() { const [user, setUser] = useState(null); const [userData, setUserData] = useState(null); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState('scan'); const [maintenanceMode, setMaintenanceMode] = useState(false); const [maintenanceMessage, setMaintenanceMessage] = useState(''); // Auth & View State const [isSecretAdminRoute, setIsSecretAdminRoute] = useState(() => window.location.pathname === '/fxbros-admin' || window.location.hash === '#/fxbros-admin'); const [showAuth, setShowAuth] = useState(isSecretAdminRoute); const [isLogin, setIsLogin] = useState(true); const [showVerification, setShowVerification] = useState(false); const [showForgotPassword, setShowForgotPassword] = useState(false); const [resetEmailSent, setResetEmailSent] = useState(false); const [verificationEmail, setVerificationEmail] = useState(''); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [repeatPassword, setRepeatPassword] = useState(''); const [authError, setAuthError] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); const [rememberMe, setRememberMe] = useState(true); const [unauthView, setUnauthView] = useState<'hero' | 'plans'>('hero'); useEffect(() => { // Listen for settings changes const settingsRef = doc(db, 'settings', 'app'); const unsubSettings = onSnapshot(settingsRef, (docSnap) => { if (docSnap.exists()) { setMaintenanceMode(docSnap.data().maintenanceMode || false); setMaintenanceMessage(docSnap.data().maintenanceMessage || ''); } }, (error) => { console.warn("Failed to listen to settings:", error); }); // Initialize OneSignal via window object if (import.meta.env.VITE_ONESIGNAL_APP_ID) { window.OneSignalDeferred = window.OneSignalDeferred || []; window.OneSignalDeferred.push(async function(OneSignal: any) { await OneSignal.init({ appId: import.meta.env.VITE_ONESIGNAL_APP_ID, allowLocalhostAsSecureOrigin: true, }); OneSignal.Slidedown.promptPush(); }); } return () => unsubSettings(); }, []); useEffect(() => { const unsubscribe = onAuthStateChanged(auth, async (currentUser) => { if (currentUser && currentUser.emailVerified) { try { const userRef = doc(db, 'users', currentUser.uid); const userSnap = await getDoc(userRef).catch(err => { handleFirestoreError(err, OperationType.GET, 'users/' + currentUser.uid); throw err; }); let data = { uid: currentUser.uid, email: currentUser.email, name: currentUser.displayName || 'User', isAdmin: currentUser.email === "fxbrosinvestments00@gmail.com", isPremium: false, plan: 'basic' as const, analysisLimit: 8, isApproved: currentUser.email === "fxbrosinvestments00@gmail.com" }; if (userSnap.exists()) { data = { ...data, ...userSnap.data() }; // Force admin rights for root email if (currentUser.email === "fxbrosinvestments00@gmail.com") { data.isAdmin = true; data.isApproved = true; if (userSnap.data().isAdmin !== true || userSnap.data().isApproved !== true) { try { await updateDoc(userRef, { isAdmin: true, isApproved: true }); } catch (e) { console.error("Failed to update root admin privileges:", e); } } } if (!data.isApproved && !data.isAdmin) { await signOut(auth); setAuthError('Sua conta foi criada. Aguarde aprovação manual do administrador.'); setShowAuth(true); setIsLogin(true); setUser(null); setUserData(null); setLoading(false); return; } setUserData(data); } else { await setDoc(userRef, data).catch(err => { handleFirestoreError(err, OperationType.WRITE, 'users/' + currentUser.uid); throw err; }); if (!data.isApproved && !data.isAdmin) { await signOut(auth); setAuthError('Sua conta foi criada. Aguarde aprovação manual do administrador.'); setShowAuth(true); setIsLogin(true); setUser(null); setUserData(null); setLoading(false); return; } setUserData(data); } } catch (err) { console.error("Firestore user initialization error:", err); // Set minimal data to allow UI to render, but it might be limited due to rules setUserData({ isPremium: false, isAdmin: currentUser.email === "fxbrosinvestments00@gmail.com", isApproved: false }); } setUser(currentUser); setUnauthView('hero'); setShowAuth(false); } else { setUser(null); setUserData(null); } setLoading(false); }); return () => unsubscribe(); }, []); const isAdmin = user?.email === "fxbrosinvestments00@gmail.com" || userData?.isAdmin; const handleResetPassword = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); setAuthError(null); try { const targetEmail = email.toLowerCase() === 'admin' ? 'fxbrosinvestments00@gmail.com' : email; await sendPasswordResetEmail(auth, targetEmail); setResetEmailSent(true); } catch (error: any) { console.error(error); setAuthError('Falha ao enviar e-mail de recuperação.'); } finally { setIsSubmitting(false); } }; const handleAuth = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); setAuthError(null); try { await setPersistence(auth, rememberMe ? browserLocalPersistence : browserSessionPersistence); if (isLogin) { const targetEmail = email.toLowerCase() === 'admin' ? 'fxbrosinvestments00@gmail.com' : email; const userCredential = await signInWithEmailAndPassword(auth, targetEmail, password); if (!userCredential.user.emailVerified) { try { await sendEmailVerification(userCredential.user); } catch (e) { console.error("Verification email send error:", e); } await signOut(auth); setVerificationEmail(email); setShowVerification(true); } } else { if (password !== repeatPassword) { setAuthError('Passwords do not match.'); setIsSubmitting(false); return; } const userCredential = await createUserWithEmailAndPassword(auth, email, password); await updateProfile(userCredential.user, { displayName: name }); try { await setDoc(doc(db, 'users', userCredential.user.uid), { uid: userCredential.user.uid, email: userCredential.user.email, name: name, isAdmin: userCredential.user.email === "fxbrosinvestments00@gmail.com", isPremium: false, plan: 'basic', analysisLimit: 8, isApproved: userCredential.user.email === "fxbrosinvestments00@gmail.com" }); } catch (e) { console.error("Failed to write new user to DB", e); } try { await sendEmailVerification(userCredential.user); } catch (e) { console.error("Verification email send error:", e); } await signOut(auth); setVerificationEmail(email); setShowVerification(true); } } catch (error: any) { console.error("Auth Error:", error); if (isLogin) { setAuthError('Email or Password Incorrect'); } else { if (error.code === 'auth/email-already-in-use') { setAuthError('User already exists. Sign in?'); setIsLogin(true); } else { setAuthError('Failed to register.'); } } } finally { setIsSubmitting(false); } }; const handleLogout = () => { signOut(auth); setShowAuth(false); setUnauthView('hero'); }; if (loading) { return (
Logo
); } // Se estiver em manutenção e o usuário não for admin, mostra a página de manutenção if (maintenanceMode && !isAdmin) { return ; } if (!user) { if (!showAuth) { if (unauthView === 'hero') { return setShowAuth(true)} onViewPlans={() => setUnauthView('plans')} />; } return (
setShowAuth(true)} onBack={() => setUnauthView('hero')} />
); } return (
{/* Background Image for Login */}
Login Background
Logo

{isSecretAdminRoute ? <>FXBROS ADMIN : <>QUANTSCAN}

{isSecretAdminRoute ? "Acesso Restrito" : "Acesse a inteligência institucional Pro."}

{showVerification ? (

We have sent you a verification email to {verificationEmail}. Verify it and log in.

) : showForgotPassword ? ( resetEmailSent ? (

We sent you a password change link to {email}.

) : (

Recuperar Senha

Digite seu e-mail para receber o link de redefinição.

setEmail(e.target.value)} placeholder="seu@email.com" className="w-full bg-brand-dark/50 border border-white/5 rounded-xl py-3 pl-10 pr-4 text-white text-sm focus:outline-none focus:border-brand-red/50 transition-colors" autoCapitalize="none" />
{authError && (

{authError}

)}
) ) : ( <> {!isSecretAdminRoute && (
)}
{!isLogin && (
setName(e.target.value)} placeholder="Seu Nome" className="w-full bg-brand-dark/50 border border-white/5 rounded-xl py-3 pl-10 pr-4 text-white text-sm focus:outline-none focus:border-brand-red/50 transition-colors" />
)}
setEmail(e.target.value)} placeholder="seu@email.com" className="w-full bg-brand-dark/50 border border-white/5 rounded-xl py-3 pl-10 pr-4 text-white text-sm focus:outline-none focus:border-brand-red/50 transition-colors" autoCapitalize="none" />
{isLogin && ( )}
setPassword(e.target.value)} placeholder="••••••••" className="w-full bg-brand-dark/50 border border-white/5 rounded-xl py-3 pl-10 pr-10 text-white text-sm focus:outline-none focus:border-brand-red/50 transition-colors" />
{!isLogin && (
setRepeatPassword(e.target.value)} placeholder="••••••••" className="w-full bg-brand-dark/50 border border-white/5 rounded-xl py-3 pl-10 pr-10 text-white text-sm focus:outline-none focus:border-brand-red/50 transition-colors" />
)} {isLogin && (
setRememberMe(e.target.checked)} className="w-3.5 h-3.5 rounded bg-brand-dark/50 border border-white/10 accent-brand-red cursor-pointer" />
)} {authError && (

{authError}

)} {authError && !isLogin && authError.includes('aprov') && (

Após o cadastro, aguarde a aprovação manual.

)}
)}
Secure Auth
IA Logic
); } return (
{/* Background Image for App */}
App Background
{/* Desktop Header */}
Olá Humano, Bem-Vindo

{activeTab === 'scan' && 'Scanner de IA'} {activeTab === 'autoTrade' && 'Auto Trading'} {activeTab === 'history' && 'Histórico de Sinais'} {activeTab === 'stats' && 'Performance & Dados'} {activeTab === 'profile' && 'Perfil do Usuário'} {activeTab === 'admin' && 'Painel Administrativo'}

Servidor Live • Latência 24ms
Logo
Olá Humano, Bem-Vindo
QUANTSCAN
{activeTab === 'scan' && setActiveTab('history')} />} {activeTab === 'autoTrade' && } {activeTab === 'history' && } {activeTab === 'stats' && } {activeTab === 'profile' && } {activeTab === 'admin' && isAdmin && }
); }