152 lines
5.2 KiB
TypeScript
152 lines
5.2 KiB
TypeScript
import { useState } from 'react'
|
||
import { useRouter } from '@tarojs/taro'
|
||
import { View, Text, Input } from '@tarojs/components'
|
||
import { Navbar } from '@/components/navbar'
|
||
import { addCared, type EmergencyContact } from '@/api/family'
|
||
import { MAX_EMERGENCY_CONTACTS, MAX_FAMILY_NAME_LEN } from '@/constants/family'
|
||
import { navigateBack } from '@/utils/navigation'
|
||
import { showToast } from '@/utils/toast'
|
||
import { validateContactForm } from './validate'
|
||
import styles from './add.module.scss'
|
||
|
||
const emptyContact = (): EmergencyContact => ({
|
||
id: `tmp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
||
name: '',
|
||
phone: '',
|
||
relation: ''
|
||
})
|
||
|
||
export default function ContactAdd() {
|
||
const router = useRouter()
|
||
const familyId = router.params.familyId ?? ''
|
||
|
||
const [name, setName] = useState('')
|
||
const [idNumber, setIdNumber] = useState('')
|
||
const [address, setAddress] = useState('')
|
||
const [contacts, setContacts] = useState<EmergencyContact[]>([])
|
||
const [submitting, setSubmitting] = useState(false)
|
||
|
||
const patchContact = (id: string, key: keyof EmergencyContact, value: string) => {
|
||
setContacts((prev) => prev.map((c) => (c.id === id ? { ...c, [key]: value } : c)))
|
||
}
|
||
|
||
const removeContact = (id: string) => {
|
||
setContacts((prev) => prev.filter((c) => c.id !== id))
|
||
}
|
||
|
||
const submit = async () => {
|
||
if (submitting) return
|
||
const result = validateContactForm({ name, idNumber, address, contacts })
|
||
if (!result.ok) {
|
||
showToast(result.error)
|
||
return
|
||
}
|
||
|
||
setSubmitting(true)
|
||
try {
|
||
await addCared({
|
||
familyId,
|
||
name: name.trim(),
|
||
idNumber: idNumber.trim(),
|
||
address: address.trim(),
|
||
contacts: result.contacts
|
||
})
|
||
showToast('添加成功')
|
||
setTimeout(() => navigateBack(), 500)
|
||
} catch (error) {
|
||
showToast(error instanceof Error ? error.message : '添加失败')
|
||
} finally {
|
||
setSubmitting(false)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<View className={styles.page}>
|
||
<Navbar title="添加关爱对象" />
|
||
|
||
<View className={styles.card}>
|
||
<View className={styles.formRow}>
|
||
<Text className={styles.label}><Text className={styles.required}>*</Text>姓名</Text>
|
||
<Input
|
||
className={styles.input}
|
||
placeholder="请输入最多 10 个字"
|
||
maxlength={MAX_FAMILY_NAME_LEN}
|
||
value={name}
|
||
onInput={(e) => setName(e.detail.value)}
|
||
/>
|
||
</View>
|
||
<View className={styles.formRow}>
|
||
<Text className={styles.label}><Text className={styles.required}>*</Text>身份证号</Text>
|
||
<Input
|
||
className={styles.input}
|
||
placeholder="请输入身份证号"
|
||
value={idNumber}
|
||
onInput={(e) => setIdNumber(e.detail.value)}
|
||
/>
|
||
</View>
|
||
<View className={styles.formRow}>
|
||
<Text className={styles.label}><Text className={styles.required}>*</Text>关爱地址</Text>
|
||
<Input
|
||
className={styles.input}
|
||
placeholder="请输入关爱地址"
|
||
value={address}
|
||
onInput={(e) => setAddress(e.detail.value)}
|
||
/>
|
||
</View>
|
||
</View>
|
||
|
||
<View className={styles.contactsCard}>
|
||
<View className={styles.contactsHead}>
|
||
<Text className={styles.contactsTitle}>紧急联系人</Text>
|
||
{contacts.length < MAX_EMERGENCY_CONTACTS && (
|
||
<Text className={styles.contactsAdd} onClick={() => setContacts((p) => [...p, emptyContact()])}>
|
||
+ 添加
|
||
</Text>
|
||
)}
|
||
</View>
|
||
<Text className={styles.contactsTip}>最多可添加 {MAX_EMERGENCY_CONTACTS} 位紧急联系人,可不填</Text>
|
||
|
||
{contacts.map((c) => (
|
||
<View key={c.id} className={styles.contactItem}>
|
||
<View className={styles.contactDel} onClick={() => removeContact(c.id)}>
|
||
<Text className={styles.contactDelText}>×</Text>
|
||
</View>
|
||
<View className={styles.formRow}>
|
||
<Text className={styles.label}>姓名</Text>
|
||
<Input
|
||
className={styles.input}
|
||
placeholder="联系人姓名"
|
||
value={c.name}
|
||
onInput={(e) => patchContact(c.id, 'name', e.detail.value)}
|
||
/>
|
||
</View>
|
||
<View className={styles.formRow}>
|
||
<Text className={styles.label}>电话</Text>
|
||
<Input
|
||
className={styles.input}
|
||
type="number"
|
||
placeholder="联系人电话"
|
||
value={c.phone}
|
||
onInput={(e) => patchContact(c.id, 'phone', e.detail.value)}
|
||
/>
|
||
</View>
|
||
<View className={styles.formRow}>
|
||
<Text className={styles.label}>关系</Text>
|
||
<Input
|
||
className={styles.input}
|
||
placeholder="如:配偶、儿子"
|
||
value={c.relation}
|
||
onInput={(e) => patchContact(c.id, 'relation', e.detail.value)}
|
||
/>
|
||
</View>
|
||
</View>
|
||
))}
|
||
</View>
|
||
|
||
<View className={styles.submit} onClick={submit}>
|
||
<Text className={styles.submitText}>{submitting ? '提交中...' : '确认添加'}</Text>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|