aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2024-09-03 09:42:34 +0300
committerArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2024-09-03 09:42:34 +0300
commit9afd15d201a3a725af6662a6d8e81a79e71ac137 (patch)
tree9d715ecf62cb1795ac94ecdb71aac1d3b380576a
parentrefactor: port to typescript (diff)
downloadlphub-9afd15d201a3a725af6662a6d8e81a79e71ac137.tar.gz
lphub-9afd15d201a3a725af6662a6d8e81a79e71ac137.tar.bz2
lphub-9afd15d201a3a725af6662a6d8e81a79e71ac137.zip
refactor: dont ignore config file, small fix in profile
-rw-r--r--frontend/src/App.tsx2
-rw-r--r--frontend/src/pages/Profile.tsx68
-rw-r--r--frontend/tsconfig.json28
3 files changed, 61 insertions, 37 deletions
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 555ce4c..36c2d03 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -27,7 +27,7 @@ const App: React.FC = () => {
27 <Sidebar setToken={setToken} profile={profile} setProfile={setProfile} /> 27 <Sidebar setToken={setToken} profile={profile} setProfile={setProfile} />
28 <Routes> 28 <Routes>
29 <Route path="/" element={<div>yo</div>} /> 29 <Route path="/" element={<div>yo</div>} />
30 <Route path="/profile" element={<Profile profile={profile!} />} /> 30 <Route path="/profile" element={<Profile profile={profile} />} />
31 <Route path="/users/*" element={<User />} /> 31 <Route path="/users/*" element={<User />} />
32 <Route path="/games" element={<Games />} /> 32 <Route path="/games" element={<Games />} />
33 <Route path="/maps/*" element={<Maps isModerator={isModerator} />} /> 33 <Route path="/maps/*" element={<Maps isModerator={isModerator} />} />
diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx
index 8654a03..8eec23c 100644
--- a/frontend/src/pages/Profile.tsx
+++ b/frontend/src/pages/Profile.tsx
@@ -5,10 +5,11 @@ import { SteamIcon, TwitchIcon, YouTubeIcon, PortalIcon, FlagIcon, StatisticsIco
5import { UserProfile } from '../types/Profile'; 5import { UserProfile } from '../types/Profile';
6import { Game, GameChapters } from '../types/Game'; 6import { Game, GameChapters } from '../types/Game';
7import { Map } from '../types/Map'; 7import { Map } from '../types/Map';
8import { ticks_to_time } from '../utils/Time';
8import "../css/Profile.css"; 9import "../css/Profile.css";
9 10
10interface ProfileProps { 11interface ProfileProps {
11 profile: UserProfile; 12 profile?: UserProfile;
12} 13}
13 14
14const Profile: React.FC<ProfileProps> = ({ profile }) => { 15const Profile: React.FC<ProfileProps> = ({ profile }) => {
@@ -53,45 +54,34 @@ const Profile: React.FC<ProfileProps> = ({ profile }) => {
53 .then(d => d.success ? window.alert("profile updated") : window.alert(`Error: ${d.message}`)) 54 .then(d => d.success ? window.alert("profile updated") : window.alert(`Error: ${d.message}`))
54 } 55 }
55 56
56 function TicksToTime(ticks: number) {
57
58 let seconds = Math.floor(ticks / 60)
59 let minutes = Math.floor(seconds / 60)
60 let hours = Math.floor(minutes / 60)
61
62 let milliseconds = Math.floor((ticks % 60) * 1000 / 60)
63 seconds = seconds % 60;
64 minutes = minutes % 60;
65
66 return `${hours === 0 ? "" : hours + ":"}${minutes === 0 ? "" : hours > 0 ? minutes.toString().padStart(2, '0') + ":" : (minutes + ":")}${minutes > 0 ? seconds.toString().padStart(2, '0') : seconds}.${milliseconds.toString().padStart(3, '0')} (${ticks})`;
67 }
68
69 React.useEffect(() => { 57 React.useEffect(() => {
70 fetch("https://lp.ardapektezol.com/api/v1/games") 58 if (profile) {
71 .then(r => r.json()) 59 fetch("https://lp.ardapektezol.com/api/v1/games")
72 .then(d => {
73 setGameData(d.data)
74 setGame("0")
75 })
76
77 }, [location]);
78
79 React.useEffect(() => {
80 if (game && game !== "0") {
81 fetch(`https://lp.ardapektezol.com/api/v1/games/${game}`)
82 .then(r => r.json()) 60 .then(r => r.json())
83 .then(d => { 61 .then(d => {
84 setChapterData(d.data) 62 setGameData(d.data)
85 setChapter("0"); 63 setGame("0")
86 // (document.querySelector('#select-chapter') as HTMLInputElement).value = "0"
87 }) 64 })
88
89 } else if (game && game === "0") {
90 setPageMax(Math.ceil(profile.records.length / 20))
91 setPageNumber(1)
92 } 65 }
66 }, [profile, location]);
93 67
94 }, [game, location]); 68 React.useEffect(() => {
69 if (profile) {
70 if (game && game !== "0") {
71 fetch(`https://lp.ardapektezol.com/api/v1/games/${game}`)
72 .then(r => r.json())
73 .then(d => {
74 setChapterData(d.data)
75 setChapter("0");
76 // (document.querySelector('#select-chapter') as HTMLInputElement).value = "0"
77 })
78
79 } else if (game && game === "0") {
80 setPageMax(Math.ceil(profile.records.length / 20))
81 setPageNumber(1)
82 }
83 }
84 }, [profile, game, location]);
95 85
96 React.useEffect(() => { 86 React.useEffect(() => {
97 if (game !== "0") { 87 if (game !== "0") {
@@ -116,6 +106,12 @@ const Profile: React.FC<ProfileProps> = ({ profile }) => {
116 } 106 }
117 }, [game, chapter, chapterData]) 107 }, [game, chapter, chapterData])
118 108
109 if (!profile) {
110 return (
111 <></>
112 );
113 };
114
119 return ( 115 return (
120 <main> 116 <main>
121 <section id='section1' className='profile'> 117 <section id='section1' className='profile'>
@@ -249,7 +245,7 @@ const Profile: React.FC<ProfileProps> = ({ profile }) => {
249 <span style={{ display: "grid" }}>{e.score_count}</span> 245 <span style={{ display: "grid" }}>{e.score_count}</span>
250 246
251 <span style={{ display: "grid" }}>{e.score_count - r.map_wr_count}</span> 247 <span style={{ display: "grid" }}>{e.score_count - r.map_wr_count}</span>
252 <span style={{ display: "grid" }}>{TicksToTime(e.score_time)}</span> 248 <span style={{ display: "grid" }}>{ticks_to_time(e.score_time)}</span>
253 <span> </span> 249 <span> </span>
254 {i === 0 ? <span>#{r.placement}</span> : <span> </span>} 250 {i === 0 ? <span>#{r.placement}</span> : <span> </span>}
255 <span>{e.date.split("T")[0]}</span> 251 <span>{e.date.split("T")[0]}</span>
@@ -294,7 +290,7 @@ const Profile: React.FC<ProfileProps> = ({ profile }) => {
294 <span>{r.name}</span> 290 <span>{r.name}</span>
295 <span style={{ display: "grid" }}>{record!.scores[i].score_count}</span> 291 <span style={{ display: "grid" }}>{record!.scores[i].score_count}</span>
296 <span style={{ display: "grid" }}>{record!.scores[i].score_count - record!.map_wr_count}</span> 292 <span style={{ display: "grid" }}>{record!.scores[i].score_count - record!.map_wr_count}</span>
297 <span style={{ display: "grid" }}>{TicksToTime(record!.scores[i].score_time)}</span> 293 <span style={{ display: "grid" }}>{ticks_to_time(record!.scores[i].score_time)}</span>
298 <span> </span> 294 <span> </span>
299 {i === 0 ? <span>#{record!.placement}</span> : <span> </span>} 295 {i === 0 ? <span>#{record!.placement}</span> : <span> </span>}
300 <span>{record!.scores[i].date.split("T")[0]}</span> 296 <span>{record!.scores[i].date.split("T")[0]}</span>
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
new file mode 100644
index 0000000..ab0af5e
--- /dev/null
+++ b/frontend/tsconfig.json
@@ -0,0 +1,28 @@
1{
2 "compilerOptions": {
3 "target": "es5",
4 "lib": [
5 "dom",
6 "dom.iterable",
7 "esnext"
8 ],
9 "allowJs": true,
10 "skipLibCheck": true,
11 "esModuleInterop": true,
12 "allowSyntheticDefaultImports": true,
13 "strict": true,
14 "forceConsistentCasingInFileNames": true,
15 "noFallthroughCasesInSwitch": true,
16 "strictNullChecks": true,
17 // "allowImportingTsExtensions": false,
18 "module": "esnext",
19 "moduleResolution": "node",
20 "resolveJsonModule": true,
21 "isolatedModules": true,
22 "noEmit": true,
23 "jsx": "react-jsx"
24 },
25 "include": [
26 "src"
27 ]
28}