diff --git a/src/components/GameTable.tsx b/src/components/GameTable.tsx new file mode 100644 index 0000000..61bbe33 --- /dev/null +++ b/src/components/GameTable.tsx @@ -0,0 +1,104 @@ +import { Button, Divider, Flex, Table } from "antd"; +import type { GamesData } from "../types"; +import User from "./User"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useRequest } from "ahooks"; + +interface Props { + uid?: string; + data?: GamesData[]; +} + +function toTeams(data: GamesData) { + const { + uid1, uid11, username1, username11, + uid2, uid22, username2, username22, + result1, result2, ascore1, score1, score2, + } = data; + const isDoubles = Boolean(username11); + const team1 = [{ uid: uid1, name: username1 }]; + const team2 = [{ uid: uid2, name: username2 }]; + if (isDoubles) { + team1.push({ uid: uid11, name: username11 }); + team2.push({ uid: uid22, name: username22 }); + } + return { team1, team2 }; +} + +export function GameTable(props: Props) { + const [displayData, setDisplayData] = useState(props.data ?? []); + const [page, setPage] = useState(props.data?.length ? 1 :0); + const fetchNextPage = useRequest(async () => { + const newPage = page + 1; + const resp = await fetch(`/api/user/${props.uid}/games?page=${newPage}`); + const nextPageData: GamesData[] = await resp.json(); + setDisplayData(data => [...data, ...nextPageData]) + setPage(newPage); + return nextPageData; + }, { manual: true, refreshDeps: [page] }); + const hasMore = useMemo(() => page < 2 || (fetchNextPage.data?.length || 0) === 10, [page, fetchNextPage]); + + return ( + <> + 最近战绩 + e.gameid} + showHeader={false} + pagination={false} + dataSource={displayData} + size="small" + style={{ width: '100%', maxWidth: 400 }} + footer={() => ( + + + + )} + > + i + 1} /> + { + const { uid1 } = record; + const { team1, team2 } = toTeams(record); + return ( + + + + ); + })} + /> + { + const list = props.uid === uid1 ? [result1, result2] : [result2, result1]; + return list.join(':'); + }} + /> + { + return props.uid === uid1 ? score1 : score2; + }} + /> + +
+ + ); +} + +function PlayerTeam(props: { + idNames: { uid: string; name: string; }[] +}) { + return ( + + {props.idNames.map(e => (
))} +
+ ); +} \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 9ec0026..ac0ce8d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -41,6 +41,15 @@ const server = serve({ return Response.json(profile); }, }, + "/api/user/:uid/games": { + async GET(req) { + const uid = req.params.uid; + const search = new URL(req.url).searchParams; + const page = Number(search.get('page')) ?? 0; + const resp = await xcxApi.getGameList(uid, page); + return Response.json(resp); + }, + }, "/api/user/:uid/tags": { async GET(req) { const uid = req.params.uid; diff --git a/src/page/EventPage.tsx b/src/page/EventPage.tsx index 929e716..1ab60dc 100644 --- a/src/page/EventPage.tsx +++ b/src/page/EventPage.tsx @@ -4,6 +4,7 @@ import type { BasePlayer, MatchInfo, XCXMember } from "../types"; import { Typography } from "antd"; import { HomeOutlined } from "@ant-design/icons"; import { useMemo } from "react"; +import { useTitle } from "ahooks"; export default function EventPage() { const { @@ -20,6 +21,7 @@ export default function EventPage() { const basePlayers = useMemo(() => { return members.map(e => ({ ...e, name: e.realname } as BasePlayer)) }, [members]); + useTitle(game.title, { restoreOnUnmount: true }); return (
diff --git a/src/page/ProfilePage.tsx b/src/page/ProfilePage.tsx index a08ecb2..35e4e69 100644 --- a/src/page/ProfilePage.tsx +++ b/src/page/ProfilePage.tsx @@ -7,6 +7,8 @@ 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; @@ -82,6 +84,7 @@ export default function ProfilePage() { const profile = useLoaderData(); console.debug('profile', profile); const navigate = useNavigate(); + useTitle(`${profile?.username}${profile?.realname ? ` (${profile?.realname})` : ''} 个人详情`, { restoreOnUnmount: true }); return ( <> @@ -127,6 +130,7 @@ export default function ProfilePage() { + );