myheats

Live heats, scoring and leaderboard for sport events
git clone https://git.in0rdr.ch/myheats.git
Log | Files | Refs | Pull requests | README | LICENSE

commit 0d39d4b89fb2bf98272e67661bab5f7158de7d4c
parent 480312c07e52003fa7aadf82fe26378b27677023
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Mon, 10 Jul 2023 01:17:52 +0200

feat: layout and design

Diffstat:
Msrc/App.css | 65+++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/Athletes.jsx | 6+++---
Msrc/Auth.jsx | 2+-
Msrc/Heats.jsx | 6+++---
Msrc/Startlist.jsx | 6+++---
Msrc/index.css | 27++++++++++++++-------------
6 files changed, 63 insertions(+), 49 deletions(-)

diff --git a/src/App.css b/src/App.css @@ -7,11 +7,14 @@ main { flex: 1; + border-top: 1px solid #e1e1e7; + border-bottom: 1px solid #e1e1e7; + padding: 30px 0; } nav { - padding: 0; - margin: 0 0 20px 0; + background: #f9f9fc; + border-bottom: 1px solid white; } nav ul { @@ -22,8 +25,8 @@ nav ul { } nav li { - list-style-type: none; flex: 1; + list-style-type: none; white-space: nowrap; } @@ -31,37 +34,44 @@ nav li a { text-transform: uppercase; text-align: center; font-size: 0.8em; - border: 5px solid white; - background: #f7f7f7; text-decoration: none; padding: 10px; display: block; } nav a.active { font-weight: bold; - color: white; - background: #353535; + background: white; } table { border-collapse: collapse; + width: 100%; } th, td { - padding: 5px; + padding: 5px 20px; text-align: left; - /* border: 1px solid #e4e4e4; */ } -tbody tr:nth-child(even) { - background-color: #f7f7f7; +th { + font-weight: normal; + font-size: 0.8em; + text-transform: uppercase; + color: #b0b0b6; +} + +tbody tr:nth-child(even):not(.input) { + background-color: #f9f9fc; } footer { - padding: 20px; + padding: 5px; display: flex; flex-wrap: wrap; justify-content: space-between; + align-items: center; + border-top: 1px solid white; + background: #f9f9fc; } footer span { flex: 1; @@ -90,19 +100,12 @@ footer .login button { } .heatInfo { - margin-bottom: 20px; -} -.heatInfo ul { - padding: 5px; + padding: 20px; } .heatInfo li { list-style: none; } -.newHeatForm { - margin-top: 20px; -} - /* increment rank row number */ table.leaderboard tr{ counter-increment: rowNumber; @@ -118,8 +121,15 @@ table.leaderboard td:last-child { font-weight: bold; } +@media(min-width: 1600px) { + main > div { + width: 75%; + margin: 0 auto; + } +} + /* https://css-tricks.com/making-tables-responsive-with-minimal-css */ -@media(max-width: 800px) { +@media(max-width: 1100px) { table thead { left: -9999px; position: absolute; @@ -127,11 +137,14 @@ table.leaderboard td:last-child { } table tr { - border-bottom: 0; display: flex; flex-direction: row; flex-wrap: wrap; - margin-bottom: 20px; + padding: 20px 0; + } + + table tr:not(:last-child) { + border-bottom: 1px solid #e1e1e7; } table td { @@ -139,7 +152,7 @@ table.leaderboard td:last-child { padding-top: 35px; margin-bottom: 25px; position: relative; - width: 45%; + width: 35%; text-align: left !important; } @@ -147,10 +160,10 @@ table.leaderboard td:last-child { content: attr(data-title); position: absolute; top: 3px; - left: 3px; + left: 20px; font-size: 0.8em; text-transform: uppercase; - background: rgb(255, 247, 208); + color: #b0b0b6; } table.leaderboard td:nth-child(-n+6) { diff --git a/src/Athletes.jsx b/src/Athletes.jsx @@ -89,16 +89,16 @@ function AthleteForm({session}) { <tbody> {athletes.map(a => ( <tr key={a.id}> - <td data-title='Created at' className='right'>{new Date(a.created_at).toLocaleString()}</td> + <td data-title='Created at' className='right'>{new Date(a.created_at).toLocaleDateString()}</td> <td data-title='Start Nr.' className='right'>{a.nr}</td> <td data-title='Firstname'>{a.firstname}</td> <td data-title='Lastname'>{a.lastname}</td> <td data-title='Birthday'>{a.birthday}</td> <td data-title='School'>{a.school}</td> - <td><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname)}>&ndash; delete</button></td> + <td><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname)}>&ndash; del</button></td> </tr> ))} - <tr> + <tr className='input'> <td className='right'><i>* required</i></td> <td data-title='Start Nr. *' className='right'> <input type='number' name='nr' defaultValue='00' /> diff --git a/src/Auth.jsx b/src/Auth.jsx @@ -39,7 +39,7 @@ function Auth() { placeholder="Your email" value={email} onChange={(e) => setEmail(e.target.value)} - /> + /><br/> <button>🛸 Send magic link</button> </form> </div> diff --git a/src/Heats.jsx b/src/Heats.jsx @@ -81,14 +81,14 @@ function HeatForm({session}) { <tbody> {heats.map(h => ( <tr key={h.id}> - <td data-title='Created at' className='right'>{new Date(h.created_at).toLocaleString()}</td> + <td data-title='Created at' className='right'>{new Date(h.created_at).toLocaleDateString()}</td> <td data-title='Name'><Link to={generatePath('/startlist/:heatId', {heatId:h.id})}>{h.name}</Link></td> <td data-title='Location'>{h.location}</td> <td data-title='Planned start' className='right'>{h.planned_start}</td> - <td><button onClick={e => deleteHeat(e, h.id, h.name)}>&ndash; delete</button></td> + <td><button onClick={e => deleteHeat(e, h.id, h.name)}>&ndash; del</button></td> </tr> ))} - <tr> + <tr className='input'> <td className='right'><i>* required</i></td> <td data-title='Name'> <input type='text' name='name' defaultValue='Name *' /> diff --git a/src/Startlist.jsx b/src/Startlist.jsx @@ -108,7 +108,7 @@ function StartlistForm({heatId}) { <th>Lastname</th> <th>Birthday</th> <th>School</th> - <th>Add/remove</th> + <th>Add/Delete</th> </tr> </thead> <tbody> @@ -125,10 +125,10 @@ function StartlistForm({heatId}) { i.athlete.firstname, i.athlete.lastname, heatName - )}>&ndash; remove</button></td> + )}>&ndash; del</button></td> </tr> ))} - <tr> + <tr className='input'> <td data-title='Athlete' colSpan={5}> <Select options={athleteOpts} diff --git a/src/index.css b/src/index.css @@ -9,23 +9,24 @@ a { color: black; } +h1, h2, p { + padding: 10px 20px; +} + +button, input { + width: 100%; + padding: 5px 10px; + border-radius: 3px; + box-shadow: 0 1px #b1b0b6; + background: white; + border: 1px solid #f3f2f7; +} + button { - background: none; - border: none; cursor: pointer; - text-align: left; - box-shadow: 0 1px #c7c7c7; - background: white; - border: 1px solid #f7f7f7; - padding: 5px 10px; - width: 100%; text-align: center; } button:disabled { - visibility: hidden; -} - -input { - width: 100%; + display: none; }