myheats / change low width table design to description tables #2 rss

accepted · opened on 2024-10-08 by sam
Help
# add changes to patch request
git format-patch master --stdout | ssh pr.in0rdr.ch pr add 2
# add review to patch request
git format-patch master --stdout | ssh pr.in0rdr.ch pr add --review 2
# remove patchset
ssh pr.in0rdr.ch ps rm ps-x
# checkout all patches
ssh pr.in0rdr.ch pr print 2 | git am -3
# print a diff between the last two patches in a patch request
ssh pr.in0rdr.ch pr diff 2
# accept PR
ssh pr.in0rdr.ch pr accept 2
# close PR
ssh pr.in0rdr.ch pr close 2

Logs

sam created pr with ps-2 on 2024-10-08
in0rdr changed status on 2024-10-10 {"status":"accepted"}

Patchsets

ps-2 by sam on 2024-10-08T22:18:28Z

change low width table design to description tables

index.html
+2 -2
 1diff --git a/index.html b/index.html
 2index 05d71f0..3d94e61 100644
 3--- a/index.html
 4+++ b/index.html
 5@@ -3,7 +3,7 @@
 6   <head>
 7     <meta charset="UTF-8" />
 8     <link rel="icon" type="image/x-icon" href="/favicon.ico" />
 9-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10+    <meta name="viewport" content="width=device-width" />
11     <link rel="apple-touch-icon" href="/logo192.png" />
12     <!--
13       manifest.json provides metadata used when your web app is installed on a
14@@ -13,7 +13,7 @@
15     <title>My Heats</title>
16   </head>
17   <body>
18-    <noscript>You need to enable JavaScript to run this app.</noscript>
19+    <noscript>Why You scared of JavaScript so much, failure.</noscript>
20     <div id="root"></div>
21     <script type="module" src="/src/frontend/main.jsx"></script>
22   </body>
 1diff --git a/src/frontend/App.jsx b/src/frontend/App.jsx
 2index b8f6357..1ef94c4 100644
 3--- a/src/frontend/App.jsx
 4+++ b/src/frontend/App.jsx
 5@@ -65,7 +65,7 @@ function Layout() {
 6   }, [])
 7 
 8   return (
 9-    <Fragment>
10+    <>
11       <nav className={theme}>
12         <ul>
13           <li>
14@@ -123,7 +123,7 @@ function Layout() {
15           }
16         </span>
17       </footer>
18-    </Fragment>
19+    </>
20   )
21 }
22 
  1diff --git a/src/frontend/Leaderboard.jsx b/src/frontend/Leaderboard.jsx
  2index 1e44ddc..b345b12 100644
  3--- a/src/frontend/Leaderboard.jsx
  4+++ b/src/frontend/Leaderboard.jsx
  5@@ -204,46 +204,51 @@ function NewHeatForm(leaderboard, rankingComp, selectHeatRef, selectRankRef, ses
  6       <p>
  7         Create new heat with top N athletes from the sorted leaderboard (<i>* required</i>).
  8       </p>
  9-      <form method='post' onSubmit={e => newHeatFromLeaderboard(
 10-          e,
 11-          leaderboard,
 12-          rankingComp,
 13-          selectHeatRef,
 14-          selectRankRef,
 15-          session,
 16-        )}>
 17-        <table>
 18-          <thead>
 19-            <tr>
 20-              <th>New heat name *</th>
 21-              <th>Location</th>
 22-              <th>Planned start</th>
 23-              <th>Include top N</th>
 24-              <td></td>
 25-            </tr>
 26-          </thead>
 27-          <tbody>
 28-            <tr>
 29-              <td data-title='New heat name *'>
 30-                <input type='text' name='name' />
 31-              </td>
 32-              <td data-title='Location'>
 33-                <input type='text' name='location' />
 34-              </td>
 35-              <td data-title='Planned start'>
 36-                <input
 37-                  type='time'
 38-                  name='planned_start' />
 39-              </td>
 40-              <td data-title='Include top N'>
 41-                <input type='number' name='size' />
 42-              </td>
 43-              <td>
 44-                <button type='submit'>&#43; new</button>
 45-              </td>
 46-            </tr>
 47-          </tbody>
 48-        </table>
 49+      <form
 50+        method="post"
 51+        onSubmit={(e) =>
 52+          newHeatFromLeaderboard(
 53+            e,
 54+            leaderboard,
 55+            rankingComp,
 56+            selectHeatRef,
 57+            selectRankRef,
 58+            session
 59+          )
 60+        }
 61+      >
 62+        <div className="table-container">
 63+          <table>
 64+            <thead>
 65+              <tr>
 66+                <th>New heat name *</th>
 67+                <th>Location</th>
 68+                <th>Planned start</th>
 69+                <th>Include top N</th>
 70+                <td></td>
 71+              </tr>
 72+            </thead>
 73+            <tbody>
 74+              <tr>
 75+                <td data-title="New heat name *">
 76+                  <input type="text" name="name" />
 77+                </td>
 78+                <td data-title="Location">
 79+                  <input type="text" name="location" />
 80+                </td>
 81+                <td data-title="Planned start">
 82+                  <input type="time" name="planned_start" />
 83+                </td>
 84+                <td data-title="Include top N">
 85+                  <input type="number" name="size" />
 86+                </td>
 87+                <td>
 88+                  <button type="submit">&#43; new</button>
 89+                </td>
 90+              </tr>
 91+            </tbody>
 92+          </table>
 93+        </div>
 94       </form>
 95     </div>
 96   )
 97@@ -351,85 +356,130 @@ function Leaderboard({session}) {
 98   }, [heatSelection]);
 99 
