Files
banban/banban-mini/src/pages/family-invite/index.tsx
T

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>
)
}