首次提交

This commit is contained in:
zeronline
2026-06-25 08:39:47 +08:00
parent 20a93c703a
commit c5cccd346b
169 changed files with 24720 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
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>
)
}