|
|
|
@ -1,7 +1,7 @@ |
|
|
|
import { Ionicons } from '@expo/vector-icons'; |
|
|
|
import { LinearGradient } from 'expo-linear-gradient'; |
|
|
|
import { useRouter } from 'expo-router'; |
|
|
|
import { useMemo, useState } from 'react'; |
|
|
|
import { useEffect, useMemo, useState } from 'react'; |
|
|
|
import { |
|
|
|
ActivityIndicator, |
|
|
|
Pressable, |
|
|
|
@ -231,13 +231,28 @@ function ErrorState({ onRetry }: { onRetry: () => void }) { |
|
|
|
export default function ProgressScreen() { |
|
|
|
const router = useRouter(); |
|
|
|
const { progress, loading, error, refresh } = useJobProgress(); |
|
|
|
// 公司列表首屏抽样条数:列表过长时只列前 N 家,并提供「查看全部」入口(移动端长列表标准做法)
|
|
|
|
const PREVIEW_COUNT = 5; |
|
|
|
const [activeTab, setActiveTab] = useState<'all' | JobProgressStage>('all'); |
|
|
|
const [showAll, setShowAll] = useState(false); |
|
|
|
|
|
|
|
const totalCompanies = progress?.companies.length ?? 0; |
|
|
|
|
|
|
|
const companies = useMemo(() => { |
|
|
|
if (!progress) return []; |
|
|
|
if (activeTab === 'all') return progress.companies; |
|
|
|
return progress.companies.filter((c) => c.stage === activeTab); |
|
|
|
}, [progress, activeTab]); |
|
|
|
const list = |
|
|
|
activeTab === 'all' |
|
|
|
? progress.companies |
|
|
|
: progress.companies.filter((c) => c.stage === activeTab); |
|
|
|
// 「全部」页首屏只抽样前 N 家;切到具体阶段或展开后展示全量
|
|
|
|
if (activeTab === 'all' && !showAll) return list.slice(0, PREVIEW_COUNT); |
|
|
|
return list; |
|
|
|
}, [progress, activeTab, showAll]); |
|
|
|
|
|
|
|
// 切换 Tab 时重置「展开全部」,回到抽样视图
|
|
|
|
useEffect(() => { |
|
|
|
setShowAll(false); |
|
|
|
}, [activeTab]); |
|
|
|
|
|
|
|
// 标题文字跟随当前 Tab,与下方列表同源(见渲染处注释)
|
|
|
|
const activeLabel = TABS.find((tab) => tab.key === activeTab)?.label ?? '全部'; |
|
|
|
@ -286,7 +301,18 @@ export default function ProgressScreen() { |
|
|
|
<Text style={styles.emptyHint}>投递岗位后,进度会在这里按阶段更新</Text> |
|
|
|
</View> |
|
|
|
) : ( |
|
|
|
companies.map((company) => <CompanyRow key={company.id} company={company} />) |
|
|
|
<> |
|
|
|
{companies.map((company) => ( |
|
|
|
<CompanyRow key={company.id} company={company} /> |
|
|
|
))} |
|
|
|
{/* 全部页且公司数超过抽样条数:提供「查看全部 N 家」入口,展开后渲染完整列表 */} |
|
|
|
{activeTab === 'all' && totalCompanies > PREVIEW_COUNT && !showAll && ( |
|
|
|
<Pressable style={styles.viewAllBtn} onPress={() => setShowAll(true)} hitSlop={4}> |
|
|
|
<Text style={styles.viewAllText}>查看全部 {totalCompanies} 家</Text> |
|
|
|
<Ionicons name="chevron-forward" size={16} color={colors.primary} /> |
|
|
|
</Pressable> |
|
|
|
)} |
|
|
|
</> |
|
|
|
)} |
|
|
|
|
|
|
|
{progress.offers.length > 0 && ( |
|
|
|
@ -319,6 +345,19 @@ const styles = StyleSheet.create({ |
|
|
|
headerBtn: { width: 40, alignItems: 'center' }, |
|
|
|
headerTitle: { fontSize: 17, fontWeight: '700', color: colors.textPrimary }, |
|
|
|
body: { padding: 8, paddingBottom: 32 }, |
|
|
|
viewAllBtn: { |
|
|
|
flexDirection: 'row', |
|
|
|
alignItems: 'center', |
|
|
|
justifyContent: 'center', |
|
|
|
marginTop: 8, |
|
|
|
paddingVertical: 12, |
|
|
|
}, |
|
|
|
viewAllText: { |
|
|
|
fontSize: 14, |
|
|
|
fontWeight: '600', |
|
|
|
color: colors.primary, |
|
|
|
marginRight: 2, |
|
|
|
}, |
|
|
|
statsCard: { |
|
|
|
borderRadius: 8, |
|
|
|
padding: 8, |
|
|
|
|