137 lines
4.9 KiB
TypeScript
137 lines
4.9 KiB
TypeScript
import { Link, useLoaderData, useNavigate } from "react-router";
|
||
import type { XCXProfile } from "../types/profile";
|
||
import { Avatar, Descriptions, Divider, Flex, FloatButton, Image, Typography } from "antd";
|
||
import { HomeOutlined } from "@ant-design/icons";
|
||
|
||
import User from "../components/User";
|
||
import React from "react";
|
||
import { ChangeBackground } from "../components/ChangeBackground";
|
||
import UserTags from "../components/Tags";
|
||
import { GameTable } from "../components/GameTable";
|
||
import { useTitle } from "ahooks";
|
||
|
||
function Honor(props: { honors?: XCXProfile['honors'] }) {
|
||
if (!props.honors?.length) return null;
|
||
return (
|
||
<>
|
||
<Divider>荣誉</Divider>
|
||
<Flex vertical gap={12}>
|
||
{props.honors?.map(honor => {
|
||
return (
|
||
<Flex key={honor.hid} gap={12} style={{ width: '100%' }}>
|
||
<Image style={{ mixBlendMode: 'multiply' }} src={honor.honor} />
|
||
<Link to={`/event/${honor.eventid}`}>
|
||
<Typography.Text>
|
||
{honor.subject}
|
||
</Typography.Text>
|
||
</Link>
|
||
</Flex>
|
||
);
|
||
})}
|
||
</Flex>
|
||
</>
|
||
);
|
||
}
|
||
|
||
function Raket(props: { profile?: XCXProfile | null }) {
|
||
const {
|
||
qiupaitype = '',
|
||
zhengshoutype = '',
|
||
fanshoutype = '',
|
||
qiupai = '',
|
||
zhengshou = '',
|
||
fanshou = '',
|
||
} = props.profile || {};
|
||
if ([qiupaitype, zhengshoutype, fanshoutype].every(e => !e)) {
|
||
return null;
|
||
}
|
||
return (
|
||
<>
|
||
<Divider>装备</Divider>
|
||
<Descriptions>
|
||
<Descriptions.Item label="底板">
|
||
{qiupaitype}
|
||
<Typography.Text type="secondary" style={{ marginLeft: 4 }}>({qiupai})</Typography.Text>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label="正手">
|
||
{zhengshoutype}
|
||
<Typography.Text type="secondary" style={{ marginLeft: 4 }}>({zhengshou})</Typography.Text>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label="反手">
|
||
{fanshoutype}
|
||
<Typography.Text type="secondary" style={{ marginLeft: 4 }}>({fanshou})</Typography.Text>
|
||
</Descriptions.Item>
|
||
</Descriptions>
|
||
</>
|
||
);
|
||
}
|
||
|
||
function PlayerList(props: { title: string; names?: string[]; uids?: string[] }) {
|
||
if (!props.names?.length) return null;
|
||
return (
|
||
<>
|
||
<Typography.Title level={5}>{props.title}</Typography.Title>
|
||
<Flex vertical align="center">
|
||
{props.names.map((e, i) => (
|
||
<User key={e} name={e} uid={props.uids?.[i] ?? ''} />
|
||
))}
|
||
</Flex>
|
||
</>
|
||
);
|
||
}
|
||
|
||
export default function ProfilePage() {
|
||
const profile = useLoaderData<XCXProfile | null>();
|
||
console.debug('profile', profile);
|
||
const navigate = useNavigate();
|
||
useTitle(`${profile?.username}${profile?.realname ? ` (${profile?.realname})` : ''} 个人详情`, { restoreOnUnmount: true });
|
||
return (
|
||
<>
|
||
<ChangeBackground url={profile?.realpic} />
|
||
<FloatButton icon={<HomeOutlined />} onClick={() => navigate('/')} />
|
||
<Flex vertical align="center" style={{ padding: 24 }}>
|
||
<Avatar src={profile?.realpic} size={128} />
|
||
<Typography.Title level={2}>{profile?.username}</Typography.Title>
|
||
<Typography.Text>姓名:{profile?.realname}</Typography.Text>
|
||
<Typography.Text>积分:{profile?.score}</Typography.Text>
|
||
<Typography.Text style={{ textAlign: 'center' }}>
|
||
{
|
||
([profile?.province, profile?.sex, profile?.bg ?? '', ...(profile?.allCities ?? [])] as React.ReactNode[])
|
||
.filter(Boolean)
|
||
.reduce((a, b) => (<>{a}<Divider orientation="vertical" />{b}</>))
|
||
}
|
||
</Typography.Text>
|
||
<Divider>简介</Divider>
|
||
<Typography.Paragraph>
|
||
{profile?.description}
|
||
</Typography.Paragraph>
|
||
<UserTags uid={profile?.uid} />
|
||
<Raket profile={profile} />
|
||
<Flex wrap gap={24} justify="center">
|
||
<Flex vertical align="center">
|
||
<PlayerList title="交手前三名" names={profile?.TopPlayerUsernameScore} />
|
||
</Flex>
|
||
<Flex vertical align="center">
|
||
<PlayerList title="战胜前三名" names={profile?.Top3OfBeatUsernameScore} />
|
||
</Flex>
|
||
<Flex vertical align="center">
|
||
<PlayerList title="战胜的男子" names={profile?.Top3ManOfBeatUsernameScore} />
|
||
</Flex>
|
||
<Flex vertical align="center">
|
||
<PlayerList title="战胜的女子" names={profile?.Top3WomanOfBeatUsernameScore} />
|
||
</Flex>
|
||
</Flex>
|
||
<Flex gap={24}>
|
||
<Flex vertical align="center">
|
||
<PlayerList title="福星" names={profile?.FuXing?.names} uids={profile?.FuXing?.uids} />
|
||
</Flex>
|
||
<Flex vertical align="center">
|
||
<PlayerList title="苦主" names={profile?.KuZhu?.names} uids={profile?.KuZhu?.uids} />
|
||
</Flex>
|
||
</Flex>
|
||
<Honor honors={profile?.honors} />
|
||
<GameTable uid={profile?.uid} data={profile?.games.data} />
|
||
</Flex>
|
||
</>
|
||
);
|
||
} |