114 lines
3.8 KiB
TypeScript
114 lines
3.8 KiB
TypeScript
import { getPageStyle } from '@/utils/page-style'
|
|
import { View, Text, Image } from '@tarojs/components'
|
|
import Taro, { useDidShow, useRouter } from '@tarojs/taro'
|
|
import { useState } from 'react'
|
|
|
|
import { getToken } from '@/services/auth'
|
|
import { setSelectedBindingDeviceId } from '@/services/binding'
|
|
import { setSelectedChildId } from '@/services/child'
|
|
import { acceptFamilyInvitation, FamilyInvitation, getFamilyInvitation } from '@/services/family'
|
|
import { usePageShare } from '@/utils/page-share'
|
|
import './index.scss'
|
|
|
|
export default function FamilyInvite() {
|
|
usePageShare()
|
|
const router = useRouter()
|
|
const inviteToken = String(router.params?.token || '').trim()
|
|
const redirectUrl = `/pages/family-invite/index?token=${inviteToken}`
|
|
const [loading, setLoading] = useState(true)
|
|
const [joining, setJoining] = useState(false)
|
|
const [invitation, setInvitation] = useState<FamilyInvitation | null>(null)
|
|
const [errorText, setErrorText] = useState('')
|
|
|
|
useDidShow(() => {
|
|
void loadInvitation()
|
|
})
|
|
|
|
const loadInvitation = async () => {
|
|
if (!getToken()) {
|
|
Taro.setStorageSync('postLoginRedirect', redirectUrl)
|
|
Taro.reLaunch({ url: '/pages/login/index' })
|
|
return
|
|
}
|
|
if (!inviteToken) {
|
|
setErrorText('邀请无效')
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
setLoading(true)
|
|
setErrorText('')
|
|
try {
|
|
const nextInvitation = await getFamilyInvitation(inviteToken)
|
|
setInvitation(nextInvitation)
|
|
} catch (error: any) {
|
|
setInvitation(null)
|
|
setErrorText(error?.message || '邀请加载失败')
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
const handleAccept = async () => {
|
|
if (!inviteToken || joining) return
|
|
|
|
setJoining(true)
|
|
try {
|
|
const result = await acceptFamilyInvitation(inviteToken)
|
|
setSelectedBindingDeviceId(result.device_id)
|
|
if (result.child_id) {
|
|
setSelectedChildId(result.child_id)
|
|
}
|
|
Taro.showToast({ title: '已加入家庭', icon: 'success' })
|
|
setTimeout(() => {
|
|
Taro.switchTab({ url: '/pages/device/index' })
|
|
}, 600)
|
|
} catch (error: any) {
|
|
Taro.showToast({
|
|
title: error?.message || '加入失败',
|
|
icon: 'none',
|
|
})
|
|
} finally {
|
|
setJoining(false)
|
|
}
|
|
}
|
|
|
|
const targetName = invitation?.child_name || invitation?.device_id || '--'
|
|
const statusText = invitation?.status === 1 ? '等待确认加入' : '邀请已失效'
|
|
|
|
return (
|
|
<View className='family-invite-page' style={getPageStyle(false)}>
|
|
<Image className='invite-mascot' src={require('../../assets/ui/dog-running.png')} mode='aspectFit' />
|
|
<View className='invite-panel'>
|
|
<Text className='invite-title'>家庭共享邀请</Text>
|
|
{loading ? (
|
|
<Text className='invite-desc'>加载中...</Text>
|
|
) : errorText ? (
|
|
<Text className='invite-desc danger'>{errorText}</Text>
|
|
) : (
|
|
<>
|
|
<View className='invite-row'>
|
|
<Text className='invite-label'>共享对象</Text>
|
|
<Text className='invite-value'>{targetName}</Text>
|
|
</View>
|
|
<View className='invite-row'>
|
|
<Text className='invite-label'>设备</Text>
|
|
<Text className='invite-value'>{invitation?.device_id || '--'}</Text>
|
|
</View>
|
|
<View className='invite-row'>
|
|
<Text className='invite-label'>状态</Text>
|
|
<Text className='invite-value'>{statusText}</Text>
|
|
</View>
|
|
<View
|
|
className={`invite-action ${invitation?.status === 1 && !joining ? '' : 'disabled'}`}
|
|
onClick={invitation?.status === 1 && !joining ? handleAccept : undefined}
|
|
>
|
|
<Text className='invite-action-text'>{joining ? '加入中...' : '加入家庭'}</Text>
|
|
</View>
|
|
</>
|
|
)}
|
|
</View>
|
|
</View>
|
|
)
|
|
}
|