Logs
sam
created pr with ps-2
on in0rdr
changed status
on {"status":"accepted"}
Patchsets
Diff ↕
change low width table design to description tables
Berchtold Samuel <samuel.berchtold@gmail.com>
index.html | 4 +- src/frontend/App.jsx | 4 +- src/frontend/Leaderboard.jsx | 250 +++++++++++++++++++++-------------- src/frontend/css/App.css | 73 +++++----- src/frontend/css/index.css | 8 +- 5 files changed, 198 insertions(+), 141 deletions(-)
Patch
1From 1b0a391fd2609391299e9802b835d0e467acb3b4 Mon Sep 17 00:00:00 2001
2From: Berchtold Samuel <samuel.berchtold@gmail.com>
3Date: Wed, 9 Oct 2024 00:06:13 +0200
4Subject: [PATCH] change low width table design to description tables
5
6---
7 index.html | 4 +-
8 src/frontend/App.jsx | 4 +-
9 src/frontend/Leaderboard.jsx | 250 +++++++++++++++++++++--------------
10 src/frontend/css/App.css | 73 +++++-----
11 src/frontend/css/index.css | 8 +-
12 5 files changed, 198 insertions(+), 141 deletions(-)
13
14diff --git a/index.html b/index.html
15index 05d71f0..3d94e61 100644
16--- a/index.html
17+++ b/index.html
18@@ -3,7 +3,7 @@
19 <head>
20 <meta charset="UTF-8" />
21 <link rel="icon" type="image/x-icon" href="/favicon.ico" />
22- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
23+ <meta name="viewport" content="width=device-width" />
24 <link rel="apple-touch-icon" href="/logo192.png" />
25 <!--
26 manifest.json provides metadata used when your web app is installed on a
27@@ -13,7 +13,7 @@
28 <title>My Heats</title>
29 </head>
30 <body>
31- <noscript>You need to enable JavaScript to run this app.</noscript>
32+ <noscript>Why You scared of JavaScript so much, failure.</noscript>
33 <div id="root"></div>
34 <script type="module" src="/src/frontend/main.jsx"></script>
35 </body>
36diff --git a/src/frontend/App.jsx b/src/frontend/App.jsx
37index b8f6357..1ef94c4 100644
38--- a/src/frontend/App.jsx
39+++ b/src/frontend/App.jsx
40@@ -65,7 +65,7 @@ function Layout() {
41 }, [])
42
43 return (
44- <Fragment>
45+ <>
46 <nav className={theme}>
47 <ul>
48 <li>
49@@ -123,7 +123,7 @@ function Layout() {
50 }
51 </span>
52 </footer>
53- </Fragment>
54+ </>
55 )
56 }
57
58diff --git a/src/frontend/Leaderboard.jsx b/src/frontend/Leaderboard.jsx
59index 1e44ddc..b345b12 100644
60--- a/src/frontend/Leaderboard.jsx
61+++ b/src/frontend/Leaderboard.jsx
62@@ -204,46 +204,51 @@ function NewHeatForm(leaderboard, rankingComp, selectHeatRef, selectRankRef, ses
63 <p>
64 Create new heat with top N athletes from the sorted leaderboard (<i>* required</i>).
65 </p>
66- <form method='post' onSubmit={e => newHeatFromLeaderboard(
67- e,
68- leaderboard,
69- rankingComp,
70- selectHeatRef,
71- selectRankRef,
72- session,
73- )}>
74- <table>
75- <thead>
76- <tr>
77- <th>New heat name *</th>
78- <th>Location</th>
79- <th>Planned start</th>
80- <th>Include top N</th>
81- <td></td>
82- </tr>
83- </thead>
84- <tbody>
85- <tr>
86- <td data-title='New heat name *'>
87- <input type='text' name='name' />
88- </td>
89- <td data-title='Location'>
90- <input type='text' name='location' />
91- </td>
92- <td data-title='Planned start'>
93- <input
94- type='time'
95- name='planned_start' />
96- </td>
97- <td data-title='Include top N'>
98- <input type='number' name='size' />
99- </td>
100- <td>
101- <button type='submit'>+ new</button>
102- </td>
103- </tr>
104- </tbody>
105- </table>
106+ <form
107+ method="post"
108+ onSubmit={(e) =>
109+ newHeatFromLeaderboard(
110+ e,
111+ leaderboard,
112+ rankingComp,
113+ selectHeatRef,
114+ selectRankRef,
115+ session
116+ )
117+ }
118+ >
119+ <div className="table-container">
120+ <table>
121+ <thead>
122+ <tr>
123+ <th>New heat name *</th>
124+ <th>Location</th>
125+ <th>Planned start</th>
126+ <th>Include top N</th>
127+ <td></td>
128+ </tr>
129+ </thead>
130+ <tbody>
131+ <tr>
132+ <td data-title="New heat name *">
133+ <input type="text" name="name" />
134+ </td>
135+ <td data-title="Location">
136+ <input type="text" name="location" />
137+ </td>
138+ <td data-title="Planned start">
139+ <input type="time" name="planned_start" />
140+ </td>
141+ <td data-title="Include top N">
142+ <input type="number" name="size" />
143+ </td>
144+ <td>
145+ <button type="submit">+ new</button>
146+ </td>
147+ </tr>
148+ </tbody>
149+ </table>
150+ </div>
151 </form>
152 </div>
153 )
154@@ -351,85 +356,130 @@ function Leaderboard({session}) {
155 }, [heatSelection]);
156
157 return (
158- <div>
159- <div className='Leaderboard'>
160+ <>
161+ <div className="Leaderboard">
162 <header>
163- <button disabled={!loading} className='loading' >↺ loading</button>
164- <button className={`show-details ${details ? 'toggled' : ''}`} onClick={() => showDetails(!details)}>
165- <div className='thumb'></div>
166- <span>{details ? 'less' : 'more'}</span>
167+ <button disabled={!loading} className="loading">
168+ ↺ loading
169 </button>
170- <label htmlFor='heat'>Heats to display</label>
171+ <button
172+ className={`show-details ${details ? "toggled" : ""}`}
173+ onClick={() => showDetails(!details)}
174+ >
175+ <div className="thumb"></div>
176+ <span>{details ? "less" : "more"}</span>
177+ </button>
178+ <label htmlFor="heat">Heats to display</label>
179 <Select
180 closeMenuOnSelect={false}
181 isMulti
182 options={heatOpts}
183- onChange={h => setHeatSelection(h)}
184+ onChange={(h) => setHeatSelection(h)}
185 ref={selectHeatRef}
186- id='heat' />
187- <label htmlFor='rank' className={details ? '' : 'hidden'}>Rank by</label>
188- <Select
189+ id="heat"
190+ />
191+ <label htmlFor="rank" className={details ? "" : "hidden"}>
192+ Rank by
193+ </label>
194+ <Select
195 closeMenuOnSelect={false}
196 isMulti
197 options={rankOpts}
198 defaultValue={rankOpts[0].options[3]}
199- onChange={h => setRankingComp(h)}
200+ onChange={(h) => setRankingComp(h)}
201 ref={selectRankRef}
202- className={details ? '' : 'hidden'}
203- id='rank' />
204+ className={details ? "" : "hidden"}
205+ id="rank"
206+ />
207 </header>
208- <table className={details ? 'leaderboard' : 'hide-rank'}>
209- <thead>
210- <tr>
211- <th className={details ? 'right' : 'hidden'}>Rank</th>
212- <th className='right'>Start Nr.</th>
213- <th>Name</th>
214- <th className={details ? '' : 'hidden'}>Birthday</th>
215- <th className={details ? '' : 'hidden'}>School</th>
216- {heatSelection.map(h => (
217- <th className={details ? 'right' : 'hidden'} key={h.value}>{h.label}</th>
218+ <div className="table-container">
219+ <table className={details ? "leaderboard" : "hide-rank"}>
220+ <thead>
221+ <tr>
222+ <th className={details ? "right" : "hidden"}>Rank</th>
223+ <th className="right">Start Nr.</th>
224+ <th>Name</th>
225+ <th className={details ? "" : "hidden"}>Birthday</th>
226+ <th className={details ? "" : "hidden"}>School</th>
227+ {heatSelection.map((h) => (
228+ <th className={details ? "right" : "hidden"} key={h.value}>
229+ {h.label}
230+ </th>
231+ ))}
232+ <th className={details ? "right" : "hidden"}>Best</th>
233+ <th className={details ? "right" : "hidden"}>Worst</th>
234+ <th className="right">Total</th>
235+ </tr>
236+ </thead>
237+ <tbody>
238+ {leaderboard.sort(rankByHeat(rankingComp)).map((i) => (
239+ <tr key={i.id}>
240+ <td className={details ? "right" : "hidden"}></td>
241+ <td data-title="Start Nr." className="right">
242+ {i.nr}
243+ </td>
244+ <td data-title="Name">
245+ {i.firstname} {i.lastname}
246+ </td>
247+ <td data-title="Birthday" className={details ? "" : "hidden"}>
248+ {i.birthday
249+ ? new Date(i.birthday).toLocaleDateString(
250+ locale,
251+ dateOptions
252+ )
253+ : ""}
254+ </td>
255+ <td data-title="School" className={details ? "" : "hidden"}>
256+ {i.school}
257+ </td>
258+ {heatSelection.map((h) => (
259+ // list all scores from the judges seperated with '+' signs, show sum on right side
260+ <td
261+ key={h.value}
262+ className={details ? "right" : "hidden"}
263+ data-title={h.label}
264+ >
265+ {formatScores(i, h)}
266+ </td>
267+ ))}
268+ <td
269+ className={details ? "right" : "hidden"}
270+ data-title="Best"
271+ >
272+ {i.bestHeat}
273+ </td>
274+ <td
275+ className={details ? "right" : "hidden"}
276+ data-title="Worst"
277+ >
278+ {i.worstHeat}
279+ </td>
280+ <td className="right total" data-title="Total">
281+ {i.sum}
282+ </td>
283+ </tr>
284 ))}
285- <th className={details ? 'right' : 'hidden'}>Best</th>
286- <th className={details ? 'right' : 'hidden'}>Worst</th>
287- <th className='right'>Total</th>
288- </tr>
289- </thead>
290- <tbody>
291- {leaderboard.sort(rankByHeat(rankingComp)).map(i => (
292- <tr key={i.id}>
293- <td className={details ? 'right' : 'hidden'}></td>
294- <td data-title='Start Nr.' className='right'>{i.nr}</td>
295- <td data-title='Name'>{i.firstname} {i.lastname}</td>
296- <td data-title='Birthday' className={details ? '' : 'hidden'}>
297- {i.birthday ? new Date(i.birthday).toLocaleDateString(locale, dateOptions) : ''}
298- </td>
299- <td data-title='School' className={details ? '' : 'hidden'}>{i.school}</td>
300- {heatSelection.map(h => (
301- <Fragment key={h.value}>
302- {/* list all scores from the judges seperated with '+' signs, show sum on right side */}
303- <td className={details ? 'right' : 'hidden'} data-title={h.label}>{formatScores(i, h)}</td>
304- </Fragment>
305- ))}
306- <td className={details ? 'right' : 'hidden'} data-title='Best'>{i.bestHeat}</td>
307- <td className={details ? 'right' : 'hidden'} data-title='Worst'>{i.worstHeat}</td>
308- <td className='right total' data-title='Total'>{i.sum}</td>
309- </tr>
310- ))}
311- </tbody>
312- </table>
313+ </tbody>
314+ </table>
315+ </div>
316 </div>
317 <ExportForm
318 leaderboard={leaderboard}
319 heatSelection={heatSelection}
320- rankingComp={rankingComp} />
321- {session.auth ? <NewHeatForm
322- leaderboard={leaderboard}
323 rankingComp={rankingComp}
324- selectHeatRef={selectHeatRef}
325- selectRankRef={selectRankRef}
326- session={session}
327- /> : ''}
328- </div>
329+ />
330+ {session.auth ? (
331+ <NewHeatForm
332+ leaderboard={leaderboard}
333+ rankingComp={rankingComp}
334+ selectHeatRef={selectHeatRef}
335+ selectRankRef={selectRankRef}
336+ session={session}
337+ />
338+ ) : (
339+ ""
340+ )}
341+ </>
342 )
343 }
344
345diff --git a/src/frontend/css/App.css b/src/frontend/css/App.css
346index ba26e36..ad1fc99 100644
347--- a/src/frontend/css/App.css
348+++ b/src/frontend/css/App.css
349@@ -99,10 +99,11 @@ footer span button {
350 }
351
352 .loginForm, .exportForm {
353- margin: 30px;
354+ margin: auto;
355+ padding: 3rem;
356 }
357 .loginForm button, .loginForm input, .exportForm button {
358- width: 250px;
359+ width: 100%;
360 display: block;
361 }
362
363@@ -125,6 +126,11 @@ footer span button {
364 padding: 0 20px;
365 }
366
367+.table-container {
368+ padding-top: 1rem;
369+ overflow-x: auto;
370+}
371+
372 .Scoring ul {
373 display: flex;
374 flex-direction: row;
375@@ -214,55 +220,50 @@ td.total {
376 }
377
378 /* https://css-tricks.com/making-tables-responsive-with-minimal-css */
379-@media(max-width: 1100px) {
380+/* Mobile / Small screen styles */
381+@media (max-width: 768px) {
382+ table.leaderboard {
383+ display: block;
384+ }
385+
386 table.leaderboard thead {
387- left: -9999px;
388- position: absolute;
389- visibility: hidden;
390+ display: none;
391 }
392
393- table.leaderboard tr {
394- display: flex;
395- flex-direction: row;
396- flex-wrap: wrap;
397- padding: 20px 0;
398+ table.leaderboard tbody,
399+ table.leaderboard tr,
400+ table.leaderboard td {
401+ display: block;
402 }
403
404- table.leaderboard tr:not(:last-child) {
405- border-bottom: 1px solid #e1e1e7;
406+ table.leaderboard tr {
407+ padding: 2rem;
408 }
409
410 table.leaderboard td {
411- margin: 0 -1px -1px 0;
412- padding-top: 35px;
413- margin-bottom: 25px;
414+ display: flex;
415+ padding: 10px;
416+ border-bottom: 1px solid #ddd;
417 position: relative;
418- width: 35%;
419- text-align: left !important;
420 }
421
422- table.leaderboard td:before {
423- content: attr(data-title);
424- position: absolute;
425- top: 3px;
426- left: 20px;
427+ table.leaderboard:not(.hide-rank) tr td:first-child::before {
428+ content: counter(rowNumber) ". Rank";
429+ }
430+
431+ table.leaderboard td[data-title]:before {
432+ content: attr(data-title) ": ";
433+ display: inline-block;
434+ width: 50%;
435+ padding-right: 1rem;
436+ text-align: right;
437+ align-content: center;
438 font-size: 0.8em;
439 text-transform: uppercase;
440 color: #b0b0b6;
441 }
442
443- table.leaderboard td:nth-child(-n+6) {
444- /* background: rgb(236, 236, 236); */
445- }
446-
447- table td button {
448- position: absolute;
449- bottom: 0;
450- height: 50px;
451- width: 100%;
452- }
453-
454- table td:empty {
455- display: none;
456+ table.leaderboard tr {
457+ border-bottom: 1px solid #ddd;
458 }
459 }
460diff --git a/src/frontend/css/index.css b/src/frontend/css/index.css
461index ae40ae5..59eaa31 100644
462--- a/src/frontend/css/index.css
463+++ b/src/frontend/css/index.css
464@@ -1,8 +1,13 @@
465 * {
466 padding: 0;
467 margin: 0;
468+ box-sizing: border-box;
469 font-family: monospace;
470- font-size: 18px;
471+ font-size: 1.125rem;
472+}
473+
474+html, body {
475+ height: 100%;
476 }
477
478 a {
479@@ -21,6 +26,7 @@ button, input {
480 background: white;
481 border: 1px solid #f3f2f7;
482 color: black;
483+ white-space: nowrap;
484 }
485
486 button {
487--
4882.46.0
489
ps-2
by
sam
on change low width table design to description tables
Berchtold Samuel <samuel.berchtold@gmail.com>
index.html | 4 +- src/frontend/App.jsx | 4 +- src/frontend/Leaderboard.jsx | 250 +++++++++++++++++++++-------------- src/frontend/css/App.css | 73 +++++----- src/frontend/css/index.css | 8 +- 5 files changed, 198 insertions(+), 141 deletions(-)
Patch
1From 1b0a391fd2609391299e9802b835d0e467acb3b4 Mon Sep 17 00:00:00 2001
2From: Berchtold Samuel <samuel.berchtold@gmail.com>
3Date: Wed, 9 Oct 2024 00:06:13 +0200
4Subject: [PATCH] change low width table design to description tables
5
6---
7 index.html | 4 +-
8 src/frontend/App.jsx | 4 +-
9 src/frontend/Leaderboard.jsx | 250 +++++++++++++++++++++--------------
10 src/frontend/css/App.css | 73 +++++-----
11 src/frontend/css/index.css | 8 +-
12 5 files changed, 198 insertions(+), 141 deletions(-)
13
14diff --git a/index.html b/index.html
15index 05d71f0..3d94e61 100644
16--- a/index.html
17+++ b/index.html
18@@ -3,7 +3,7 @@
19 <head>
20 <meta charset="UTF-8" />
21 <link rel="icon" type="image/x-icon" href="/favicon.ico" />
22- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
23+ <meta name="viewport" content="width=device-width" />
24 <link rel="apple-touch-icon" href="/logo192.png" />
25 <!--
26 manifest.json provides metadata used when your web app is installed on a
27@@ -13,7 +13,7 @@
28 <title>My Heats</title>
29 </head>
30 <body>
31- <noscript>You need to enable JavaScript to run this app.</noscript>
32+ <noscript>Why You scared of JavaScript so much, failure.</noscript>
33 <div id="root"></div>
34 <script type="module" src="/src/frontend/main.jsx"></script>
35 </body>
36diff --git a/src/frontend/App.jsx b/src/frontend/App.jsx
37index b8f6357..1ef94c4 100644
38--- a/src/frontend/App.jsx
39+++ b/src/frontend/App.jsx
40@@ -65,7 +65,7 @@ function Layout() {
41 }, [])
42
43 return (
44- <Fragment>
45+ <>
46 <nav className={theme}>
47 <ul>
48 <li>
49@@ -123,7 +123,7 @@ function Layout() {
50 }
51 </span>
52 </footer>
53- </Fragment>
54+ </>
55 )
56 }
57
58diff --git a/src/frontend/Leaderboard.jsx b/src/frontend/Leaderboard.jsx
59index 1e44ddc..b345b12 100644
60--- a/src/frontend/Leaderboard.jsx
61+++ b/src/frontend/Leaderboard.jsx
62@@ -204,46 +204,51 @@ function NewHeatForm(leaderboard, rankingComp, selectHeatRef, selectRankRef, ses
63 <p>
64 Create new heat with top N athletes from the sorted leaderboard (<i>* required</i>).
65 </p>
66- <form method='post' onSubmit={e => newHeatFromLeaderboard(
67- e,
68- leaderboard,
69- rankingComp,
70- selectHeatRef,
71- selectRankRef,
72- session,
73- )}>
74- <table>
75- <thead>
76- <tr>
77- <th>New heat name *</th>
78- <th>Location</th>
79- <th>Planned start</th>
80- <th>Include top N</th>
81- <td></td>
82- </tr>
83- </thead>
84- <tbody>
85- <tr>
86- <td data-title='New heat name *'>
87- <input type='text' name='name' />
88- </td>
89- <td data-title='Location'>
90- <input type='text' name='location' />
91- </td>
92- <td data-title='Planned start'>
93- <input
94- type='time'
95- name='planned_start' />
96- </td>
97- <td data-title='Include top N'>
98- <input type='number' name='size' />
99- </td>
100- <td>
101- <button type='submit'>+ new</button>
102- </td>
103- </tr>
104- </tbody>
105- </table>
106+ <form
107+ method="post"
108+ onSubmit={(e) =>
109+ newHeatFromLeaderboard(
110+ e,
111+ leaderboard,
112+ rankingComp,
113+ selectHeatRef,
114+ selectRankRef,
115+ session
116+ )
117+ }
118+ >
119+ <div className="table-container">
120+ <table>
121+ <thead>
122+ <tr>
123+ <th>New heat name *</th>
124+ <th>Location</th>
125+ <th>Planned start</th>
126+ <th>Include top N</th>
127+ <td></td>
128+ </tr>
129+ </thead>
130+ <tbody>
131+ <tr>
132+ <td data-title="New heat name *">
133+ <input type="text" name="name" />
134+ </td>
135+ <td data-title="Location">
136+ <input type="text" name="location" />
137+ </td>
138+ <td data-title="Planned start">
139+ <input type="time" name="planned_start" />
140+ </td>
141+ <td data-title="Include top N">
142+ <input type="number" name="size" />
143+ </td>
144+ <td>
145+ <button type="submit">+ new</button>
146+ </td>
147+ </tr>
148+ </tbody>
149+ </table>
150+ </div>
151 </form>
152 </div>
153 )
154@@ -351,85 +356,130 @@ function Leaderboard({session}) {
155 }, [heatSelection]);
156
157 return (
158- <div>
159- <div className='Leaderboard'>
160+ <>
161+ <div className="Leaderboard">
162 <header>
163- <button disabled={!loading} className='loading' >↺ loading</button>
164- <button className={`show-details ${details ? 'toggled' : ''}`} onClick={() => showDetails(!details)}>
165- <div className='thumb'></div>
166- <span>{details ? 'less' : 'more'}</span>
167+ <button disabled={!loading} className="loading">
168+ ↺ loading
169 </button>
170- <label htmlFor='heat'>Heats to display</label>
171+ <button
172+ className={`show-details ${details ? "toggled" : ""}`}
173+ onClick={() => showDetails(!details)}
174+ >
175+ <div className="thumb"></div>
176+ <span>{details ? "less" : "more"}</span>
177+ </button>
178+ <label htmlFor="heat">Heats to display</label>
179 <Select
180 closeMenuOnSelect={false}
181 isMulti
182 options={heatOpts}
183- onChange={h => setHeatSelection(h)}
184+ onChange={(h) => setHeatSelection(h)}
185 ref={selectHeatRef}
186- id='heat' />
187- <label htmlFor='rank' className={details ? '' : 'hidden'}>Rank by</label>
188- <Select
189+ id="heat"
190+ />
191+ <label htmlFor="rank" className={details ? "" : "hidden"}>
192+ Rank by
193+ </label>
194+ <Select
195 closeMenuOnSelect={false}
196 isMulti
197 options={rankOpts}
198 defaultValue={rankOpts[0].options[3]}
199- onChange={h => setRankingComp(h)}
200+ onChange={(h) => setRankingComp(h)}
201 ref={selectRankRef}
202- className={details ? '' : 'hidden'}
203- id='rank' />
204+ className={details ? "" : "hidden"}
205+ id="rank"
206+ />
207 </header>
208- <table className={details ? 'leaderboard' : 'hide-rank'}>
209- <thead>
210- <tr>
211- <th className={details ? 'right' : 'hidden'}>Rank</th>
212- <th className='right'>Start Nr.</th>
213- <th>Name</th>
214- <th className={details ? '' : 'hidden'}>Birthday</th>
215- <th className={details ? '' : 'hidden'}>School</th>
216- {heatSelection.map(h => (
217- <th className={details ? 'right' : 'hidden'} key={h.value}>{h.label}</th>
218+ <div className="table-container">
219+ <table className={details ? "leaderboard" : "hide-rank"}>
220+ <thead>
221+ <tr>
222+ <th className={details ? "right" : "hidden"}>Rank</th>
223+ <th className="right">Start Nr.</th>
224+ <th>Name</th>
225+ <th className={details ? "" : "hidden"}>Birthday</th>
226+ <th className={details ? "" : "hidden"}>School</th>
227+ {heatSelection.map((h) => (
228+ <th className={details ? "right" : "hidden"} key={h.value}>
229+ {h.label}
230+ </th>
231+ ))}
232+ <th className={details ? "right" : "hidden"}>Best</th>
233+ <th className={details ? "right" : "hidden"}>Worst</th>
234+ <th className="right">Total</th>
235+ </tr>
236+ </thead>
237+ <tbody>
238+ {leaderboard.sort(rankByHeat(rankingComp)).map((i) => (
239+ <tr key={i.id}>
240+ <td className={details ? "right" : "hidden"}></td>
241+ <td data-title="Start Nr." className="right">
242+ {i.nr}
243+ </td>
244+ <td data-title="Name">
245+ {i.firstname} {i.lastname}
246+ </td>
247+ <td data-title="Birthday" className={details ? "" : "hidden"}>
248+ {i.birthday
249+ ? new Date(i.birthday).toLocaleDateString(
250+ locale,
251+ dateOptions
252+ )
253+ : ""}
254+ </td>
255+ <td data-title="School" className={details ? "" : "hidden"}>
256+ {i.school}
257+ </td>
258+ {heatSelection.map((h) => (
259+ // list all scores from the judges seperated with '+' signs, show sum on right side
260+ <td
261+ key={h.value}
262+ className={details ? "right" : "hidden"}
263+ data-title={h.label}
264+ >
265+ {formatScores(i, h)}
266+ </td>
267+ ))}
268+ <td
269+ className={details ? "right" : "hidden"}
270+ data-title="Best"
271+ >
272+ {i.bestHeat}
273+ </td>
274+ <td
275+ className={details ? "right" : "hidden"}
276+ data-title="Worst"
277+ >
278+ {i.worstHeat}
279+ </td>
280+ <td className="right total" data-title="Total">
281+ {i.sum}
282+ </td>
283+ </tr>
284 ))}
285- <th className={details ? 'right' : 'hidden'}>Best</th>
286- <th className={details ? 'right' : 'hidden'}>Worst</th>
287- <th className='right'>Total</th>
288- </tr>
289- </thead>
290- <tbody>
291- {leaderboard.sort(rankByHeat(rankingComp)).map(i => (
292- <tr key={i.id}>
293- <td className={details ? 'right' : 'hidden'}></td>
294- <td data-title='Start Nr.' className='right'>{i.nr}</td>
295- <td data-title='Name'>{i.firstname} {i.lastname}</td>
296- <td data-title='Birthday' className={details ? '' : 'hidden'}>
297- {i.birthday ? new Date(i.birthday).toLocaleDateString(locale, dateOptions) : ''}
298- </td>
299- <td data-title='School' className={details ? '' : 'hidden'}>{i.school}</td>
300- {heatSelection.map(h => (
301- <Fragment key={h.value}>
302- {/* list all scores from the judges seperated with '+' signs, show sum on right side */}
303- <td className={details ? 'right' : 'hidden'} data-title={h.label}>{formatScores(i, h)}</td>
304- </Fragment>
305- ))}
306- <td className={details ? 'right' : 'hidden'} data-title='Best'>{i.bestHeat}</td>
307- <td className={details ? 'right' : 'hidden'} data-title='Worst'>{i.worstHeat}</td>
308- <td className='right total' data-title='Total'>{i.sum}</td>
309- </tr>
310- ))}
311- </tbody>
312- </table>
313+ </tbody>
314+ </table>
315+ </div>
316 </div>
317 <ExportForm
318 leaderboard={leaderboard}
319 heatSelection={heatSelection}
320- rankingComp={rankingComp} />
321- {session.auth ? <NewHeatForm
322- leaderboard={leaderboard}
323 rankingComp={rankingComp}
324- selectHeatRef={selectHeatRef}
325- selectRankRef={selectRankRef}
326- session={session}
327- /> : ''}
328- </div>
329+ />
330+ {session.auth ? (
331+ <NewHeatForm
332+ leaderboard={leaderboard}
333+ rankingComp={rankingComp}
334+ selectHeatRef={selectHeatRef}
335+ selectRankRef={selectRankRef}
336+ session={session}
337+ />
338+ ) : (
339+ ""
340+ )}
341+ </>
342 )
343 }
344
345diff --git a/src/frontend/css/App.css b/src/frontend/css/App.css
346index ba26e36..ad1fc99 100644
347--- a/src/frontend/css/App.css
348+++ b/src/frontend/css/App.css
349@@ -99,10 +99,11 @@ footer span button {
350 }
351
352 .loginForm, .exportForm {
353- margin: 30px;
354+ margin: auto;
355+ padding: 3rem;
356 }
357 .loginForm button, .loginForm input, .exportForm button {
358- width: 250px;
359+ width: 100%;
360 display: block;
361 }
362
363@@ -125,6 +126,11 @@ footer span button {
364 padding: 0 20px;
365 }
366
367+.table-container {
368+ padding-top: 1rem;
369+ overflow-x: auto;
370+}
371+
372 .Scoring ul {
373 display: flex;
374 flex-direction: row;
375@@ -214,55 +220,50 @@ td.total {
376 }
377
378 /* https://css-tricks.com/making-tables-responsive-with-minimal-css */
379-@media(max-width: 1100px) {
380+/* Mobile / Small screen styles */
381+@media (max-width: 768px) {
382+ table.leaderboard {
383+ display: block;
384+ }
385+
386 table.leaderboard thead {
387- left: -9999px;
388- position: absolute;
389- visibility: hidden;
390+ display: none;
391 }
392
393- table.leaderboard tr {
394- display: flex;
395- flex-direction: row;
396- flex-wrap: wrap;
397- padding: 20px 0;
398+ table.leaderboard tbody,
399+ table.leaderboard tr,
400+ table.leaderboard td {
401+ display: block;
402 }
403
404- table.leaderboard tr:not(:last-child) {
405- border-bottom: 1px solid #e1e1e7;
406+ table.leaderboard tr {
407+ padding: 2rem;
408 }
409
410 table.leaderboard td {
411- margin: 0 -1px -1px 0;
412- padding-top: 35px;
413- margin-bottom: 25px;
414+ display: flex;
415+ padding: 10px;
416+ border-bottom: 1px solid #ddd;
417 position: relative;
418- width: 35%;
419- text-align: left !important;
420 }
421
422- table.leaderboard td:before {
423- content: attr(data-title);
424- position: absolute;
425- top: 3px;
426- left: 20px;
427+ table.leaderboard:not(.hide-rank) tr td:first-child::before {
428+ content: counter(rowNumber) ". Rank";
429+ }
430+
431+ table.leaderboard td[data-title]:before {
432+ content: attr(data-title) ": ";
433+ display: inline-block;
434+ width: 50%;
435+ padding-right: 1rem;
436+ text-align: right;
437+ align-content: center;
438 font-size: 0.8em;
439 text-transform: uppercase;
440 color: #b0b0b6;
441 }
442
443- table.leaderboard td:nth-child(-n+6) {
444- /* background: rgb(236, 236, 236); */
445- }
446-
447- table td button {
448- position: absolute;
449- bottom: 0;
450- height: 50px;
451- width: 100%;
452- }
453-
454- table td:empty {
455- display: none;
456+ table.leaderboard tr {
457+ border-bottom: 1px solid #ddd;
458 }
459 }
460diff --git a/src/frontend/css/index.css b/src/frontend/css/index.css
461index ae40ae5..59eaa31 100644
462--- a/src/frontend/css/index.css
463+++ b/src/frontend/css/index.css
464@@ -1,8 +1,13 @@
465 * {
466 padding: 0;
467 margin: 0;
468+ box-sizing: border-box;
469 font-family: monospace;
470- font-size: 18px;
471+ font-size: 1.125rem;
472+}
473+
474+html, body {
475+ height: 100%;
476 }
477
478 a {
479@@ -21,6 +26,7 @@ button, input {
480 background: white;
481 border: 1px solid #f3f2f7;
482 color: black;
483+ white-space: nowrap;
484 }
485
486 button {
487--
4882.46.0
489