84 lines
3.3 KiB
TypeScript
84 lines
3.3 KiB
TypeScript
import React, { useState, useEffect, useCallback } from 'react'
|
|
import { View, Text, TouchableOpacity, StyleSheet, SafeAreaView, StatusBar } from 'react-native'
|
|
import { AuthProvider, useAuth } from './src/components/AuthProvider'
|
|
import { getStoredToken } from './src/services/api'
|
|
import LoginScreen from './src/screens/LoginScreen'
|
|
import HomeScreen from './src/screens/HomeScreen'
|
|
import FeedScreen from './src/screens/FeedScreen'
|
|
import ProfileScreen from './src/screens/ProfileScreen'
|
|
import CheckInDetailScreen from './src/screens/CheckInDetailScreen'
|
|
import CreateCheckInScreen from './src/screens/CreateCheckInScreen'
|
|
|
|
const TABS = [
|
|
{ key: 'home', label: '打卡', icon: '📋' },
|
|
{ key: 'feed', label: '广场', icon: '🌊' },
|
|
{ key: 'profile', label: '我的', icon: '👤' },
|
|
]
|
|
|
|
function TabBar({ active, onChange }: { active: string; onChange: (k: string) => void }) {
|
|
return (
|
|
<View style={tabBarStyles.container}>
|
|
{TABS.map(t => (
|
|
<TouchableOpacity key={t.key} onPress={() => onChange(t.key)} style={tabBarStyles.tab}>
|
|
<Text style={tabBarStyles.icon}>{t.icon}</Text>
|
|
<Text style={[tabBarStyles.label, active === t.key && tabBarStyles.active]}>{t.label}</Text>
|
|
</TouchableOpacity>
|
|
))}
|
|
</View>
|
|
)
|
|
}
|
|
|
|
const tabBarStyles = StyleSheet.create({
|
|
container: { flexDirection: 'row', borderTopWidth: 0.5, borderTopColor: '#E5E5EA', backgroundColor: 'rgba(245,245,247,0.95)', paddingBottom: 20, paddingTop: 6 },
|
|
tab: { flex: 1, alignItems: 'center', gap: 2 },
|
|
icon: { fontSize: 22 },
|
|
label: { fontSize: 10, color: '#86868B' },
|
|
active: { color: '#FF6B35', fontWeight: '600' },
|
|
})
|
|
|
|
function MainApp() {
|
|
const { user, loading } = useAuth()
|
|
const [tab, setTab] = useState('home')
|
|
const [screen, setScreen] = useState<'loading' |const [screen, setScreen] = useState<'loading' | 'login' | 'main'>('loading')
|
|
const [selectedItemId, setSelectedItemId] = useState<string | null>(null)
|
|
const [showCreate, setShowCreate] = useState(false)| 'main'>('loading')
|
|
|
|
useEffect(() => {
|
|
if (!loading) {
|
|
getStoredToken().then(t => setScreen(t ? 'main' : 'login'))
|
|
}
|
|
}, [loading])
|
|
|
|
const onLogin = useCallback(() => setScreen('main'), [])
|
|
|
|
if (screen === 'loading') return <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5F5F7' }}><Text style={{ color: '#86868B' }}>加载中...</Text></View>
|
|
if (screen === 'login') return <LoginScreen onLogin={onLogin} />
|
|
if (selectedItemId) return <CheckInDetailScreen itemId={selectedItemId} onBack={() => setSelectedItemId(null)} />
|
|
if (showCreate) return <CreateCheckInScreen onBack={() => setShowCreate(false)} onCreated={() => { setShowCreate(false); setTab('home') }} />
|
|
|
|
const renderScreen = () => {
|
|
switch (tab) {
|
|
case 'home': return <HomeScreen onSelectItem={setSelectedItemId} onCreateItem={() => setShowCreate(true)} />
|
|
case 'feed': return <FeedScreen />
|
|
case 'profile': return <ProfileScreen />
|
|
default: return null
|
|
}
|
|
}
|
|
|
|
return (
|
|
<SafeAreaView style={{ flex: 1, backgroundColor: '#F5F5F7' }}>
|
|
<StatusBar barStyle="dark-content" background="#F5F5F7" />
|
|
{renderScreen()}
|
|
<TabBar active={tab} onChange={setTab} />
|
|
</SafeAreaView>
|
|
)
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<AuthProvider>
|
|
<MainApp />
|
|
</AuthProvider>
|
|
)
|
|
}
|