diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2024-09-03 00:08:53 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2024-09-03 00:08:53 +0300 |
| commit | a65d6d9127c3fa7f6a8ecaec5d1ffd1f47c2bc98 (patch) | |
| tree | edf8630e9d6426124dd49854af0cb703ebc5b710 /frontend/src/components/Summary.tsx | |
| parent | fix: revert to static homepage (#195) (diff) | |
| download | lphub-a65d6d9127c3fa7f6a8ecaec5d1ffd1f47c2bc98.tar.gz lphub-a65d6d9127c3fa7f6a8ecaec5d1ffd1f47c2bc98.tar.bz2 lphub-a65d6d9127c3fa7f6a8ecaec5d1ffd1f47c2bc98.zip | |
refactor: port to typescript
Diffstat (limited to 'frontend/src/components/Summary.tsx')
| -rw-r--r-- | frontend/src/components/Summary.tsx | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/frontend/src/components/Summary.tsx b/frontend/src/components/Summary.tsx new file mode 100644 index 0000000..b8f0087 --- /dev/null +++ b/frontend/src/components/Summary.tsx | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | import React from 'react'; | ||
| 2 | import ReactMarkdown from 'react-markdown'; | ||
| 3 | |||
| 4 | import { MapSummary } from '../types/Map'; | ||
| 5 | import "../css/Maps.css" | ||
| 6 | |||
| 7 | interface SummaryProps { | ||
| 8 | selectedRun: number | ||
| 9 | setSelectedRun: (x: number) => void; | ||
| 10 | data: MapSummary; | ||
| 11 | } | ||
| 12 | |||
| 13 | const Summary: React.FC<SummaryProps> = ({ selectedRun, setSelectedRun, data }) => { | ||
| 14 | |||
| 15 | const [selectedCategory, setSelectedCategory] = React.useState<number>(1); | ||
| 16 | const [historySelected, setHistorySelected] = React.useState<boolean>(false); | ||
| 17 | |||
| 18 | function _select_run(x: number, y: number) { | ||
| 19 | let r = document.querySelectorAll("button.record"); | ||
| 20 | r.forEach(e => (e as HTMLElement).style.backgroundColor = "#2b2e46"); | ||
| 21 | (r[x] as HTMLElement).style.backgroundColor = "#161723" | ||
| 22 | |||
| 23 | |||
| 24 | if (data && data.summary.routes.length !== 0 && data.summary.routes.length !== 0) { | ||
| 25 | if (y === 2) { x += data.summary.routes.filter(e => e.category.id < 2).length } | ||
| 26 | if (y === 3) { x += data.summary.routes.filter(e => e.category.id < 3).length } | ||
| 27 | if (y === 4) { x += data.summary.routes.filter(e => e.category.id < 4).length } | ||
| 28 | setSelectedRun(x); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | function _get_youtube_id(url: string): string { | ||
| 33 | const urlArray = url.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); | ||
| 34 | return (urlArray[2] !== undefined) ? urlArray[2].split(/[^0-9a-z_]/i)[0] : urlArray[0]; | ||
| 35 | }; | ||
| 36 | |||
| 37 | function _category_change() { | ||
| 38 | const btn = document.querySelectorAll("#section3 #category span button"); | ||
| 39 | btn.forEach((e) => { (e as HTMLElement).style.backgroundColor = "#2b2e46" }); | ||
| 40 | (btn[selectedCategory - 1] as HTMLElement).style.backgroundColor = "#202232"; | ||
| 41 | }; | ||
| 42 | |||
| 43 | function _history_change() { | ||
| 44 | const btn = document.querySelectorAll("#section3 #history span button"); | ||
| 45 | btn.forEach((e) => { (e as HTMLElement).style.backgroundColor = "#2b2e46" }); | ||
| 46 | (historySelected ? btn[1] as HTMLElement : btn[0] as HTMLElement).style.backgroundColor = "#202232"; | ||
| 47 | }; | ||
| 48 | |||
| 49 | React.useEffect(() => { | ||
| 50 | _history_change(); | ||
| 51 | }, [historySelected]); | ||
| 52 | |||
| 53 | React.useEffect(() => { | ||
| 54 | _category_change(); | ||
| 55 | }, [selectedCategory]); | ||
| 56 | |||
| 57 | React.useEffect(() => { | ||
| 58 | _select_run(0, selectedCategory); | ||
| 59 | }, []); | ||
| 60 | |||
| 61 | return ( | ||
| 62 | <> | ||
| 63 | <section id='section3' className='summary1'> | ||
| 64 | <div id='category' | ||
| 65 | style={data.map.image === "" ? { backgroundColor: "#202232" } : {}}> | ||
| 66 | <img src={data.map.image} alt="" id='category-image'></img> | ||
| 67 | <p><span className='portal-count'>{data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].history.score_count}</span> | ||
| 68 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].history.score_count === 1 ? ` portal` : ` portals`}</p> | ||
| 69 | <span> | ||
| 70 | <button onClick={() => setSelectedCategory(1)}>CM</button> | ||
| 71 | <button onClick={() => setSelectedCategory(2)}>NoSLA</button> | ||
| 72 | {data.map.is_coop ? <button onClick={() => setSelectedCategory(3)}>SLA</button> | ||
| 73 | : <button onClick={() => setSelectedCategory(3)}>Inbounds SLA</button>} | ||
| 74 | <button onClick={() => setSelectedCategory(4)}>Any%</button> | ||
| 75 | </span> | ||
| 76 | |||
| 77 | </div> | ||
| 78 | |||
| 79 | <div id='history'> | ||
| 80 | |||
| 81 | <div style={{ display: historySelected ? "none" : "block" }}> | ||
| 82 | {data.summary.routes.filter(e => e.category.id === selectedCategory).length === 0 ? <h5>There are no records for this map.</h5> : | ||
| 83 | <> | ||
| 84 | <div className='record-top'> | ||
| 85 | <span>Date</span> | ||
| 86 | <span>Record</span> | ||
| 87 | <span>First completion</span> | ||
| 88 | </div> | ||
| 89 | <hr /> | ||
| 90 | <div id='records'> | ||
| 91 | |||
| 92 | {data.summary.routes | ||
| 93 | .sort((a, b) => a.history.score_count - b.history.score_count) | ||
| 94 | .filter(e => e.category.id === selectedCategory) | ||
| 95 | .map((r, index) => ( | ||
| 96 | <button className='record' key={index} onClick={() => { | ||
| 97 | _select_run(index, r.category.id); | ||
| 98 | }}> | ||
| 99 | <span>{new Date(r.history.date).toLocaleDateString( | ||
| 100 | "en-US", { month: 'long', day: 'numeric', year: 'numeric' } | ||
| 101 | )}</span> | ||
| 102 | <span>{r.history.score_count}</span> | ||
| 103 | <span>{r.history.runner_name}</span> | ||
| 104 | </button> | ||
| 105 | ))} | ||
| 106 | </div> | ||
| 107 | </> | ||
| 108 | } | ||
| 109 | </div> | ||
| 110 | |||
| 111 | <div style={{ display: historySelected ? "block" : "none" }}> | ||
| 112 | {data.summary.routes.filter(e => e.category.id === selectedCategory).length === 0 ? <h5>There are no records for this map.</h5> : | ||
| 113 | <div id='graph'> | ||
| 114 | {/* <div>{graph(1)}</div> | ||
| 115 | <div>{graph(2)}</div> | ||
| 116 | <div>{graph(3)}</div> */} | ||
| 117 | </div> | ||
| 118 | } | ||
| 119 | </div> | ||
| 120 | <span> | ||
| 121 | <button onClick={() => setHistorySelected(false)}>List</button> | ||
| 122 | <button onClick={() => setHistorySelected(true)}>Graph</button> | ||
| 123 | </span> | ||
| 124 | </div> | ||
| 125 | |||
| 126 | |||
| 127 | </section> | ||
| 128 | <section id='section4' className='summary1'> | ||
| 129 | <div id='difficulty'> | ||
| 130 | <span>Difficulty</span> | ||
| 131 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 0 ? (<span>N/A</span>) : null} | ||
| 132 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 1 ? (<span style={{ color: "lime" }}>Very easy</span>) : null} | ||
| 133 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 2 ? (<span style={{ color: "green" }}>Easy</span>) : null} | ||
| 134 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 3 ? (<span style={{ color: "yellow" }}>Medium</span>) : null} | ||
| 135 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 4 ? (<span style={{ color: "orange" }}>Hard</span>) : null} | ||
| 136 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 5 ? (<span style={{ color: "red" }}>Very hard</span>) : null} | ||
| 137 | <div> | ||
| 138 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 1 ? (<div className='difficulty-rating' style={{ backgroundColor: "lime" }}></div>) : (<div className='difficulty-rating'></div>)} | ||
| 139 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 2 ? (<div className='difficulty-rating' style={{ backgroundColor: "green" }}></div>) : (<div className='difficulty-rating'></div>)} | ||
| 140 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 3 ? (<div className='difficulty-rating' style={{ backgroundColor: "yellow" }}></div>) : (<div className='difficulty-rating'></div>)} | ||
| 141 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 4 ? (<div className='difficulty-rating' style={{ backgroundColor: "orange" }}></div>) : (<div className='difficulty-rating'></div>)} | ||
| 142 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].rating === 5 ? (<div className='difficulty-rating' style={{ backgroundColor: "red" }}></div>) : (<div className='difficulty-rating'></div>)} | ||
| 143 | </div> | ||
| 144 | </div> | ||
| 145 | <div id='count'> | ||
| 146 | <span>Completion count</span> | ||
| 147 | <div>{selectedCategory === 1 ? data.summary.routes[selectedRun].completion_count : "N/A"}</div> | ||
| 148 | </div> | ||
| 149 | </section> | ||
| 150 | |||
| 151 | <section id='section5' className='summary1'> | ||
| 152 | <div id='description'> | ||
| 153 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].showcase !== "" ? | ||
| 154 | <iframe title='Showcase video' src={"https://www.youtube.com/embed/" + _get_youtube_id(data.summary.routes[selectedRun].showcase)}> </iframe> | ||
| 155 | : ""} | ||
| 156 | <h3>Route description</h3> | ||
| 157 | <span id='description-text'> | ||
| 158 | <ReactMarkdown> | ||
| 159 | {data.summary.routes.sort((a, b) => a.category.id - b.category.id)[selectedRun].description} | ||
| 160 | </ReactMarkdown> | ||
| 161 | </span> | ||
| 162 | </div> | ||
| 163 | </section> | ||
| 164 | |||
| 165 | </> | ||
| 166 | ); | ||
| 167 | }; | ||
| 168 | |||
| 169 | export default Summary; | ||