From fdca879e2c31e6cb3673920399c95a1fc2f64217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=8F=E9=83=A8?= Date: Fri, 22 Mar 2024 22:14:47 +0800 Subject: [PATCH] fix --- 222100414_222100415/index.html | 2 +- 222100414_222100415/public/defaultAvatar.webp | Bin 0 -> 4242 bytes 222100414_222100415/src/common/api/api.ts | 116 +++++++++++-- .../component/mika-ui/Skeleton/Skeleton.less | 4 +- 222100414_222100415/src/page/App/App.tsx | 137 +-------------- .../src/page/DaliySchedule/DailySchedule.tsx | 156 +++++++++++++++--- .../page/DaliySchedule/DailyScheduleItem.tsx | 29 ++-- .../src/page/RankList/RankList.tsx | 49 +++--- 8 files changed, 283 insertions(+), 210 deletions(-) create mode 100644 222100414_222100415/public/defaultAvatar.webp diff --git a/222100414_222100415/index.html b/222100414_222100415/index.html index ab4dd64..fd48c16 100644 --- a/222100414_222100415/index.html +++ b/222100414_222100415/index.html @@ -3,7 +3,7 @@ - + Vite + React 18 + TS + TailwindCSS + ESLint + diff --git a/222100414_222100415/public/defaultAvatar.webp b/222100414_222100415/public/defaultAvatar.webp new file mode 100644 index 0000000000000000000000000000000000000000..f65da6d226fb5fd18a4c9efac203c3690c41f31d GIT binary patch literal 4242 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 literal 0 HcmV?d00001 diff --git a/222100414_222100415/src/common/api/api.ts b/222100414_222100415/src/common/api/api.ts index b321818..ab04a8a 100644 --- a/222100414_222100415/src/common/api/api.ts +++ b/222100414_222100415/src/common/api/api.ts @@ -1,33 +1,115 @@ -export interface Schedule { - UtcDateTime: string; - Date: string; - Time: string; - TimeZoneDisplayName: string; -} export const getSchedules = async () => { const response = await fetch('/api/fina/competitions/3337/schedule'); return response.json(); }; -export interface Competition { - Id: string; - DisciplineName: string; + +export const getResults = async (hash: string) => { + const response = await fetch(`/api/fina/events/${hash}`); + return await response.json(); +}; + +export const getDailySchedule = async () => { + const schedules = (await getSchedules()).map((item: any) => { + return { + Date: item.Date, + id: item.DisciplineId, + Name: item.DisciplineName + ' ' + item.Name, + }; + }); + + let dailySchedule = schedules.reduce((acc: any, cur: any) => { + if (!acc[cur.Date]) { + acc[cur.Date] = []; + } + acc[cur.Date].push(cur); + return acc; + }, {}); + + const map = new Map(); + for (const key in dailySchedule) { + for (const [index, item] of dailySchedule[key].entries()) { + if (map.has(item.id)) { + dailySchedule[key][index].data = map.get(item.id); + continue; + } + const data = await getResults(item.id); + const flag = data['Heats'][0]['Results'][0]['Competitors'] === null; + + dailySchedule[key][index].data = data['Heats'][0]['Results'].map((result: any) => { + return { + rank: result.Rank, + athlete: result.FullName, + country: result.NAT, + age: flag ? result.AthleteResultAge : (result.Competitors[0].AthleteResultAge || '?') + ' / ' + result.Competitors[1].AthleteResultAge, + points: result.TotalPoints, + ptsBehind: result.PointsBehind || '0' + }; + }); + + map.set(item.id, dailySchedule[key][index].data); + } + } + + dailySchedule = Object.entries(dailySchedule).map(([key, value]) => { + return { + Date: key, + data: value + }; + }); + + return dailySchedule; +}; + +export interface RankListData { + rank: number; + athlete: string; + country: string; + age: number; + points: number; } -export const getCompetitions = async (): Promise => { - const response = await fetch('https://swimming.abdecd.xyz/api/fina/competitions/3337/events'); - const data = await response.json() as { Sports: [{ DisciplineList: Competition[] }] }; - return data.Sports?.[0]?.DisciplineList; +export const getRankList = async () => { + const hash = '108c795d-5e4f-4dc6-acea-0bc70bfd1928'; + const data = await getResults(hash); + const result = data['Heats'][0]['Results']; + const rankList: RankListData[] = []; + for (const item of result) { + rankList.push({ + rank: item.Rank, + athlete: item.FullName, + country: item.NAT, + age: item.AthleteResultAge, + points: item.TotalPoints + }); + } + + return rankList; }; -getCompetitions().then(console.log); -export const getResults = async (hash: string) => { - const response = await fetch(`https://swimming.abdecd.xyz/api/fina/events/${hash}`); - return await response.json(); +export const getRankListAthletePhotos = async () => { + const hash = '108c795d-5e4f-4dc6-acea-0bc70bfd1928'; + return await getAthletePhotosById(hash); }; +export const getAthletePhotosById = async (id: string) => { + const data = await getResults(id); + const result = data['Heats'][0]['Results']; + const rankListData: any[] = []; + for (const item of result) { + const ResultId = item.ResultId.substring(1); + const dat = (await getAthletePhoto(ResultId))[0]; + rankListData.push(dat ? dat['imageUrl'] : '/defaultAvatar.webp'); + } + + return rankListData; +} + export const getCountryFlag = (country: string): string => { + if (!country) { + return '/defaultAvatar.webp'; + } return `https://www.worldaquatics.com/resources/v2.11.4/i/elements/flags/${country.toLowerCase()}.png`; }; diff --git a/222100414_222100415/src/component/mika-ui/Skeleton/Skeleton.less b/222100414_222100415/src/component/mika-ui/Skeleton/Skeleton.less index 9cb076e..be5ee7c 100644 --- a/222100414_222100415/src/component/mika-ui/Skeleton/Skeleton.less +++ b/222100414_222100415/src/component/mika-ui/Skeleton/Skeleton.less @@ -11,8 +11,8 @@ display: inline-block; width: 100%; height: 100%; - background: linear-gradient(90deg, rgba(0, 0, 0, 0.04) 25%, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0.04) 75%); + background: linear-gradient(90deg, rgba(255, 255, 255, 0.24) 25%, rgba(255, 255, 255, 0.34) 50%, rgba(255, 255, 255, 0.24) 75%); background-size: 400% 100%; border-radius: 4px; animation: mika-skeleton-loading 1.3s ease infinite; -} \ No newline at end of file +} diff --git a/222100414_222100415/src/page/App/App.tsx b/222100414_222100415/src/page/App/App.tsx index 985acff..55e4cb6 100644 --- a/222100414_222100415/src/page/App/App.tsx +++ b/222100414_222100415/src/page/App/App.tsx @@ -1,140 +1,10 @@ import Home from '../Home/Home'; import RankList from '../RankList/RankList'; import DailySchedule from '../DaliySchedule/DailySchedule'; -import MedalTally from '../MedalTally/MedalTally'; import LearnMore from '../LearnMore/LearnMore'; -import {getSchedules} from '../../common/api/api'; import './App.less'; import Header from '../../component/Header/Header'; -const data = [ - { - rank: 1, - name: 'John', - score: 100 - }, { - rank: 2, - name: 'Doe', - score: 90 - }, { - rank: 3, - name: 'Jane', - score: 80 - }, { - rank: 4, - name: 'Dane', - score: 70 - }, { - rank: 5, - name: 'Jone', - score: 60 - }, { - rank: 6, - name: 'Jone', - score: 50 - }, { - rank: 7, - name: 'Jone', - score: 40 - }, { - rank: 8, - name: 'Jone', - score: 30 - }, { - rank: 9, - name: 'Jone', - score: 20 - }, { - rank: 10, - name: 'Jone', - score: 10 - } -]; - -const dailyData = [ - { - title: 'Day 1', - data: [ - { - rank: 1, - athlete: 'John', - country: 'USA', - age: 20, - points: 100, - ptsBehind: 0 - }, { - rank: 2, - athlete: 'Doe', - country: 'USA', - age: 21, - points: 90, - ptsBehind: 10 - }, { - rank: 3, - athlete: 'Jane', - country: 'USA', - age: 22, - points: 80, - ptsBehind: 20 - }, { - rank: 4, - athlete: 'Dane', - country: 'USA', - age: 23, - points: 70, - ptsBehind: 30 - }, { - rank: 5, - athlete: 'Jone', - country: 'USA', - age: 24, - points: 60, - ptsBehind: 40 - } - ] - }, { - title: 'Day 2', - data: [ - { - rank: 1, - athlete: 'John', - country: 'USA', - age: 20, - points: 100, - ptsBehind: 0 - }, { - rank: 2, - athlete: 'Doe', - country: 'USA', - age: 21, - points: 90, - ptsBehind: 10 - }, { - rank: 3, - athlete: 'Jane', - country: 'USA', - age: 22, - points: 80, - ptsBehind: 20 - }, { - rank: 4, - athlete: 'Dane', - country: 'USA', - age: 23, - points: 70, - ptsBehind: 30 - }, { - rank: 5, - athlete: 'Jone', - country: 'USA', - age: 24, - points: 60, - ptsBehind: 40 - } - ] - } -]; - const content = { title: 'WORLD AQUATICS - THE GLOBAL HOME OF AQUATIC SPORTS', content: ['World Aquatics, formerly known as the Fédération Internationale de Natation (FINA), is the sole and exclusive world governing body for all Aquatics.  Since June 2021, under the presidency of Captain Husain Al Musallam, World Aquatics comprises 209 National Member Federations in the five continents.', @@ -142,14 +12,11 @@ const content = { }; const App = () => { - getSchedules().then(console.log); - return (
- - - + +
); }; diff --git a/222100414_222100415/src/page/DaliySchedule/DailySchedule.tsx b/222100414_222100415/src/page/DaliySchedule/DailySchedule.tsx index 35307b4..350e9b0 100644 --- a/222100414_222100415/src/page/DaliySchedule/DailySchedule.tsx +++ b/222100414_222100415/src/page/DaliySchedule/DailySchedule.tsx @@ -1,29 +1,123 @@ import React from 'react'; import Panel from '../../component/Panel/Panel'; import Title from '../../component/Title/Title'; -import DailyScheduleItem from './DailyScheduleItem'; import {theme} from '../../common/theme/theme'; +import {getDailySchedule} from '../../common/api/api'; +import DailyScheduleItem from './DailyScheduleItem'; +import {Skeleton} from '../../component/mika-ui'; + -export interface DailyScheduleProps extends React.HTMLAttributes { - data: { - title: string; +const Loading = () => { + return ( +
+ + + + +
+ ); +}; + +const DailyScheduleDateItem = (props: { + item: { + Date: string; data: { - rank: number; - athlete: string; - country: string; - age: number; - points: number; - ptsBehind: number; + Name: string; + data: { + rank: number; + athlete: string; + country: string; + age: number; + points: number; + ptsBehind: number; + }[]; }[]; - }[]; + } +}) => { + const {item} = props; + const [isOpen, setIsOpen] = React.useState(false); + + return (<> + { + isOpen ? (
+
setIsOpen(!isOpen)} + > +
{item.Date}
+
{isOpen ? '-' : '+'}
+
+
+
+ {item.data && item.data.map((i: { + Name: string; + data: { + rank: number; + athlete: string; + country: string; + age: number; + points: number; + ptsBehind: number; + }[]; + }, index: React.Key | null | undefined) => ( + + ))} +
+
+ ) : ( +
+
setIsOpen(!isOpen)} + > +
{item.Date}
+
{isOpen ? '-' : '+'}
+
+
+ ) + } + + ); +}; -} +const DailySchedule = () => { + const [list, setList] = React.useState([]); + const [loading, setLoading] = React.useState(true); -const DailySchedule = (props: DailyScheduleProps) => { - const { - data, - ...rest - } = props; + React.useEffect(() => { + getDailySchedule().then((res) => { + setList(res); + setLoading(false); + }); + }, []); + + if (loading) { + return ( +
+
+ + <Panel> + <Loading/> + </Panel> + </div> + </div> + ); + } return ( <div @@ -32,7 +126,6 @@ const DailySchedule = (props: DailyScheduleProps) => { style={{ backgroundColor: theme.background }} - {...rest} > <div className="flex flex-col gap-4 text-white" @@ -42,14 +135,25 @@ const DailySchedule = (props: DailyScheduleProps) => { > <Title title="Daily Schedule"/> <Panel> - <div className="text-black text-4xl bg-white p-4 rounded-tl-lg rounded-tr-lg select-none mb-4"> - {new Date().toLocaleDateString()} - </div> - <div className="overflow-y-auto"> - {data.map((item, index) => ( - <DailyScheduleItem key={index} title={item.title} data={item.data}/> - ))} - </div> + { + list && list.map((item: { + Date: string; + data: { + Name: string; + data: { + rank: number; + athlete: string; + country: string; + age: number; + points: number; + ptsBehind: number; + }[]; + }[]; + }, index) => { + return (<DailyScheduleDateItem key={index} item={item}/>); + }) + } + </Panel> </div> </div> diff --git a/222100414_222100415/src/page/DaliySchedule/DailyScheduleItem.tsx b/222100414_222100415/src/page/DaliySchedule/DailyScheduleItem.tsx index fe49101..06ff0d9 100644 --- a/222100414_222100415/src/page/DaliySchedule/DailyScheduleItem.tsx +++ b/222100414_222100415/src/page/DaliySchedule/DailyScheduleItem.tsx @@ -1,5 +1,6 @@ import React, {useState} from 'react'; import './DailyScheduleItem.less'; +import {getCountryFlag} from '../../common/api/api'; export interface DailyScheduleItemProps { title: string; @@ -18,11 +19,12 @@ const DailyScheduleItem = (props: DailyScheduleItemProps) => { title, data } = props; + console.log(data); const [isOpen, setIsOpen] = useState(false); return ( <div - className="flex flex-col gap-4 bg-white m-4 rounded-lg shadow-xl" + className="flex flex-col gap-4 bg-white mb-4 ml-4 mr-4 rounded-lg shadow-xl" > <div className="flex justify-between items-center text-black p-4 select-none text-2xl cursor-pointer" @@ -36,23 +38,30 @@ const DailyScheduleItem = (props: DailyScheduleItemProps) => { <div className="pb-4"> <div className="item-container grid grid-cols-6 gap-4 text-black text-2xl p-4"> <div className="flex justify-center">Rank</div> - <div className="flex justify-center">Athlete</div> - <div className="flex justify-center">Country</div> + <div className="flex justify-center justify-self-start">Athlete</div> + <div className="flex justify-center justify-self-start">Country</div> <div className="flex justify-center">Age</div> <div className="flex justify-center">Points</div> <div className="flex justify-center">Pts Behind</div> <div className="bg-black h-0.5 w-full col-span-6 rounded-lg"/> {data.map((item, index) => ( - <div key={index} className="item col-span-6 grid grid-cols-6 gap-4 text-black text-2xl p-1 rounded-2xl" + <div key={index} + className="item col-span-6 grid grid-cols-6 gap-4 text-black text-2xl p-1 rounded-2xl" style={{ boxShadow: '2px 2px 12px rgba(0, 0, 0, 0.1)' }}> - <div className="flex justify-center">{item.rank}</div> - <div className="flex justify-center">{item.athlete}</div> - <div className="flex justify-center">{item.country}</div> - <div className="flex justify-center">{item.age}</div> - <div className="flex justify-center">{item.points}</div> - <div className="flex justify-center">{item.ptsBehind}</div> + <div className="flex justify-center items-center">{item.rank}</div> + <div className="flex justify-center justify-self-start items-center"> + {item.athlete} + </div> + <div className="flex justify-center items-center justify-self-start gap-4"> + <img src={getCountryFlag(item.country)} alt="country" + className="w-6 h-6" loading="lazy"/> + {item.country} + </div> + <div className="flex justify-center items-center">{item.age}</div> + <div className="flex justify-center items-center">{item.points}</div> + <div className="flex justify-center items-center">{item.ptsBehind}</div> </div> ))} </div> diff --git a/222100414_222100415/src/page/RankList/RankList.tsx b/222100414_222100415/src/page/RankList/RankList.tsx index dcaf0a8..48d941f 100644 --- a/222100414_222100415/src/page/RankList/RankList.tsx +++ b/222100414_222100415/src/page/RankList/RankList.tsx @@ -1,24 +1,27 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import {theme} from '../../common/theme/theme'; import Panel from '../../component/Panel/Panel'; import Title from '../../component/Title/Title'; +import {getCountryFlag, getRankList, getRankListAthletePhotos, RankListData} from '../../common/api/api'; -export interface RankListProps extends React.HTMLAttributes<HTMLDivElement> { - data: any; -} +const RankList = () => { + const [list, setList] = React.useState<RankListData[]>([]); + const [photoList, setPhotoList] = React.useState<string[]>([]); + useEffect(() => { + getRankList().then((res) => { + setList(res); + }); -const RankList = (props: RankListProps) => { - const { - data, - ...rest - } = props; + getRankListAthletePhotos().then((res) => { + setPhotoList(res); + }); + }, []); return ( <div className="flex flex-col h-screen" id="ranklist" style={{backgroundColor: theme.background}} - {...rest} > <div className="flex flex-col gap-4" @@ -30,12 +33,12 @@ const RankList = (props: RankListProps) => { <Title title="Rank List"/> <Panel> <div className="text-black text-4xl bg-white p-4 rounded-tl-lg rounded-tr-lg select-none mb-4"> - Women's Singles + Women 1m Springboard </div> <div className="grid grid-cols-5 gap-4 text-white text-2xl"> <div className="flex justify-center">Rank</div> - <div className="flex justify-center">Athlete</div> - <div className="flex justify-center">Country</div> + <div className="flex justify-center justify-self-start">Athlete</div> + <div className="flex justify-center justify-self-start">Country</div> <div className="flex justify-center">Age</div> <div className="flex justify-center">Points</div> <div className="bg-white h-1 w-full col-span-5 rounded-lg"/> @@ -43,15 +46,23 @@ const RankList = (props: RankListProps) => { <div className="overflow-y-auto grid grid-cols-5 gap-4 text-white text-2xl pt-4 pb-4 rounded-2xl" > - {data.map((item: any, index: number) => ( + {list && list.map((item: any, index: number) => ( <React.Fragment key={index}> - <div className="flex justify-center" style={{ + <div className="flex justify-center items-center" style={{ color: item.rank === 1 ? 'gold' : item.rank === 2 ? 'silver' : item.rank === 3 ? '#cd7f32' : 'white' }}>{item.rank}</div> - <div className="flex justify-center">{item.name}</div> - <div className="flex justify-center">{item.country}</div> - <div className="flex justify-center">{item.age}</div> - <div className="flex justify-center">{item.points}</div> + <div className="flex justify-center items-center gap-4 justify-self-start"> + <img src={photoList[index]} alt="athlete" className="w-10 h-10 rounded-full" + loading="lazy"/> + {item.athlete} + </div> + <div className="flex justify-center items-center gap-4 justify-self-start "> + <img src={getCountryFlag(item.country)} alt="country" className="w-10 h-10" + loading="lazy"/> + {item.country} + </div> + <div className="flex justify-center items-center">{item.age}</div> + <div className="flex justify-center items-center">{item.points}</div> </React.Fragment> ))} </div> -- GitLab