// 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;