feat(index)
This commit is contained in:
parent
0f33f63459
commit
7df7b70516
7
src/components/ChangeBackground.tsx
Normal file
7
src/components/ChangeBackground.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { createGlobalStyle } from "styled-components";
|
||||
|
||||
export const ChangeBackground = createGlobalStyle<{ url?: string }>`
|
||||
body:before {
|
||||
${({ url }) => url ? `background: url(${url});` : ''}
|
||||
}
|
||||
`
|
||||
@ -1,10 +1,10 @@
|
||||
import { Card, Divider, Select, Space, Spin, Statistic, Typography } from 'antd';
|
||||
import { Card, Divider, Flex, Select, Space, Statistic, Switch, Typography } from 'antd';
|
||||
import type React from 'react';
|
||||
import { useRequest } from 'ahooks';
|
||||
import { clubs } from './clubList';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import type { IEventInfo } from '../../types';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import dayjs from 'dayjs';
|
||||
import type { IEventInfo } from '../../types';
|
||||
|
||||
interface Props {
|
||||
onGameClick?: (info: IEventInfo) => void;
|
||||
@ -14,14 +14,18 @@ export const GameSelector: React.FC<Props> = props => {
|
||||
const requestEvents = useRequest<IEventInfo[], [string]>(
|
||||
async (clubId: string) => (await fetch(`/api/events/${clubId}`)).json()
|
||||
, { manual: true })
|
||||
const [gameList, setGameList] = useState<IEventInfo[]>([]);
|
||||
const [gameList, setGameList] = useState<(IEventInfo & { finished: boolean })[]>([]);
|
||||
const [isEmpty, setIsEmpty] = useState(false);
|
||||
const [clubId, setClubId] = useState(clubs[0].clubId);
|
||||
const [showFinished, setShowFinished] = useState(false);
|
||||
const handleClubChange = useCallback(async (clubId: string) => {
|
||||
const list = await requestEvents.runAsync(clubId);
|
||||
const activeList = list.filter(e => !e.info.join('').includes('已结束'));
|
||||
const activeList = list.map(e => ({
|
||||
...e,
|
||||
finished: e.info.join('').includes('已结束'),
|
||||
}));
|
||||
setGameList(activeList);
|
||||
setIsEmpty(activeList.length === 0);
|
||||
setIsEmpty(activeList.filter(e => !e.finished).length === 0);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
const clubId = clubs[0].clubId;
|
||||
@ -29,6 +33,11 @@ export const GameSelector: React.FC<Props> = props => {
|
||||
}, []);
|
||||
return (
|
||||
<Space orientation='vertical' style={{ width: '100%' }}>
|
||||
<Flex vertical gap={12} justify='center'>
|
||||
<Space style={{ alignItems: 'self-end' }}>
|
||||
<Typography.Text>已结束的比赛</Typography.Text>
|
||||
<Switch checkedChildren='显示' unCheckedChildren='隐藏' checked={showFinished} onChange={e => setShowFinished(e)} />
|
||||
</Space>
|
||||
<Select
|
||||
style={{ width: '100%' }}
|
||||
placeholder={'请选择俱乐部'}
|
||||
@ -37,10 +46,25 @@ export const GameSelector: React.FC<Props> = props => {
|
||||
options={clubs.map(e => ({ label: e.name, value: e.clubId }))}
|
||||
onChange={handleClubChange}
|
||||
/>
|
||||
<Divider />
|
||||
{isEmpty && (<Typography.Text type='secondary'>没有未开始的比赛</Typography.Text>)}
|
||||
<Spin spinning={requestEvents.loading}>
|
||||
{gameList.map(e => {
|
||||
</Flex>
|
||||
<Divider>{isEmpty && (<Typography.Text type='secondary'>没有未开始的比赛</Typography.Text>)}</Divider>
|
||||
<Flex wrap gap={12} justify='center'>
|
||||
{gameList
|
||||
.filter(e => showFinished || !e.finished)
|
||||
.map(e => <EventCard key={e.matchId} eventInfo={e} onGameClick={props.onGameClick} />)
|
||||
}
|
||||
</Flex>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
interface EventCardProps {
|
||||
eventInfo: IEventInfo & { finished: boolean };
|
||||
onGameClick?: (info: IEventInfo) => void;
|
||||
}
|
||||
|
||||
function EventCard(props: EventCardProps) {
|
||||
const { eventInfo: e } = props;
|
||||
const { y, M, D } = /^(?<y>\d{4})年(?<M>\d+)月(?<D>\d+)日/.exec(e.title)?.groups ?? {} as { y: string; M: string; D: string};
|
||||
const hm = /(?<hm>\d+:\d+)\b/.exec(e.info.join('\n'))?.groups?.hm ?? '10:00';
|
||||
const day = dayjs(`${y}-${M}-${D} ${hm}`);
|
||||
@ -49,23 +73,21 @@ export const GameSelector: React.FC<Props> = props => {
|
||||
key={e.matchId}
|
||||
title={e.title}
|
||||
hoverable
|
||||
style={{ width: '100%' }}
|
||||
onClick={() => props.onGameClick?.(e)}
|
||||
>
|
||||
<Typography.Text type='success'>{e.title}</Typography.Text>
|
||||
<Typography.Text type={e.finished ? undefined : 'success'}>{e.title}</Typography.Text>
|
||||
<Statistic.Timer
|
||||
type={e.finished ? 'countup' : 'countdown'}
|
||||
value={day.toDate().getTime()}
|
||||
format={`距离比赛${e.finished ? '结束' : '开始'}: DD 天${e.finished ? '' : ' HH 时'}`}
|
||||
styles={{ content: e.finished ? { color: 'gray' } : {} }}
|
||||
/>
|
||||
{e.info.map(e => (
|
||||
<div key={e}>
|
||||
<Typography.Text type='secondary'>{e}</Typography.Text>
|
||||
</div>
|
||||
))}
|
||||
<Statistic.Timer
|
||||
type='countdown'
|
||||
value={day.toDate().getTime()}
|
||||
format='距离比赛开始: DD 天 HH 时 mm 分 ss 秒'
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</Spin>
|
||||
</Space>
|
||||
);
|
||||
)
|
||||
}
|
||||
@ -5,13 +5,7 @@ import { HomeOutlined } from "@ant-design/icons";
|
||||
|
||||
import User from "../components/User";
|
||||
import React from "react";
|
||||
import { createGlobalStyle } from "styled-components";
|
||||
|
||||
const BodyBG = createGlobalStyle<{ url?: string }>`
|
||||
body:before {
|
||||
${({ url }) => url ? `background: url(${url});` : ''}
|
||||
}
|
||||
`
|
||||
import { ChangeBackground } from "../components/ChangeBackground";
|
||||
|
||||
function Honor(props: { honors?: XCXProfile['honors'] }) {
|
||||
if (!props.honors?.length) return null;
|
||||
@ -81,7 +75,7 @@ export default function ProfilePage() {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<>
|
||||
<BodyBG url={profile?.realpic} />
|
||||
<ChangeBackground url={profile?.realpic} />
|
||||
<FloatButton icon={<HomeOutlined />} onClick={() => navigate('/')} />
|
||||
<Flex vertical align="center" style={{ padding: 24 }}>
|
||||
<Avatar src={profile?.realpic} size={128} />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user