100   return (
101-    <div>
102-      <div className='Leaderboard'>
103+    <>
104+      <div className="Leaderboard">
105         <header>
106-          <button disabled={!loading} className='loading' >↺ loading</button>
107-          <button className={`show-details ${details ? 'toggled' : ''}`} onClick={() => showDetails(!details)}>
108-            <div className='thumb'></div>
109-            <span>{details ? 'less' : 'more'}</span>
110+          <button disabled={!loading} className="loading">
111+            ↺ loading
112           </button>
113-          <label htmlFor='heat'>Heats to display</label>
114+          <button
115+            className={`show-details ${details ? "toggled" : ""}`}
116+            onClick={() => showDetails(!details)}
117+          >
118+            <div className="thumb"></div>
119+            <span>{details ? "less" : "more"}</span>
120+          </button>
121+          <label htmlFor="heat">Heats to display</label>
122           <Select
123             closeMenuOnSelect={false}
124             isMulti
125             options={heatOpts}
126-            onChange={h => setHeatSelection(h)}
127+            onChange={(h) => setHeatSelection(h)}
128             ref={selectHeatRef}
129-            id='heat' />
130-           <label htmlFor='rank' className={details ? '' : 'hidden'}>Rank by</label>
131-           <Select
132+            id="heat"
133+          />
134+          <label htmlFor="rank" className={details ? "" : "hidden"}>
135+            Rank by
136+          </label>
137+          <Select
138             closeMenuOnSelect={false}
139             isMulti
140             options={rankOpts}
141             defaultValue={rankOpts[0].options[3]}
142-            onChange={h => setRankingComp(h)}
143+            onChange={(h) => setRankingComp(h)}
144             ref={selectRankRef}
145-            className={details ? '' : 'hidden'}
146-            id='rank' />
147+            className={details ? "" : "hidden"}
148+            id="rank"
149+          />
150         </header>
151-        <table className={details ? 'leaderboard' : 'hide-rank'}>
152-          <thead>
153-            <tr>
154-              <th className={details ? 'right' : 'hidden'}>Rank</th>
155-              <th className='right'>Start Nr.</th>
156-              <th>Name</th>
157-              <th className={details ? '' : 'hidden'}>Birthday</th>
158-              <th className={details ? '' : 'hidden'}>School</th>
159-              {heatSelection.map(h => (
160-                <th className={details ? 'right' : 'hidden'} key={h.value}>{h.label}</th>
161+        <div className="table-container">
162+          <table className={details ? "leaderboard" : "hide-rank"}>
163+            <thead>
164+              <tr>
165+                <th className={details ? "right" : "hidden"}>Rank</th>
166+                <th className="right">Start Nr.</th>
167+                <th>Name</th>
168+                <th className={details ? "" : "hidden"}>Birthday</th>
169+                <th className={details ? "" : "hidden"}>School</th>
170+                {heatSelection.map((h) => (
171+                  <th className={details ? "right" : "hidden"} key={h.value}>
172+                    {h.label}
173+                  </th>
174+                ))}
175+                <th className={details ? "right" : "hidden"}>Best</th>
176+                <th className={details ? "right" : "hidden"}>Worst</th>
177+                <th className="right">Total</th>
178+              </tr>
179+            </thead>
180+            <tbody>
181+              {leaderboard.sort(rankByHeat(rankingComp)).map((i) => (
182+                <tr key={i.id}>
183+                  <td className={details ? "right" : "hidden"}></td>
184+                  <td data-title="Start Nr." className="right">
185+                    {i.nr}
186+                  </td>
187+                  <td data-title="Name">
188+                    {i.firstname} {i.lastname}
189+                  </td>
190+                  <td data-title="Birthday" className={details ? "" : "hidden"}>
191+                    {i.birthday
192+                      ? new Date(i.birthday).toLocaleDateString(
193+                          locale,
194+                          dateOptions
195+                        )
196+                      : ""}
197+                  </td>
198+                  <td data-title="School" className={details ? "" : "hidden"}>
199+                    {i.school}
200+                  </td>
201+                  {heatSelection.map((h) => (
202+                    // list all scores from the judges seperated with '+' signs, show sum on right side
203+                    <td
204+                      key={h.value}
205+                      className={details ? "right" : "hidden"}
206+                      data-title={h.label}
207+                    >
208+                      {formatScores(i, h)}
209+                    </td>
210+                  ))}
211+                  <td
212+                    className={details ? "right" : "hidden"}
213+                    data-title="Best"
214+                  >
215+                    {i.bestHeat}
216+                  </td>
217+                  <td
218+                    className={details ? "right" : "hidden"}
219+                    data-title="Worst"
220+                  >
221+                    {i.worstHeat}
222+                  </td>
223+                  <td className="right total" data-title="Total">
224+                    {i.sum}
225+                  </td>
226+                </tr>
227               ))}
228-              <th className={details ? 'right' : 'hidden'}>Best</th>
229-              <th className={details ? 'right' : 'hidden'}>Worst</th>
230-              <th className='right'>Total</th>
231-            </tr>
232-          </thead>
233-          <tbody>
234-          {leaderboard.sort(rankByHeat(rankingComp)).map(i => (
235-            <tr key={i.id}>
236-              <td className={details ? 'right' : 'hidden'}></td>
237-              <td data-title='Start Nr.' className='right'>{i.nr}</td>
238-              <td data-title='Name'>{i.firstname} {i.lastname}</td>
239-              <td data-title='Birthday' className={details ? '' : 'hidden'}>
240-                {i.birthday ? new Date(i.birthday).toLocaleDateString(locale, dateOptions) : ''}
241-              </td>
242-              <td data-title='School' className={details ? '' : 'hidden'}>{i.school}</td>
243-              {heatSelection.map(h => (
244-                <Fragment key={h.value}>
245-                  {/* list all scores from the judges seperated with '+' signs, show sum on right side */}
246-                  <td className={details ? 'right' : 'hidden'} data-title={h.label}>{formatScores(i, h)}</td>
247-                </Fragment>
248-              ))}
249-              <td className={details ? 'right' : 'hidden'} data-title='Best'>{i.bestHeat}</td>
250-              <td className={details ? 'right' : 'hidden'} data-title='Worst'>{i.worstHeat}</td>
251-              <td className='right total' data-title='Total'>{i.sum}</td>
252-            </tr>
253-          ))}
254-          </tbody>
255-        </table>
256+            </tbody>
257+          </table>
258+        </div>
259       </div>
260       <ExportForm
261         leaderboard={leaderboard}
262         heatSelection={heatSelection}
263-        rankingComp={rankingComp} />
264-      {session.auth ? <NewHeatForm
265-        leaderboard={leaderboard}
266         rankingComp={rankingComp}
267-        selectHeatRef={selectHeatRef}
268-        selectRankRef={selectRankRef}
269-        session={session}
270-      /> : ''}
271-    </div>
272+      />
273+      {session.auth ? (
274+        <NewHeatForm
275+          leaderboard={leaderboard}
276+          rankingComp={rankingComp}
277+          selectHeatRef={selectHeatRef}
278+          selectRankRef={selectRankRef}
279+          session={session}
280+        />
281+      ) : (
282+        ""
283+      )}
284+    </>
285   )
286 }
287 
  1diff --git a/src/frontend/css/App.css b/src/frontend/css/App.css
  2index ba26e36..ad1fc99 100644
  3--- a/src/frontend/css/App.css
  4+++ b/src/frontend/css/App.css
  5@@ -99,10 +99,11 @@ footer span button {
  6 }
  7 
  8 .loginForm, .exportForm {
  9-  margin: 30px;
 10+  margin: auto;
 11+  padding: 3rem;
 12 }
 13 .loginForm button, .loginForm input, .exportForm button {
 14-  width: 250px;
 15+  width: 100%;
 16   display: block;
 17 }
 18 
 19@@ -125,6 +126,11 @@ footer span button {
 20   padding: 0 20px;
 21 }
 22 
 23+.table-container {
 24+  padding-top: 1rem;
 25+  overflow-x: auto;
 26+}
 27+
 28 .Scoring ul {
 29   display: flex;
 30   flex-direction: row;
 31@@ -214,55 +220,50 @@ td.total {
 32 }
 33 
 34 /* https://css-tricks.com/making-tables-responsive-with-minimal-css */
 35-@media(max-width: 1100px) {
 36+/* Mobile / Small screen styles */
 37+@media (max-width: 768px) {
 38+  table.leaderboard {
 39+    display: block;
 40+  }
 41+
 42   table.leaderboard thead {
 43-    left: -9999px;
 44-    position: absolute;
 45-    visibility: hidden;
 46+    display: none;
 47   }
 48 
 49-  table.leaderboard tr {
 50-    display: flex;
 51-    flex-direction: row;
 52-    flex-wrap: wrap;
 53-    padding: 20px 0;
 54+  table.leaderboard tbody,
 55+  table.leaderboard tr,
 56+  table.leaderboard td {
 57+    display: block;
 58   }
 59 
 60-  table.leaderboard tr:not(:last-child) {
 61-    border-bottom: 1px solid #e1e1e7;
 62+  table.leaderboard tr {
 63+    padding: 2rem;
 64   }
 65 
 66   table.leaderboard td {
 67-    margin: 0 -1px -1px 0;
 68-    padding-top: 35px;
 69-    margin-bottom: 25px;
 70+    display: flex;
 71+    padding: 10px;
 72+    border-bottom: 1px solid #ddd;
 73     position: relative;
 74-    width: 35%;
 75-    text-align: left !important;
 76   }
 77 
 78-  table.leaderboard td:before {
 79-    content: attr(data-title);
 80-    position: absolute;
 81-    top: 3px;
 82-    left: 20px;
 83+  table.leaderboard:not(.hide-rank) tr td:first-child::before {
 84+    content: counter(rowNumber) ". Rank";
 85+  }
 86+
 87+  table.leaderboard td[data-title]:before {
 88+    content: attr(data-title) ": ";
 89+    display: inline-block;
 90+    width: 50%;
 91+    padding-right: 1rem;
 92+    text-align: right;
 93+    align-content: center;
 94     font-size: 0.8em;
 95     text-transform: uppercase;
 96     color: #b0b0b6;
 97   }
 98 
 99-  table.leaderboard td:nth-child(-n+6) {
100-    /* background: rgb(236, 236, 236); */
101-  }
102-
103-  table td button {
104-    position: absolute;
105-    bottom: 0;
106-    height: 50px;
107-    width: 100%;
108-  }
109-
110-  table td:empty {
111-    display: none;
112+  table.leaderboard tr {
113+    border-bottom: 1px solid #ddd;
114   }
115 }
 1diff --git a/src/frontend/css/index.css b/src/frontend/css/index.css
 2index ae40ae5..59eaa31 100644
 3--- a/src/frontend/css/index.css
 4+++ b/src/frontend/css/index.css
 5@@ -1,8 +1,13 @@
 6 * {
 7   padding: 0;
 8   margin: 0;
 9+  box-sizing: border-box;
10   font-family: monospace;
11-  font-size: 18px;
12+  font-size: 1.125rem;
13+}
14+
15+html, body {
16+  height: 100%;
17 }
18 
19 a {
20@@ -21,6 +26,7 @@ button, input {
21   background: white;
22   border: 1px solid #f3f2f7;
23   color: black;
24+  white-space: nowrap;
25 }
26 
27 button {