myheats

created pr with 2.1 on 2024-10-08 · by ed0d12e1
cmds
checkout latest patchset:
ssh pr.in0rdr.ch print 2 | git am -3
checkout any patchset in a patch request:
ssh pr.in0rdr.ch print 2.[rev] | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.in0rdr.ch pr add 2

Patchset 2.1 on 2024-10-08 · commit 1b0a391

+2 -2 index.html #
......@@ -3,7 +3,7 @@
33 <head>
44 <meta charset="UTF-8" />
55 <link rel="icon" type="image/x-icon" href="/favicon.ico" />
6- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+ <meta name="viewport" content="width=device-width" />
77 <link rel="apple-touch-icon" href="/logo192.png" />
88 <!--
99 manifest.json provides metadata used when your web app is installed on a
......@@ -13,7 +13,7 @@
1313 <title>My Heats</title>
1414 </head>
1515 <body>
16- <noscript>You need to enable JavaScript to run this app.</noscript>
16+ <noscript>Why You scared of JavaScript so much, failure.</noscript>
1717 <div id="root"></div>
1818 <script type="module" src="/src/frontend/main.jsx"></script>
1919 </body>
+2 -2 src/frontend/App.jsx #
......@@ -65,7 +65,7 @@ function Layout() {
6565 }, [])
6666
6767 return (
68- <Fragment>
68+ <>
6969 <nav className={theme}>
7070 <ul>
7171 <li>
......@@ -123,7 +123,7 @@ function Layout() {
123123 }
124124 </span>
125125 </footer>
126- </Fragment>
126+ </>
127127 )
128128 }
129129
+150 -100 src/frontend/Leaderboard.jsx #
......@@ -204,46 +204,51 @@ function NewHeatForm(leaderboard, rankingComp, selectHeatRef, selectRankRef, ses
204204 <p>
205205 Create new heat with top N athletes from the sorted leaderboard (<i>* required</i>).
206206 </p>
207- <form method='post' onSubmit={e => newHeatFromLeaderboard(
208- e,
209- leaderboard,
210- rankingComp,
211- selectHeatRef,
212- selectRankRef,
213- session,
214- )}>
215- <table>
216- <thead>
217- <tr>
218- <th>New heat name *</th>
219- <th>Location</th>
220- <th>Planned start</th>
221- <th>Include top N</th>
222- <td></td>
223- </tr>
224- </thead>
225- <tbody>
226- <tr>
227- <td data-title='New heat name *'>
228- <input type='text' name='name' />
229- </td>
230- <td data-title='Location'>
231- <input type='text' name='location' />
232- </td>
233- <td data-title='Planned start'>
234- <input
235- type='time'
236- name='planned_start' />
237- </td>
238- <td data-title='Include top N'>
239- <input type='number' name='size' />
240- </td>
241- <td>
242- <button type='submit'>&#43; new</button>
243- </td>
244- </tr>
245- </tbody>
246- </table>
207+ <form
208+ method="post"
209+ onSubmit={(e) =>
210+ newHeatFromLeaderboard(
211+ e,
212+ leaderboard,
213+ rankingComp,
214+ selectHeatRef,
215+ selectRankRef,
216+ session
217+ )
218+ }
219+ >
220+ <div className="table-container">
221+ <table>
222+ <thead>
223+ <tr>
224+ <th>New heat name *</th>
225+ <th>Location</th>
226+ <th>Planned start</th>
227+ <th>Include top N</th>
228+ <td></td>
229+ </tr>
230+ </thead>
231+ <tbody>
232+ <tr>
233+ <td data-title="New heat name *">
234+ <input type="text" name="name" />
235+ </td>
236+ <td data-title="Location">
237+ <input type="text" name="location" />
238+ </td>
239+ <td data-title="Planned start">
240+ <input type="time" name="planned_start" />
241+ </td>
242+ <td data-title="Include top N">
243+ <input type="number" name="size" />
244+ </td>
245+ <td>
246+ <button type="submit">&#43; new</button>
247+ </td>
248+ </tr>
249+ </tbody>
250+ </table>
251+ </div>
247252 </form>
248253 </div>
249254 )
......@@ -351,85 +356,130 @@ function Leaderboard({session}) {
351356 }, [heatSelection]);
352357
353358 return (
354- <div>
355- <div className='Leaderboard'>
359+ <>
360+ <div className="Leaderboard">
356361 <header>
357- <button disabled={!loading} className='loading' >↺ loading</button>
358- <button className={`show-details ${details ? 'toggled' : ''}`} onClick={() => showDetails(!details)}>
359- <div className='thumb'></div>
360- <span>{details ? 'less' : 'more'}</span>
362+ <button disabled={!loading} className="loading">
363+ ↺ loading
361364 </button>
362- <label htmlFor='heat'>Heats to display</label>
365+ <button
366+ className={`show-details ${details ? "toggled" : ""}`}
367+ onClick={() => showDetails(!details)}
368+ >
369+ <div className="thumb"></div>
370+ <span>{details ? "less" : "more"}</span>
371+ </button>
372+ <label htmlFor="heat">Heats to display</label>
363373 <Select
364374 closeMenuOnSelect={false}
365375 isMulti
366376 options={heatOpts}
367- onChange={h => setHeatSelection(h)}
377+ onChange={(h) => setHeatSelection(h)}
368378 ref={selectHeatRef}
369- id='heat' />
370- <label htmlFor='rank' className={details ? '' : 'hidden'}>Rank by</label>
371- <Select
379+ id="heat"
380+ />
381+ <label htmlFor="rank" className={details ? "" : "hidden"}>
382+ Rank by
383+ </label>
384+ <Select
372385 closeMenuOnSelect={false}
373386 isMulti
374387 options={rankOpts}
375388 defaultValue={rankOpts[0].options[3]}
376- onChange={h => setRankingComp(h)}
389+ onChange={(h) => setRankingComp(h)}
377390 ref={selectRankRef}
378- className={details ? '' : 'hidden'}
379- id='rank' />
391+ className={details ? "" : "hidden"}
392+ id="rank"
393+ />
380394 </header>
381- <table className={details ? 'leaderboard' : 'hide-rank'}>
382- <thead>
383- <tr>
384- <th className={details ? 'right' : 'hidden'}>Rank</th>
385- <th className='right'>Start Nr.</th>
386- <th>Name</th>
387- <th className={details ? '' : 'hidden'}>Birthday</th>
388- <th className={details ? '' : 'hidden'}>School</th>
389- {heatSelection.map(h => (
390- <th className={details ? 'right' : 'hidden'} key={h.value}>{h.label}</th>
395+ <div className="table-container">
396+ <table className={details ? "leaderboard" : "hide-rank"}>
397+ <thead>
398+ <tr>
399+ <th className={details ? "right" : "hidden"}>Rank</th>
400+ <th className="right">Start Nr.</th>
401+ <th>Name</th>
402+ <th className={details ? "" : "hidden"}>Birthday</th>
403+ <th className={details ? "" : "hidden"}>School</th>
404+ {heatSelection.map((h) => (
405+ <th className={details ? "right" : "hidden"} key={h.value}>
406+ {h.label}
407+ </th>
408+ ))}
409+ <th className={details ? "right" : "hidden"}>Best</th>
410+ <th className={details ? "right" : "hidden"}>Worst</th>
411+ <th className="right">Total</th>
412+ </tr>
413+ </thead>
414+ <tbody>
415+ {leaderboard.sort(rankByHeat(rankingComp)).map((i) => (
416+ <tr key={i.id}>
417+ <td className={details ? "right" : "hidden"}></td>
418+ <td data-title="Start Nr." className="right">
419+ {i.nr}
420+ </td>
421+ <td data-title="Name">
422+ {i.firstname} {i.lastname}
423+ </td>
424+ <td data-title="Birthday" className={details ? "" : "hidden"}>
425+ {i.birthday
426+ ? new Date(i.birthday).toLocaleDateString(
427+ locale,
428+ dateOptions
429+ )
430+ : ""}
431+ </td>
432+ <td data-title="School" className={details ? "" : "hidden"}>
433+ {i.school}
434+ </td>
435+ {heatSelection.map((h) => (
436+ // list all scores from the judges seperated with '+' signs, show sum on right side
437+ <td
438+ key={h.value}
439+ className={details ? "right" : "hidden"}
440+ data-title={h.label}
441+ >
442+ {formatScores(i, h)}
443+ </td>
444+ ))}
445+ <td
446+ className={details ? "right" : "hidden"}
447+ data-title="Best"
448+ >
449+ {i.bestHeat}
450+ </td>
451+ <td
452+ className={details ? "right" : "hidden"}
453+ data-title="Worst"
454+ >
455+ {i.worstHeat}
456+ </td>
457+ <td className="right total" data-title="Total">
458+ {i.sum}
459+ </td>
460+ </tr>
391461 ))}
392- <th className={details ? 'right' : 'hidden'}>Best</th>
393- <th className={details ? 'right' : 'hidden'}>Worst</th>
394- <th className='right'>Total</th>
395- </tr>
396- </thead>
397- <tbody>
398- {leaderboard.sort(rankByHeat(rankingComp)).map(i => (
399- <tr key={i.id}>
400- <td className={details ? 'right' : 'hidden'}></td>
401- <td data-title='Start Nr.' className='right'>{i.nr}</td>
402- <td data-title='Name'>{i.firstname} {i.lastname}</td>
403- <td data-title='Birthday' className={details ? '' : 'hidden'}>
404- {i.birthday ? new Date(i.birthday).toLocaleDateString(locale, dateOptions) : ''}
405- </td>
406- <td data-title='School' className={details ? '' : 'hidden'}>{i.school}</td>
407- {heatSelection.map(h => (
408- <Fragment key={h.value}>
409- {/* list all scores from the judges seperated with '+' signs, show sum on right side */}
410- <td className={details ? 'right' : 'hidden'} data-title={h.label}>{formatScores(i, h)}</td>
411- </Fragment>
412- ))}
413- <td className={details ? 'right' : 'hidden'} data-title='Best'>{i.bestHeat}</td>
414- <td className={details ? 'right' : 'hidden'} data-title='Worst'>{i.worstHeat}</td>
415- <td className='right total' data-title='Total'>{i.sum}</td>
416- </tr>
417- ))}
418- </tbody>
419- </table>
462+ </tbody>
463+ </table>
464+ </div>
420465 </div>
421466 <ExportForm
422467 leaderboard={leaderboard}
423468 heatSelection={heatSelection}
424- rankingComp={rankingComp} />
425- {session.auth ? <NewHeatForm
426- leaderboard={leaderboard}
427469 rankingComp={rankingComp}
428- selectHeatRef={selectHeatRef}
429- selectRankRef={selectRankRef}
430- session={session}
431- /> : ''}
432- </div>
470+ />
471+ {session.auth ? (
472+ <NewHeatForm
473+ leaderboard={leaderboard}
474+ rankingComp={rankingComp}
475+ selectHeatRef={selectHeatRef}
476+ selectRankRef={selectRankRef}
477+ session={session}
478+ />
479+ ) : (
480+ ""
481+ )}
482+ </>
433483 )
434484 }
435485
+37 -36 src/frontend/css/App.css #
......@@ -99,10 +99,11 @@ footer span button {
9999 }
100100
101101 .loginForm, .exportForm {
102- margin: 30px;
102+ margin: auto;
103+ padding: 3rem;
103104 }
104105 .loginForm button, .loginForm input, .exportForm button {
105- width: 250px;
106+ width: 100%;
106107 display: block;
107108 }
108109
......@@ -125,6 +126,11 @@ footer span button {
125126 padding: 0 20px;
126127 }
127128
129+.table-container {
130+ padding-top: 1rem;
131+ overflow-x: auto;
132+}
133+
128134 .Scoring ul {
129135 display: flex;
130136 flex-direction: row;
......@@ -214,55 +220,50 @@ td.total {
214220 }
215221
216222 /* https://css-tricks.com/making-tables-responsive-with-minimal-css */
217-@media(max-width: 1100px) {
223+/* Mobile / Small screen styles */
224+@media (max-width: 768px) {
225+ table.leaderboard {
226+ display: block;
227+ }
228+
218229 table.leaderboard thead {
219- left: -9999px;
220- position: absolute;
221- visibility: hidden;
230+ display: none;
222231 }
223232
224- table.leaderboard tr {
225- display: flex;
226- flex-direction: row;
227- flex-wrap: wrap;
228- padding: 20px 0;
233+ table.leaderboard tbody,
234+ table.leaderboard tr,
235+ table.leaderboard td {
236+ display: block;
229237 }
230238
231- table.leaderboard tr:not(:last-child) {
232- border-bottom: 1px solid #e1e1e7;
239+ table.leaderboard tr {
240+ padding: 2rem;
233241 }
234242
235243 table.leaderboard td {
236- margin: 0 -1px -1px 0;
237- padding-top: 35px;
238- margin-bottom: 25px;
244+ display: flex;
245+ padding: 10px;
246+ border-bottom: 1px solid #ddd;
239247 position: relative;
240- width: 35%;
241- text-align: left !important;
242248 }
243249
244- table.leaderboard td:before {
245- content: attr(data-title);
246- position: absolute;
247- top: 3px;
248- left: 20px;
250+ table.leaderboard:not(.hide-rank) tr td:first-child::before {
251+ content: counter(rowNumber) ". Rank";
252+ }
253+
254+ table.leaderboard td[data-title]:before {
255+ content: attr(data-title) ": ";
256+ display: inline-block;
257+ width: 50%;
258+ padding-right: 1rem;
259+ text-align: right;
260+ align-content: center;
249261 font-size: 0.8em;
250262 text-transform: uppercase;
251263 color: #b0b0b6;
252264 }
253265
254- table.leaderboard td:nth-child(-n+6) {
255- /* background: rgb(236, 236, 236); */
256- }
257-
258- table td button {
259- position: absolute;
260- bottom: 0;
261- height: 50px;
262- width: 100%;
263- }
264-
265- table td:empty {
266- display: none;
266+ table.leaderboard tr {
267+ border-bottom: 1px solid #ddd;
267268 }
268269 }
+7 -1 src/frontend/css/index.css #
......@@ -1,8 +1,13 @@
11 * {
22 padding: 0;
33 margin: 0;
4+ box-sizing: border-box;
45 font-family: monospace;
5- font-size: 18px;
6+ font-size: 1.125rem;
7+}
8+
9+html, body {
10+ height: 100%;
611 }
712
813 a {
......@@ -21,6 +26,7 @@ button, input {
2126 background: white;
2227 border: 1px solid #f3f2f7;
2328 color: black;
29+ white-space: nowrap;
2430 }
2531
2632 button {
Back to top