// template/src/modules/core/combined-auth/index.tsx import React, { useState, useEffect, useRef } from 'react'; import { Platform } from 'react-native'; import { View, Text, TextInput, TouchableOpacity, ActivityIndicator, SafeAreaView, ScrollView, Alert, Dimensions, Modal } from 'react-native'; // Import our components import Tile from '../../../components/Tile'; import BottomTabs from '../../../components/BottomTabs'; import PillCarousel from '../../../components/PillCarousell'; import Header from '../../../components/Header'; // Add this line // Import our data import { bottomTabsData, userData } from './data/mockData'; import { carouselSections } from './data/carouselSections'; // Import feature components import Summary from '../../feature/summary'; import Everyday from '../../feature/everyday/index'; import Apply from '../../feature/apply'; import Cards from '../../feature/cards'; // Import theme hook import { useTheme } from '../../../theme/ThemeProvider'; // Import styles import { createCombinedAuthStyles } from './styles'; // Define the different states/screens type AppState = 'splash' | 'login' | 'register' | 'dashboard'; // Mock user data type interface User { id: string; name: string; email: string; } const CombinedAuthModule: React.FC = () => { // Get theme from context - let's see what we actually get const themeContext = useTheme(); // console.log('Theme context keys:', Object.keys(themeContext)); // console.log('Theme context:', themeContext); const { theme, isLoading } = themeContext; // Show loading state while theme is loading if (isLoading || !theme) { return ( Loading theme... ); } // Create theme-aware styles const styles = createCombinedAuthStyles(theme); // Dev flag - set to true to skip splash/auth and go straight to dashboard const DEV_SKIP_AUTH = true; // State management const [currentState, setCurrentState] = useState(DEV_SKIP_AUTH ? 'dashboard' : 'splash'); const [user, setUser] = useState(DEV_SKIP_AUTH ? { id: 'dev', name: 'Alex', email: 'dev@example.com' } : null); const [loading, setLoading] = useState(false); const [isDragging, setIsDragging] = useState(false); // Carousel state const [activeSection, setActiveSection] = useState(0); // Index of current section const [scrollProgress, setScrollProgress] = useState(0); // 0-1 progress between sections const scrollViewRef = useRef(null); const pillScrollViewRef = useRef(null); const screenWidth = Dimensions.get('window').width; // NEW: Bottom navigation state - tracks which main section is active const [activeBottomSection, setActiveBottomSection] = useState('home'); // NEW: Overlay state management const [activeOverlay, setActiveOverlay] = useState(null); // Form states const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [name, setName] = useState(''); // Splash screen timer (only if not skipping auth) useEffect(() => { if (!DEV_SKIP_AUTH) { const timer = setTimeout(() => { setCurrentState('login'); }, 2000); return () => clearTimeout(timer); } }, [DEV_SKIP_AUTH]); // Authentication functions const handleLogin = async () => { if (!email || !password) { Alert.alert('Error', 'Please fill in all fields'); return; } setLoading(true); // Simulate API call setTimeout(() => { const mockUser: User = { id: '1', name: name || 'John Doe', email: email, }; setUser(mockUser); setCurrentState('dashboard'); setLoading(false); }, 1500); }; const handleRegister = async () => { if (!name || !email || !password) { Alert.alert('Error', 'Please fill in all fields'); return; } setLoading(true); // Simulate API call setTimeout(() => { const mockUser: User = { id: '2', name: name, email: email, }; setUser(mockUser); setCurrentState('dashboard'); setLoading(false); }, 1500); }; const handleLogout = () => { setUser(null); setEmail(''); setPassword(''); setName(''); setCurrentState('login'); }; // NEW: Bottom navigation section switching const handleBottomSectionChange = (sectionId: string) => { setActiveBottomSection(sectionId); // Reset carousel to first section when switching to home if (sectionId === 'home') { setActiveSection(0); setScrollProgress(0); scrollViewRef.current?.scrollTo({ x: 0, animated: false, }); } }; // NEW: Overlay management functions const handleOverlayOpen = (tabId: string) => { console.log(`Opening ${tabId} overlay`); setActiveOverlay(tabId); }; const handleOverlayClose = () => { console.log('Closing overlay'); setActiveOverlay(null); }; // Navigation functions const handlePillPress = (index: number) => { // Only handle pill press if we're on the home section if (activeBottomSection !== 'home') return; setActiveSection(index); scrollViewRef.current?.scrollTo({ x: index * screenWidth, animated: false, }); }; const handleScrollBegin = () => { setIsDragging(true); }; const scrollTimer = useRef(null); const lastScrollPosition = useRef(0); const handleScroll = (event: any) => { // Only handle scroll if we're on the home section if (activeBottomSection !== 'home') return; const contentOffset = event.nativeEvent.contentOffset; const progress = contentOffset.x / screenWidth; setScrollProgress(progress); lastScrollPosition.current = contentOffset.x; // Timer-based approach ONLY for web if (Platform.OS === 'web') { // Clear the existing timer if (scrollTimer.current) { clearTimeout(scrollTimer.current); } // Set a new timer - if scrolling stops for 150ms, we consider it "ended" scrollTimer.current = setTimeout(() => { handleScrollStop(); }, 150); } }; const handleScrollStop = () => { console.log('Scroll stopped (web timer)'); setIsDragging(false); const currentIndex = Math.round(lastScrollPosition.current / screenWidth); scrollViewRef.current?.scrollTo({ x: currentIndex * screenWidth, animated: true, }); if (currentIndex !== activeSection) { setActiveSection(currentIndex); } }; // Native-only scroll end handler const handleScrollEnd = (event: any) => { console.log('Scroll stopped (native event)'); setIsDragging(false); const contentOffset = event.nativeEvent.contentOffset; const currentIndex = Math.round(contentOffset.x / screenWidth); if (currentIndex !== activeSection) { setActiveSection(currentIndex); } }; // Render section content const renderSectionContent = (sectionIndex: number) => { const section = carouselSections[sectionIndex]; switch (section.id) { case 'summary': return ; case 'everyday': return ; default: // Fallback for other placeholder sections return ( {section.title} Module This section will load the {section.moduleId} module Coming soon with module loading system ); } }; // NEW: Render overlay content const renderOverlay = () => { if (!activeOverlay) return null; return ( {activeOverlay === 'payments' ? 'Payments' : 'Search'} {activeOverlay === 'payments' ? 'Payments overlay content goes here' : 'Search overlay content goes here'} Close ); }; // NEW: Render main content based on active bottom section const renderMainContent = () => { switch (activeBottomSection) { case 'apply': return ( ); case 'cards': return ( ); case 'home': default: return ( <> {/* Header - only show for home section */}
{/* Top Navigation Pills with Sliding Background */} {/* Horizontal Carousel Content */} {carouselSections.map((section, index) => ( {renderSectionContent(index)} ))} ); } }; // Render functions for each screen const renderSplash = () => ( BankApp Your Financial Partner ); const renderLogin = () => ( Welcome Back Sign in to your account {loading ? ( ) : ( Sign In )} setCurrentState('register')} > Don't have an account? Sign Up ); const renderRegister = () => ( Create Account Join us today {loading ? ( ) : ( Sign Up )} setCurrentState('login')} > Already have an account? Sign In ); const renderDashboard = () => ( {/* Main Content - changes based on bottom navigation */} {renderMainContent()} {/* Bottom Tabs - UPDATED with section handler */} {/* Render overlay */} {renderOverlay()} ); // Main render function const renderCurrentScreen = () => { switch (currentState) { case 'splash': return renderSplash(); case 'login': return renderLogin(); case 'register': return renderRegister(); case 'dashboard': return renderDashboard(); default: return renderSplash(); } }; return {renderCurrentScreen()}; }; export default CombinedAuthModule;