import { useLocalSearchParams, useRouter } from 'expo-router'; import { useEffect, useState } from 'react'; import { Alert, ScrollView, StyleSheet, Text, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { PrimaryButton } from '../../components/onboarding/ui/PrimaryButton'; import { CenterState, EditHeader, Field, FormNote, IconAction, PageFooter, } from '../../components/resume/EditKit'; import { useResume } from '../../src/hooks'; import { colors , spacing } from '../../src/theme'; import type { ResumeProject } from '../../src/types'; /** * 项目经历编辑页:一页两态(列表态 / 表单态)。 * * 本页不提供「AI 优化」按钮:项目经历在首页只有「已量化」徽标, * 徽标的置位要等后端真能改写正文,不能让用户点出一个立刻显示「已优化」的假状态。 */ export default function ResumeProjectScreen() { const router = useRouter(); const params = useLocalSearchParams<{ new?: string; id?: string }>(); const { resume, loading, error, refresh, saving, saveProjects } = useResume(); const [editing, setEditing] = useState(null); const [entryApplied, setEntryApplied] = useState(false); useEffect(() => { if (!resume || entryApplied) return; setEntryApplied(true); if (params.new === '1') { setEditing(EMPTY_FORM); return; } if (params.id !== undefined && params.id !== '') { const found = resume.projects.find((it) => it.id === params.id); if (found) setEditing(toForm(found)); } }, [resume, entryApplied, params.new, params.id]); const list = resume?.projects ?? []; const header = ( (editing === null ? router.back() : setEditing(null))} /> ); if (resume === null) { return ( {header} {error !== null ? ( ) : ( )} ); } /* ===================== 表单态 ===================== */ if (editing !== null) { const name = editing.name.trim(); const canSave = name !== ''; const update = (patch: Partial) => setEditing((prev) => ({ ...(prev ?? editing), ...patch })); const handleSubmit = async () => { if (!canSave || saving) return; const fields = { name, role: editing.role.trim(), description: editing.description.trim(), aiOptimized: false, }; const next = editing.id === undefined ? [...list, fields] : list.map((it) => (it.id === editing.id ? { ...fields, id: editing.id } : it)); await saveProjects(next); setEditing(null); }; return ( {header} update({ name: v })} placeholder="请输入项目名称" maxLength={40} autoFocus /> update({ role: v })} placeholder="如:前端负责人" maxLength={20} /> update({ description: v })} placeholder="做了什么、结果如何(有数字更好,如:首屏从 3.5s 降至 1.2s)" multiline maxLength={500} /> ); } /* ===================== 列表态 ===================== */ const handleDelete = (item: ResumeProject) => { Alert.alert('删除这条项目经历?', item.name, [ { text: '取消', style: 'cancel' }, { text: '删除', style: 'destructive', onPress: () => { void saveProjects(list.filter((it) => it.id !== item.id)); }, }, ]); }; return ( {header} {list.length === 0 ? ( ) : ( {list.map((proj) => ( {proj.name} {proj.role !== '' && {proj.role}} {proj.description !== '' && ( {proj.description} )} setEditing(toForm(proj))} /> handleDelete(proj)} /> ))} )} setEditing(EMPTY_FORM)} /> ); } /* ===================== 表单与条目互转 ===================== */ interface ProjForm { /** undefined = 新增项(由 API 层补 id) */ id?: string; name: string; role: string; description: string; } const EMPTY_FORM: ProjForm = { name: '', role: '', description: '' }; const toForm = (proj: ResumeProject): ProjForm => ({ id: proj.id, name: proj.name, role: proj.role, description: proj.description, }); const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.pageBg }, body: { padding: spacing.card, paddingBottom: 24 }, row: { flexDirection: 'row', alignItems: 'center', backgroundColor: colors.white, borderRadius: spacing.card, padding: spacing.card, marginBottom: 8, borderWidth: 1, borderColor: colors.borderLight, }, rowBody: { flex: 1, gap: 4 }, rowTitle: { fontSize: 15, fontWeight: '700', color: colors.textPrimary }, rowSub: { fontSize: 13, color: colors.textSecondary }, rowDesc: { fontSize: 13, color: colors.textHint, lineHeight: 18 }, });