diff options
Diffstat (limited to 'frontend/src/components/pages/summary.js')
| -rw-r--r-- | frontend/src/components/pages/summary.js | 650 |
1 files changed, 0 insertions, 650 deletions
diff --git a/frontend/src/components/pages/summary.js b/frontend/src/components/pages/summary.js deleted file mode 100644 index d276408..0000000 --- a/frontend/src/components/pages/summary.js +++ /dev/null | |||
| @@ -1,650 +0,0 @@ | |||
| 1 | import React, { useEffect } from 'react'; | ||
| 2 | import { useLocation, Link } from "react-router-dom"; | ||
| 3 | import ReactMarkdown from 'react-markdown' | ||
| 4 | |||
| 5 | import "./summary.css"; | ||
| 6 | |||
| 7 | import img4 from "../../imgs/4.png" | ||
| 8 | import img5 from "../../imgs/5.png" | ||
| 9 | import img6 from "../../imgs/6.png" | ||
| 10 | import img12 from "../../imgs/12.png" | ||
| 11 | import img13 from "../../imgs/13.png" | ||
| 12 | import Modview from "./summary_modview.js" | ||
| 13 | |||
| 14 | export default function Summary(prop) { | ||
| 15 | const {token,mod} = prop | ||
| 16 | const fakedata={} //for debug | ||
| 17 | |||
| 18 | const location = useLocation() | ||
| 19 | |||
| 20 | //fetching data | ||
| 21 | const [data, setData] = React.useState(null); | ||
| 22 | React.useEffect(() => { | ||
| 23 | setData(null) | ||
| 24 | setDiscussionThread(null) | ||
| 25 | setCreatePostState(0) | ||
| 26 | setSelectedRun(0) | ||
| 27 | setCatState(1) | ||
| 28 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/summary`) | ||
| 29 | .then(r => r.json()) | ||
| 30 | .then(d => { | ||
| 31 | if(Object.keys(fakedata).length!==0){setData(fakedata)} | ||
| 32 | else{setData(d.data)} | ||
| 33 | if(d.data.summary.routes.length===0){d.data.summary.routes[0]={"category": "","history": {"score_count": 0,},"rating": 0,"description": "","showcase": ""}} | ||
| 34 | }) | ||
| 35 | // eslint-disable-next-line | ||
| 36 | }, [location.pathname]); | ||
| 37 | |||
| 38 | const [pageNumber, setPageNumber] = React.useState(1); | ||
| 39 | const [lbData, setLbData] = React.useState(null); | ||
| 40 | React.useEffect(() => { | ||
| 41 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/leaderboards?page=${pageNumber}`) | ||
| 42 | .then(r => r.json()) | ||
| 43 | .then(d => setLbData(d)) | ||
| 44 | // eslint-disable-next-line | ||
| 45 | }, [pageNumber,location.pathname]); | ||
| 46 | |||
| 47 | const [discussions,setDiscussions] = React.useState(null) | ||
| 48 | function fetchDiscussions() { | ||
| 49 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions`) | ||
| 50 | .then(r=>r.json()) | ||
| 51 | .then(d=>setDiscussions(d.data.discussions)) | ||
| 52 | } | ||
| 53 | |||
| 54 | React.useEffect(()=>{ | ||
| 55 | fetchDiscussions() | ||
| 56 | },[location.pathname]) | ||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | const [discussionThread,setDiscussionThread] = React.useState(null) | ||
| 61 | function openDiscussion(x){ | ||
| 62 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions/${x}`) | ||
| 63 | .then(r=>r.json()) | ||
| 64 | .then(d=>setDiscussionThread(d.data.discussion)) | ||
| 65 | } | ||
| 66 | const [discussionSearch, setDiscussionSearch] = React.useState("") | ||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | const [navState, setNavState] = React.useState(0); // eslint-disable-next-line | ||
| 72 | React.useEffect(() => {NavClick();}, [[],navState]); | ||
| 73 | |||
| 74 | function NavClick() { | ||
| 75 | if(data!==null){ | ||
| 76 | const btn = document.querySelectorAll("#section2 button.nav-button"); | ||
| 77 | btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"}); | ||
| 78 | btn[navState].style.backgroundColor = "#202232"; | ||
| 79 | |||
| 80 | document.querySelectorAll("section").forEach((e,i)=>i>=2?e.style.display="none":"") | ||
| 81 | if(navState === 0){document.querySelectorAll(".summary1").forEach((e) => {e.style.display = "grid"});} | ||
| 82 | if(navState === 1){document.querySelectorAll(".summary2").forEach((e) => {e.style.display = "block"});} | ||
| 83 | if(navState === 2){document.querySelectorAll(".summary3").forEach((e) => {e.style.display = "block"});} | ||
| 84 | }} | ||
| 85 | |||
| 86 | |||
| 87 | const [catState, setCatState] = React.useState(1); // eslint-disable-next-line | ||
| 88 | React.useEffect(() => {CatClick();}, [[],catState]); | ||
| 89 | |||
| 90 | function CatClick() { | ||
| 91 | if(data!==null){ | ||
| 92 | const btn = document.querySelectorAll("#section3 #category span button"); | ||
| 93 | btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"}); | ||
| 94 | btn[catState-1].style.backgroundColor = "#202232"; | ||
| 95 | }} | ||
| 96 | React.useEffect(()=>{ | ||
| 97 | if(data!==null && data.summary.routes.filter(e=>e.category.id===catState).length!==0){ | ||
| 98 | selectRun(0,catState)} // eslint-disable-next-line | ||
| 99 | },[catState,data]) | ||
| 100 | |||
| 101 | |||
| 102 | const [hisState, setHisState] = React.useState(0); // eslint-disable-next-line | ||
| 103 | React.useEffect(() => {HisClick();}, [[],hisState]); | ||
| 104 | |||
| 105 | function HisClick() { | ||
| 106 | if(data!==null){ | ||
| 107 | const btn = document.querySelectorAll("#section3 #history span button"); | ||
| 108 | btn.forEach((e) => {e.style.backgroundColor = "#2b2e46"}); | ||
| 109 | btn[hisState].style.backgroundColor = "#202232"; | ||
| 110 | |||
| 111 | }} | ||
| 112 | |||
| 113 | const [selectedRun,setSelectedRun] = React.useState(0) | ||
| 114 | |||
| 115 | function selectRun(x,y){ | ||
| 116 | let r = document.querySelectorAll("button.record") | ||
| 117 | r.forEach(e=>e.style.backgroundColor="#2b2e46") | ||
| 118 | r[x].style.backgroundColor="#161723" | ||
| 119 | |||
| 120 | |||
| 121 | if(data!==null && data.summary.routes.length!==0 && data.summary.routes.length!==0){ | ||
| 122 | if(y===2){x+=data.summary.routes.filter(e=>e.category.id<2).length} | ||
| 123 | if(y===3){x+=data.summary.routes.filter(e=>e.category.id<3).length} | ||
| 124 | if(y===4){x+=data.summary.routes.filter(e=>e.category.id<4).length} | ||
| 125 | setSelectedRun(x) | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | function graph(state) { | ||
| 130 | // this is such a mess | ||
| 131 | let graph = data.summary.routes.filter(e=>e.category.id===catState) | ||
| 132 | let graph_score = [] | ||
| 133 | data.summary.routes.filter(e=>e.category.id===catState).forEach(e=>graph_score.push(e.history.score_count)) | ||
| 134 | let graph_dates = [] | ||
| 135 | data.summary.routes.filter(e=>e.category.id===catState).forEach(e=>graph_dates.push(e.history.date.split("T")[0])) | ||
| 136 | let graph_max = graph[graph.length-1].history.score_count | ||
| 137 | let graph_numbers = [] | ||
| 138 | for (let i=graph_max;i>=0;i--){ | ||
| 139 | graph_numbers[i]=i | ||
| 140 | } | ||
| 141 | |||
| 142 | switch (state) { | ||
| 143 | case 1: //numbers | ||
| 144 | return graph_numbers | ||
| 145 | .reverse().map(e=>( | ||
| 146 | graph_score.includes(e) || e===0 ? | ||
| 147 | <span>{e}<br/></span> | ||
| 148 | : | ||
| 149 | <span><br/></span> | ||
| 150 | )) | ||
| 151 | case 2: // graph | ||
| 152 | let g = 0 | ||
| 153 | let h = 0 | ||
| 154 | return graph_numbers.map((e,j)=>( | ||
| 155 | <tr id={'graph_row-'+(graph_max-j)} | ||
| 156 | data-graph={ graph_score.includes(graph_max-j) ? g++ : 0} | ||
| 157 | data-graph2={h=0} | ||
| 158 | |||
| 159 | > | ||
| 160 | { | ||
| 161 | graph_score.map((e,i)=>( | ||
| 162 | <> | ||
| 163 | <td className='graph_ver' | ||
| 164 | data-graph={ h++ } | ||
| 165 | style={{outline: | ||
| 166 | g===h-1 ? | ||
| 167 | "1px solid #2b2e46" : g>=h ? "1px dashed white" : "0" }} | ||
| 168 | ></td> | ||
| 169 | |||
| 170 | {g===h && graph_score.includes(graph_max-j) ? | ||
| 171 | <button className='graph-button' | ||
| 172 | onClick={()=>{ | ||
| 173 | selectRun(graph_dates.length-(i-1),catState); | ||
| 174 | }} | ||
| 175 | style={{left: `calc(100% / ${graph_dates.length} * ${h-1})`}} | ||
| 176 | ></button> | ||
| 177 | : ""} | ||
| 178 | |||
| 179 | <td className='graph_hor' id={'graph_table-'+i++} | ||
| 180 | style={{ | ||
| 181 | outline: | ||
| 182 | graph_score.includes(graph_max-j) ? | ||
| 183 | g>=h ? | ||
| 184 | g-1>=h ? "1px dashed #2b2e46" : "1px solid white" : "0" | ||
| 185 | : "0"}} | ||
| 186 | ></td> | ||
| 187 | |||
| 188 | |||
| 189 | |||
| 190 | <td className='graph_hor' id={'graph_table-'+i++} | ||
| 191 | style={{outline: | ||
| 192 | graph_score.includes(graph_max-j) ? | ||
| 193 | g>=h ? | ||
| 194 | g-1>=h ? "1px dashed #2b2e46" : "1px solid white" : "0" | ||
| 195 | : "0"}} | ||
| 196 | ></td> | ||
| 197 | |||
| 198 | </> | ||
| 199 | )) | ||
| 200 | |||
| 201 | } | ||
| 202 | |||
| 203 | </tr> | ||
| 204 | )) | ||
| 205 | |||
| 206 | case 3: // dates | ||
| 207 | return graph_dates | ||
| 208 | .reverse().map(e=>( | ||
| 209 | <span>{e}</span> | ||
| 210 | )) | ||
| 211 | default: | ||
| 212 | break; | ||
| 213 | |||
| 214 | } | ||
| 215 | |||
| 216 | } | ||
| 217 | |||
| 218 | const [vid,setVid] = React.useState("") | ||
| 219 | React.useEffect(()=>{ | ||
| 220 | if(data!==null){ | ||
| 221 | let showcase = data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].showcase | ||
| 222 | showcase.length>6 ? setVid("https://www.youtube.com/embed/"+YouTubeGetID(showcase)) | ||
| 223 | : setVid("") | ||
| 224 | } // eslint-disable-next-line | ||
| 225 | },[[],selectedRun]) | ||
| 226 | |||
| 227 | function YouTubeGetID(url){ | ||
| 228 | url = url.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); | ||
| 229 | return (url[2] !== undefined) ? url[2].split(/[^0-9a-z_]/i)[0] : url[0]; | ||
| 230 | } | ||
| 231 | |||
| 232 | function TimeAgo(date) { | ||
| 233 | // const seconds = Math.floor((new Date() - date) / 1000); | ||
| 234 | |||
| 235 | const seconds = Math.floor(((new Date(new Date() - (date.getTimezoneOffset()*-60000))) - date) / 1000); | ||
| 236 | |||
| 237 | let interval = Math.floor(seconds / 31536000); | ||
| 238 | if (interval === 1) {return interval + ' year ago';} | ||
| 239 | if (interval > 1) {return interval + ' years ago';} | ||
| 240 | |||
| 241 | interval = Math.floor(seconds / 2592000); | ||
| 242 | if (interval === 1) {return interval + ' month ago';} | ||
| 243 | if (interval > 1) {return interval + ' months ago';} | ||
| 244 | |||
| 245 | interval = Math.floor(seconds / 86400); | ||
| 246 | if (interval === 1) {return interval + ' day ago';} | ||
| 247 | if (interval > 1) {return interval + ' days ago';} | ||
| 248 | |||
| 249 | interval = Math.floor(seconds / 3600); | ||
| 250 | if (interval === 1) {return interval + ' hour ago';} | ||
| 251 | if (interval > 1) {return interval + ' hours ago';} | ||
| 252 | |||
| 253 | interval = Math.floor(seconds / 60); | ||
| 254 | if (interval === 1) {return interval + ' minute ago';} | ||
| 255 | if (interval > 1) {return interval + ' minutes ago';} | ||
| 256 | |||
| 257 | if(seconds < 10) return 'just now'; | ||
| 258 | |||
| 259 | return Math.floor(seconds) + ' seconds ago'; | ||
| 260 | }; | ||
| 261 | |||
| 262 | function TicksToTime(ticks) { | ||
| 263 | |||
| 264 | let seconds = Math.floor(ticks/60) | ||
| 265 | let minutes = Math.floor(seconds/60) | ||
| 266 | let hours = Math.floor(minutes/60) | ||
| 267 | |||
| 268 | let milliseconds = Math.floor((ticks%60)*1000/60) | ||
| 269 | seconds = seconds % 60; | ||
| 270 | minutes = minutes % 60; | ||
| 271 | |||
| 272 | 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})`; | ||
| 273 | } | ||
| 274 | |||
| 275 | function PostComment() { | ||
| 276 | |||
| 277 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions/${discussionThread.id}`,{ | ||
| 278 | method:"POST", | ||
| 279 | headers:{authorization:token}, | ||
| 280 | body:JSON.stringify({"comment":document.querySelector("#discussion-send>input").value}) | ||
| 281 | }) | ||
| 282 | .then(r=>r.json()) | ||
| 283 | .then(d=>{ | ||
| 284 | document.querySelector("#discussion-send>input").value="" | ||
| 285 | openDiscussion(discussionThread.id) | ||
| 286 | }) | ||
| 287 | } | ||
| 288 | |||
| 289 | |||
| 290 | const [createPostState,setCreatePostState] = React.useState(0) | ||
| 291 | function CreatePost() { | ||
| 292 | |||
| 293 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions`,{ | ||
| 294 | method:"POST", | ||
| 295 | headers:{authorization:token}, | ||
| 296 | body:JSON.stringify({"title":document.querySelector("#discussion-create-title").value,"content":document.querySelector("#discussion-create-content").value}) | ||
| 297 | }) | ||
| 298 | .then(r=>r.json()) | ||
| 299 | .then(d=>{ | ||
| 300 | setCreatePostState(0) | ||
| 301 | fetchDiscussions() | ||
| 302 | }) | ||
| 303 | } | ||
| 304 | |||
| 305 | function DeletePost(post) { | ||
| 306 | if(window.confirm(`Are you sure you want to remove post: ${post.title}?`)){ | ||
| 307 | console.log("deleted",post.id) | ||
| 308 | fetch(`https://lp.ardapektezol.com/api/v1/maps/${location.pathname.split('/')[2]}/discussions/${post.id}`,{ | ||
| 309 | method:"DELETE", | ||
| 310 | headers:{authorization:token}, | ||
| 311 | }) | ||
| 312 | .then(r=>r.json()) | ||
| 313 | .then(d=>{ | ||
| 314 | fetchDiscussions() | ||
| 315 | }) | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | |||
| 320 | if(data!==null){ | ||
| 321 | console.log(data) | ||
| 322 | |||
| 323 | let current_chapter = data.map.chapter_name | ||
| 324 | let isCoop = false; | ||
| 325 | if (data.map.game_name == "Portal 2 - Cooperative") { | ||
| 326 | isCoop = true | ||
| 327 | } | ||
| 328 | |||
| 329 | current_chapter = data.map.chapter_name.split(" ") | ||
| 330 | // current_chapter = current_chapter.split("-") | ||
| 331 | current_chapter = current_chapter[1] | ||
| 332 | |||
| 333 | return ( | ||
| 334 | <> | ||
| 335 | {token!==null?mod===true?<Modview selectedRun={selectedRun} data={data} token={token}/>:"":""} | ||
| 336 | |||
| 337 | <div id='background-image'> | ||
| 338 | <img src={data.map.image} alt="" /> | ||
| 339 | </div> | ||
| 340 | <main> | ||
| 341 | <section id='section1' className='summary1'> | ||
| 342 | <div> | ||
| 343 | <Link to="/games"><button className='nav-button' style={{borderRadius: "20px 0px 0px 20px"}}><i className='triangle'></i><span>Games list</span></button></Link> | ||
| 344 | <Link to={`/games/${!data.map.is_coop ? "1" : "2"}?chapter=${current_chapter}`}><button className='nav-button' style={{borderRadius: "0px 20px 20px 0px", marginLeft: "2px"}}><i className='triangle'></i><span>{data.map.chapter_name}</span></button></Link> | ||
| 345 | <br/><span><b>{data.map.map_name}</b></span> | ||
| 346 | </div> | ||
| 347 | |||
| 348 | |||
| 349 | </section> | ||
| 350 | |||
| 351 | <section id='section2' className='summary1'> | ||
| 352 | <button className='nav-button' onClick={()=>setNavState(0)}><img src={img4} alt="" /><span>Summary</span></button> | ||
| 353 | <button className='nav-button' onClick={()=>setNavState(1)}><img src={img5} alt="" /><span>Leaderboards</span></button> | ||
| 354 | <button className='nav-button' onClick={()=>setNavState(2)}><img src={img6} alt="" /><span>Discussions</span></button> | ||
| 355 | </section> | ||
| 356 | <section id='section3' className='summary1'> | ||
| 357 | <div id='category' | ||
| 358 | style={data.map.image===""?{backgroundColor:"#202232"}:{}}> | ||
| 359 | <img src={data.map.image} alt="" id='category-image'></img> | ||
| 360 | <p><span className='portal-count'>{data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].history.score_count}</span> | ||
| 361 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].history.score_count === 1 ? ` portal` : ` portals` }</p> | ||
| 362 | <span> | ||
| 363 | <button onClick={()=>setCatState(1)}>CM</button> | ||
| 364 | <button onClick={()=>setCatState(2)}>NoSLA</button> | ||
| 365 | {data.map.is_coop?<button onClick={()=>setCatState(3)}>SLA</button> | ||
| 366 | :<button onClick={()=>setCatState(3)}>Inbounds SLA</button>} | ||
| 367 | <button onClick={()=>setCatState(4)}>Any%</button> | ||
| 368 | </span> | ||
| 369 | |||
| 370 | </div> | ||
| 371 | |||
| 372 | <div id='history'> | ||
| 373 | |||
| 374 | <div style={{display: hisState ? "none" : "block"}}> | ||
| 375 | {data.summary.routes.filter(e=>e.category.id===catState).length===0 ? <h5>There are no records for this map.</h5> : | ||
| 376 | <> | ||
| 377 | <div className='record-top'> | ||
| 378 | <span>Date</span> | ||
| 379 | <span>Record</span> | ||
| 380 | <span>First completion</span> | ||
| 381 | </div> | ||
| 382 | <hr/> | ||
| 383 | <div id='records'> | ||
| 384 | |||
| 385 | {data.summary.routes | ||
| 386 | .sort((a, b) => a.history.score_count - b.history.score_count) | ||
| 387 | .filter(e=>e.category.id===catState) | ||
| 388 | .map((r, index) => ( | ||
| 389 | <button className='record' key={index} onClick={()=>{ | ||
| 390 | selectRun(index,r.category.id); | ||
| 391 | }}> | ||
| 392 | <span>{ new Date(r.history.date).toLocaleDateString( | ||
| 393 | "en-US", { month: 'long', day: 'numeric', year: 'numeric' } | ||
| 394 | )}</span> | ||
| 395 | <span>{r.history.score_count}</span> | ||
| 396 | <span>{r.history.runner_name}</span> | ||
| 397 | </button> | ||
| 398 | ))} | ||
| 399 | </div> | ||
| 400 | </> | ||
| 401 | } | ||
| 402 | </div> | ||
| 403 | |||
| 404 | <div style={{display: hisState ? "block" : "none"}}> | ||
| 405 | {data.summary.routes.filter(e=>e.category.id===catState).length===0 ? <h5>There are no records for this map.</h5> : | ||
| 406 | <div id='graph'> | ||
| 407 | <div>{graph(1)}</div> | ||
| 408 | <div>{graph(2)}</div> | ||
| 409 | <div>{graph(3)}</div> | ||
| 410 | </div> | ||
| 411 | } | ||
| 412 | </div> | ||
| 413 | <span> | ||
| 414 | <button onClick={()=>setHisState(0)}>List</button> | ||
| 415 | <button onClick={()=>setHisState(1)}>Graph</button> | ||
| 416 | </span> | ||
| 417 | </div> | ||
| 418 | |||
| 419 | |||
| 420 | </section> | ||
| 421 | <section id='section4' className='summary1'> | ||
| 422 | <div id='difficulty'> | ||
| 423 | <span>Difficulty</span> | ||
| 424 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 0 ? (<span>N/A</span>):null} | ||
| 425 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 1 ? (<span style={{color:"lime"}}>Very easy</span>):null} | ||
| 426 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 2 ? (<span style={{color:"green"}}>Easy</span>):null} | ||
| 427 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 3 ? (<span style={{color:"yellow"}}>Medium</span>):null} | ||
| 428 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 4 ? (<span style={{color:"orange"}}>Hard</span>):null} | ||
| 429 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].rating === 5 ? (<span style={{color:"red"}}>Very hard</span>):null} | ||
| 430 | <div> | ||
| 431 | {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>)} | ||
| 432 | {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>)} | ||
| 433 | {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>)} | ||
| 434 | {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>)} | ||
| 435 | {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>)} | ||
| 436 | </div> | ||
| 437 | </div> | ||
| 438 | <div id='count'> | ||
| 439 | <span>Completion count</span> | ||
| 440 | <div>{catState===1?data.summary.routes[selectedRun].completion_count:"N/A"}</div> | ||
| 441 | </div> | ||
| 442 | </section> | ||
| 443 | |||
| 444 | <section id='section5' className='summary1'> | ||
| 445 | <div id='description'> | ||
| 446 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].showcase!=="" ? | ||
| 447 | <iframe title='Showcase video' src={vid}> </iframe> | ||
| 448 | : ""} | ||
| 449 | <h3>Route description</h3> | ||
| 450 | <span id='description-text'> | ||
| 451 | <ReactMarkdown> | ||
| 452 | {data.summary.routes.sort((a,b)=>a.category.id - b.category.id)[selectedRun].description} | ||
| 453 | </ReactMarkdown> | ||
| 454 | </span> | ||
| 455 | </div> | ||
| 456 | </section> | ||
| 457 | |||
| 458 | {/* Leaderboards */} | ||
| 459 | |||
| 460 | {lbData===null?"":lbData.success===false?( | ||
| 461 | <section id='section6' className='summary2'> | ||
| 462 | <h1 style={{textAlign:"center"}}>Map is not available for competitive boards.</h1> | ||
| 463 | </section> | ||
| 464 | ):lbData.data.records.length===0?( | ||
| 465 | <section id='section6' className='summary2'> | ||
| 466 | <h1 style={{textAlign:"center"}}>No records found.</h1> | ||
| 467 | </section> | ||
| 468 | ):( | ||
| 469 | <section id='section6' className='summary2'> | ||
| 470 | |||
| 471 | <div id='leaderboard-top' | ||
| 472 | style={lbData.data.map.is_coop?{gridTemplateColumns:"7.5% 40% 7.5% 15% 15% 15%"}:{gridTemplateColumns:"7.5% 30% 10% 20% 17.5% 15%"}} | ||
| 473 | > | ||
| 474 | <span>Place</span> | ||
| 475 | |||
| 476 | {lbData.data.map.is_coop?( | ||
| 477 | <div id='runner'> | ||
| 478 | <span>Host</span> | ||
| 479 | <span>Partner</span> | ||
| 480 | </div> | ||
| 481 | ):( | ||
| 482 | <span>Runner</span> | ||
| 483 | )} | ||
| 484 | |||
| 485 | <span>Portals</span> | ||
| 486 | <span>Time</span> | ||
| 487 | <span>Date</span> | ||
| 488 | <div id='page-number'> | ||
| 489 | <div> | ||
| 490 | |||
| 491 | <button onClick={() => pageNumber === 1 ? null : setPageNumber(prevPageNumber => prevPageNumber - 1)} | ||
| 492 | ><i className='triangle' style={{position:'relative',left:'-5px',}}></i> </button> | ||
| 493 | <span>{lbData.data.pagination.current_page}/{lbData.data.pagination.total_pages}</span> | ||
| 494 | <button onClick={() => pageNumber === lbData.data.pagination.total_pages ? null : setPageNumber(prevPageNumber => prevPageNumber + 1)} | ||
| 495 | ><i className='triangle' style={{position:'relative',left:'5px',transform:'rotate(180deg)'}}></i> </button> | ||
| 496 | </div> | ||
| 497 | </div> | ||
| 498 | </div> | ||
| 499 | <hr/> | ||
| 500 | <div id='leaderboard-records'> | ||
| 501 | {lbData.data.records.map((r, index) => ( | ||
| 502 | <span className='leaderboard-record' key={index} | ||
| 503 | style={lbData.data.map.is_coop?{gridTemplateColumns:"3% 4.5% 40% 4% 3.5% 15% 15% 14.5%"}:{gridTemplateColumns:"3% 4.5% 30% 4% 6% 20% 17% 15%"}} | ||
| 504 | > | ||
| 505 | <span>{r.placement}</span> | ||
| 506 | <span> </span> | ||
| 507 | {lbData.data.map.is_coop?( | ||
| 508 | <div> | ||
| 509 | <span><img src={r.host.avatar_link} alt='' /> {r.host.user_name}</span> | ||
| 510 | <span><img src={r.partner.avatar_link} alt='' /> {r.partner.user_name}</span> | ||
| 511 | </div> | ||
| 512 | ):( | ||
| 513 | <div><span><img src={r.user.avatar_link} alt='' /> {r.user.user_name}</span></div> | ||
| 514 | )} | ||
| 515 | |||
| 516 | <span>{r.score_count}</span> | ||
| 517 | <span> </span> | ||
| 518 | <span>{TicksToTime(r.score_time)}</span> | ||
| 519 | <span className='hover-popup' popup-text={r.record_date.replace("T",' ').split(".")[0]}>{ TimeAgo(new Date(r.record_date.replace("T"," ").replace("Z",""))) }</span> | ||
| 520 | |||
| 521 | {lbData.data.map.is_coop?( | ||
| 522 | <span> | ||
| 523 | <button onClick={()=>{window.alert(`Host demo ID: ${r.host_demo_id} \nParnter demo ID: ${r.partner_demo_id}`)}}><img src={img13} alt="demo_id" /></button> | ||
| 524 | <button onClick={()=>window.location.href=`https://lp.ardapektezol.com/api/v1/demos?uuid=${r.partner_demo_id}`}><img src={img12} alt="download" style={{filter:"hue-rotate(160deg) contrast(60%) saturate(1000%)"}}/></button> | ||
| 525 | <button onClick={()=>window.location.href=`https://lp.ardapektezol.com/api/v1/demos?uuid=${r.host_demo_id}`}><img src={img12} alt="download" style={{filter:"hue-rotate(300deg) contrast(60%) saturate(1000%)"}}/></button> | ||
| 526 | </span> | ||
| 527 | ):( | ||
| 528 | |||
| 529 | <span> | ||
| 530 | <button onClick={()=>{window.alert(`Demo ID: ${r.demo_id}`)}}><img src={img13} alt="demo_id" /></button> | ||
| 531 | <button onClick={()=>window.location.href=`https://lp.ardapektezol.com/api/v1/demos?uuid=${r.demo_id}`}><img src={img12} alt="download" /></button> | ||
| 532 | </span> | ||
| 533 | )} | ||
| 534 | </span> | ||
| 535 | ))} | ||
| 536 | </div> | ||
| 537 | </section> | ||
| 538 | )} | ||
| 539 | |||
| 540 | |||
| 541 | {/* Discussions */} | ||
| 542 | <section id='section7' className='summary3'> | ||
| 543 | |||
| 544 | {discussionThread === null ? ( | ||
| 545 | createPostState === 0 ? ( | ||
| 546 | discussions !== null ? ( | ||
| 547 | // Main screen | ||
| 548 | <> | ||
| 549 | <div id='discussion-search'> | ||
| 550 | <input type="text" value={discussionSearch} placeholder={"Search for posts..."} onChange={()=>setDiscussionSearch(document.querySelector("#discussion-search>input").value)} /> | ||
| 551 | <div><button onClick={()=>setCreatePostState(1)}>New Post</button></div> | ||
| 552 | </div> | ||
| 553 | {discussions.filter(f=>f.title.includes(discussionSearch)).sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at)) | ||
| 554 | .map((e, i) => ( | ||
| 555 | <div id='discussion-post'> | ||
| 556 | |||
| 557 | <button key={e.id} onClick={() => openDiscussion(e.id)}> | ||
| 558 | <span>{e.title}</span> | ||
| 559 | |||
| 560 | {token!==null?e.creator.steam_id===JSON.parse(atob(token.split(".")[1])).sub? | ||
| 561 | <button onClick={()=>DeletePost(e)}>Delete Post</button> | ||
| 562 | :<span></span>:<span></span>} | ||
| 563 | <span><b>{e.creator.user_name}:</b> {e.content}</span> | ||
| 564 | <span>last updated: {TimeAgo(new Date(e.updated_at.replace("T"," ").replace("Z","")))}</span> | ||
| 565 | </button> | ||
| 566 | </div> | ||
| 567 | ))} | ||
| 568 | </> | ||
| 569 | ):( | ||
| 570 | |||
| 571 | // Main screen (no posts) | ||
| 572 | <> | ||
| 573 | <div id='discussion-search'> | ||
| 574 | <input type="text" value={discussionSearch} placeholder={"Search for posts..."} onChange={()=>setDiscussionSearch(document.querySelector("#discussion-search>input").value)} /> | ||
| 575 | <div><button onClick={()=>setCreatePostState(1)}>New Post</button></div> | ||
| 576 | </div> | ||
| 577 | <span style={{textAlign:"center",display:"block"}}>no discussions</span> | ||
| 578 | </> | ||
| 579 | ) | ||
| 580 | ):( | ||
| 581 | // Creating post | ||
| 582 | <div id='discussion-create'> | ||
| 583 | <span>Create post</span> | ||
| 584 | <button onClick={()=>setCreatePostState(0)}>X</button> | ||
| 585 | <div style={{gridColumn:"1 / span 2"}}> | ||
| 586 | <input id='discussion-create-title' placeholder='Title...'></input> | ||
| 587 | <input id='discussion-create-content' placeholder='Enter the comment...' ></input> | ||
| 588 | </div> | ||
| 589 | <div style={{placeItems:"end",gridColumn:"1 / span 2"}}> | ||
| 590 | <button id='discussion-create-button' onClick={()=>CreatePost()}>Post</button> | ||
| 591 | </div> | ||
| 592 | |||
| 593 | </div> | ||
| 594 | |||
| 595 | )):( | ||
| 596 | // Post screen | ||
| 597 | <div id='discussion-thread'> | ||
| 598 | <div> | ||
| 599 | <span>{discussionThread.title}</span> | ||
| 600 | <button onClick={()=>setDiscussionThread(null)}>X</button> | ||
| 601 | </div> | ||
| 602 | |||
| 603 | <div> | ||
| 604 | <img src={discussionThread.creator.avatar_link} alt="" /> | ||
| 605 | <div> | ||
| 606 | <span>{discussionThread.creator.user_name}</span> | ||
| 607 | <span>{TimeAgo(new Date(discussionThread.created_at.replace("T"," ").replace("Z","")))}</span> | ||
| 608 | <span>{discussionThread.content}</span> | ||
| 609 | </div> | ||
| 610 | {discussionThread.comments!==null? | ||
| 611 | discussionThread.comments.sort((a, b) => new Date(a.date) - new Date(b.date)) | ||
| 612 | .map(e=>( | ||
| 613 | <> | ||
| 614 | <img src={e.user.avatar_link} alt="" /> | ||
| 615 | <div> | ||
| 616 | <span>{e.user.user_name}</span> | ||
| 617 | <span>{TimeAgo(new Date(e.date.replace("T"," ").replace("Z","")))}</span> | ||
| 618 | <span>{e.comment}</span> | ||
| 619 | </div> | ||
| 620 | </> | ||
| 621 | |||
| 622 | )):""} | ||
| 623 | |||
| 624 | |||
| 625 | </div> | ||
| 626 | <div id='discussion-send'> | ||
| 627 | <input type="text" placeholder={"Message"} onKeyDown={(e)=>e.key==="Enter"?PostComment():""}/> | ||
| 628 | <div><button onClick={()=>PostComment()}>Send</button></div> | ||
| 629 | </div> | ||
| 630 | |||
| 631 | </div> | ||
| 632 | |||
| 633 | |||
| 634 | )} | ||
| 635 | |||
| 636 | </section> | ||
| 637 | |||
| 638 | </main> | ||
| 639 | </> | ||
| 640 | ) | ||
| 641 | }else{ | ||
| 642 | return ( | ||
| 643 | <main></main> | ||
| 644 | ) | ||
| 645 | } | ||
| 646 | |||
| 647 | |||
| 648 | } | ||
| 649 | |||
| 650 | |||