feat: integrate UI components into Home tab
Replace custom loading/error states with reusable components (RefreshControl, LoadingState, ErrorState). Add pull-to-refresh functionality and remove duplicate styles. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9703bb8fce
commit
141ccabe06
|
|
@ -19,7 +19,9 @@ import {
|
|||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
import { DownArrowIcon, PointsIcon, SearchIcon } from '@/components/icon';
|
||||
import { HomeSkeleton } from '@/components/skeleton/HomeSkeleton';
|
||||
import ErrorState from '@/components/ErrorState';
|
||||
import LoadingState from '@/components/LoadingState';
|
||||
import RefreshControl from '@/components/RefreshControl';
|
||||
import { useActivates } from '@/hooks/use-activates';
|
||||
import { useCategories } from '@/hooks/use-categories';
|
||||
import { CategoryTemplate } from '@repo/sdk';
|
||||
|
|
@ -82,6 +84,7 @@ export default function HomeScreen() {
|
|||
const params = useLocalSearchParams()
|
||||
const [activeTab, setActiveTab] = useState(0)
|
||||
const [selectedCategoryId, setSelectedCategoryId] = useState<string | null>(null)
|
||||
const [refreshing, setRefreshing] = useState(false)
|
||||
|
||||
const { load: loadCategories, data: categoriesData, loading: categoriesLoading, error: categoriesError } = useCategories()
|
||||
const { load, data: activatesData, error } = useActivates()
|
||||
|
|
@ -91,6 +94,12 @@ export default function HomeScreen() {
|
|||
loadCategories()
|
||||
}, [])
|
||||
|
||||
const handleRefresh = async () => {
|
||||
setRefreshing(true)
|
||||
await Promise.all([load(), loadCategories()])
|
||||
setRefreshing(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// 当分类数据加载完成后,默认选中第一个分类
|
||||
if (categoriesData?.categories && categoriesData.categories.length > 0 && !selectedCategoryId) {
|
||||
|
|
@ -280,6 +289,9 @@ export default function HomeScreen() {
|
|||
style={styles.scrollView}
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
showsVerticalScrollIndicator={false}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
|
||||
}
|
||||
onScroll={(event) => {
|
||||
const scrollY = event.nativeEvent.contentOffset.y
|
||||
if (scrollY >= tabsPositionRef.current) {
|
||||
|
|
@ -330,26 +342,21 @@ export default function HomeScreen() {
|
|||
)}
|
||||
|
||||
{/* 加载状态 */}
|
||||
{showLoading && <HomeSkeleton />}
|
||||
{showLoading && <LoadingState />}
|
||||
|
||||
{/* 错误状态 - 分类加载失败 */}
|
||||
{categoriesError && (
|
||||
<ErrorState message="加载分类失败" onRetry={() => loadCategories()} />
|
||||
)}
|
||||
|
||||
{/* 空状态 - 分类数据为空 */}
|
||||
{showEmptyState && (
|
||||
<View style={styles.emptyState}>
|
||||
<Text style={styles.emptyStateText}>暂无分类数据</Text>
|
||||
<Pressable style={styles.retryButton} onPress={() => loadCategories()}>
|
||||
<Text style={styles.retryButtonText}>重新加载</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
{showEmptyState && !categoriesError && (
|
||||
<ErrorState message="暂无分类数据" onRetry={() => loadCategories()} />
|
||||
)}
|
||||
|
||||
{/* 空状态 - 当前分类下没有模板 */}
|
||||
{showEmptyTemplates && (
|
||||
<View style={styles.emptyState}>
|
||||
<Text style={styles.emptyStateText}>该分类暂无模板</Text>
|
||||
<Pressable style={styles.retryButton} onPress={() => loadCategories()}>
|
||||
<Text style={styles.retryButtonText}>刷新</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<ErrorState message="该分类暂无模板" onRetry={() => loadCategories()} />
|
||||
)}
|
||||
|
||||
{/* 内容网格 - 使用 FlashList 优化性能 */}
|
||||
|
|
@ -659,26 +666,4 @@ const styles = StyleSheet.create({
|
|||
color: '#F5F5F5',
|
||||
lineHeight: 20,
|
||||
},
|
||||
emptyState: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 60,
|
||||
gap: 16,
|
||||
},
|
||||
emptyStateText: {
|
||||
color: '#ABABAB',
|
||||
fontSize: 14,
|
||||
},
|
||||
retryButton: {
|
||||
backgroundColor: '#FF6699',
|
||||
paddingHorizontal: 24,
|
||||
paddingVertical: 12,
|
||||
borderRadius: 8,
|
||||
},
|
||||
retryButtonText: {
|
||||
color: '#FFFFFF',
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
},
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue