Files
hera-web/src/pages/fortune/index.tsx
T

51 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react'
import Taro from '@tarojs/taro'
import { Button, Image, Text, View } from '@tarojs/components'
import { AppTabBar } from '../../components/AppTabBar'
import { TiangongHeader, TiangongMockNote, TiangongModal } from '../../components/TiangongUI'
import { deityCatalog, isTiangongDemo, tiangongMock, tiangongSession } from '../../services/tiangong'
import { resolveAssetUrl } from '../../services/request'
import { useTiangongSnapshot } from '../../hooks/useTiangongSnapshot'
import { DeityId } from '../../utils/tiangongMock'
import { hasLoginAccess } from '../../services/loginAccess'
import { useRequiredLogin } from '../../hooks/useRequiredLogin'
import { TiangongLoginGate } from '../../components/TiangongLoginGate'
import './index.scss'
export default function FortunePage() {
const auth = useRequiredLogin()
if (auth.status !== 'allowed' || !hasLoginAccess()) return <TiangongLoginGate status={auth.status === 'allowed' ? 'denied' : auth.status} retry={auth.retry} tab />
return <FortuneContent />
}
function FortuneContent() {
const snapshot = useTiangongSnapshot()
const items = deityCatalog.map(item => ({ ...item, ...snapshot.deities[item.id] }))
const [selected, setSelected] = useState<DeityId | null>(null)
const [settings, setSettings] = useState(false)
const open = (id: DeityId, invite = false) => Taro.navigateTo({ url: `/pages/tiangong-detail/index?id=${id}${invite ? '&mode=invite' : ''}` })
return <View className='tiangong-page'>
<TiangongHeader title='天宫' /><TiangongMockNote />
{snapshot.loading && !snapshot.ready && <Text className='tg-data-note'>正在加载神仙列表…</Text>}
{snapshot.error && <View className='tg-data-note'><Text>{snapshot.error}</Text><Button onClick={() => tiangongSession.refresh(true).catch(() => {})}>重新加载</Button></View>}
<View className='deity-grid'>
{items.map(item => <View className='deity-card-wrap' key={item.id}>
<Button disabled={item.available === false} className={`deity-card ${item.unlocked ? 'unlocked' : 'locked'}`} aria-label={`${item.name},${item.unlocked ? '已恭请' : '未恭请'}`} onClick={() => item.unlocked ? open(item.id) : setSelected(selected === item.id ? null : item.id)}>
<Image className='deity-image' src={resolveAssetUrl(item.iconUrl) || item.icon} mode='aspectFill' /><Text className='deity-name'>{item.name}{item.available === false && snapshot.ready ? '(暂未配置)' : ''}</Text>
</Button>
{selected === item.id && !item.unlocked && <View className='deity-invite-prompt'>
<Button className='deity-prompt-close' aria-label='关闭恭请提示' onClick={() => setSelected(null)}>×</Button>
<Text>您还未恭请此神</Text><Text>是否恭请</Text>
<Button className='deity-invite-button' onClick={() => { setSelected(null); open(item.id, true) }}>恭请</Button>
</View>}
</View>)}
</View>
{isTiangongDemo() && <Button className='tg-demo-settings' onClick={() => setSettings(true)}>Mock 演示设置</Button>}
{settings && <TiangongModal title='Mock 演示设置' onClose={() => setSettings(false)} variant='plain'>
<Text className='tg-modal-title'>Mock 演示设置</Text><Text className='tg-modal-caption'>仅重置本次演示,不修改真实供奉记录。</Text>
<View className='tg-modal-actions'><Button className='tg-button' onClick={() => { tiangongMock.reset(); setSelected(null); setSettings(false) }}>重置全部演示</Button></View>
</TiangongModal>}
<AppTabBar active='fortune' />
</View>
}