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 b63132b724741b2baef51ab2a676ffc472e7b2a8
parent 8d13ad688d3364e33f152e9749654abb5b25e35a
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Fri, 11 Oct 2024 00:40:12 +0200

feat: overflow on main

Diffstat:
Msrc/frontend/Athletes.jsx | 98+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/frontend/Heats.jsx | 78++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/frontend/Leaderboard.jsx | 166+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/frontend/Settings.jsx | 86+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/frontend/css/App.css | 5-----
Msrc/frontend/css/index.css | 4++++
6 files changed, 213 insertions(+), 224 deletions(-)

diff --git a/src/frontend/Athletes.jsx b/src/frontend/Athletes.jsx @@ -101,57 +101,55 @@ function AthleteForm({session}) { <div className='AthleteForm'> <button disabled={!loading} className='loading'>↺ loading</button> <form method='post' onSubmit={e => addAthlete(e, session)}> - <div className="table-container"> - <table> - <thead> - <tr> - <th>Created at</th> - <th className="right">Start Nr. *</th> - <th>Firstname *</th> - <th>Lastname</th> - <th>Birthday</th> - <th>School</th> - <th>New/delete</th> + <table> + <thead> + <tr> + <th>Created at</th> + <th className="right">Start Nr. *</th> + <th>Firstname *</th> + <th>Lastname</th> + <th>Birthday</th> + <th>School</th> + <th>New/delete</th> + </tr> + </thead> + <tbody> + {athletes.map(a => ( + <tr key={a.id}> + <td data-title='Created at' className='right'>{new Date(a.created_at).toLocaleDateString(locale, dateOptions)}</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 ? new Date(a.birthday).toLocaleDateString(locale, dateOptions) : ''}</td> + <td data-title='School'>{a.school}</td> + <td><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname, session)}>&ndash; del</button></td> </tr> - </thead> - <tbody> - {athletes.map(a => ( - <tr key={a.id}> - <td data-title='Created at' className='right'>{new Date(a.created_at).toLocaleDateString(locale, dateOptions)}</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 ? new Date(a.birthday).toLocaleDateString(locale, dateOptions) : ''}</td> - <td data-title='School'>{a.school}</td> - <td><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname, session)}>&ndash; del</button></td> - </tr> - ))} - <tr className='input'> - <td className='right'><i>* required</i></td> - <td data-title='Start Nr. *' className='right'> - <input type='number' name='nr' /> - </td> - <td data-title='Firstname *'> - <input type='text' name='firstname' /> - </td> - <td data-title='Lastname'> - <input type='text' name='lastname' /> - </td> - <td data-title='Birthday' className='right'> - <input - type='date' - name='birthday' /> - </td> - <td data-title='School'> - <input type='text' name='school' /> - </td> - <td> - <button type='submit'>&#43; new</button> - </td> - </tr> - </tbody> - </table> - </div> + ))} + <tr className='input'> + <td className='right'><i>* required</i></td> + <td data-title='Start Nr. *' className='right'> + <input type='number' name='nr' /> + </td> + <td data-title='Firstname *'> + <input type='text' name='firstname' /> + </td> + <td data-title='Lastname'> + <input type='text' name='lastname' /> + </td> + <td data-title='Birthday' className='right'> + <input + type='date' + name='birthday' /> + </td> + <td data-title='School'> + <input type='text' name='school' /> + </td> + <td> + <button type='submit'>&#43; new</button> + </td> + </tr> + </tbody> + </table> </form> <ExportForm athletes={athletes} /> </div> diff --git a/src/frontend/Heats.jsx b/src/frontend/Heats.jsx @@ -116,47 +116,45 @@ function HeatForm({session}) { <div className='HeatForm'> <button disabled={!loading} className='loading'>↺ loading</button> <form method='post' onSubmit={e => addHeat(e, session)}> - <div className="table-container"> - <table> - <thead> - <tr> - <th>Created at</th> - <th>Name *</th> - <th>Location</th> - <th>Planned start</th> - <th>New/delete</th> + <table> + <thead> + <tr> + <th>Created at</th> + <th>Name *</th> + <th>Location</th> + <th>Planned start</th> + <th>New/delete</th> + </tr> + </thead> + <tbody> + {heats.map(h => ( + <tr key={h.id}> + <td data-title='Created at' className='right'>{new Date(h.created_at).toLocaleDateString(locale, dateOptions)}</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'>{h.planned_start}</td> + <td><button onClick={e => deleteHeat(e, h.id, h.name, session)}>&ndash; del</button></td> </tr> - </thead> - <tbody> - {heats.map(h => ( - <tr key={h.id}> - <td data-title='Created at' className='right'>{new Date(h.created_at).toLocaleDateString(locale, dateOptions)}</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'>{h.planned_start}</td> - <td><button onClick={e => deleteHeat(e, h.id, h.name, session)}>&ndash; del</button></td> - </tr> - ))} - <tr className='input'> - <td className='right'><i>* required</i></td> - <td data-title='Name *'> - <input type='text' name='name' /> - </td> - <td data-title='Location'> - <input type='text' name='location' /> - </td> - <td data-title='Planned start' className='right'> - <input - type='time' - name='planned_start' /> - </td> - <td> - <button type='submit'>&#43; new</button> - </td> - </tr> - </tbody> - </table> - </div> + ))} + <tr className='input'> + <td className='right'><i>* required</i></td> + <td data-title='Name *'> + <input type='text' name='name' /> + </td> + <td data-title='Location'> + <input type='text' name='location' /> + </td> + <td data-title='Planned start' className='right'> + <input + type='time' + name='planned_start' /> + </td> + <td> + <button type='submit'>&#43; new</button> + </td> + </tr> + </tbody> + </table> </form> <ExportForm heats={heats} /> </div> diff --git a/src/frontend/Leaderboard.jsx b/src/frontend/Leaderboard.jsx @@ -212,38 +212,36 @@ function NewHeatForm(leaderboard, rankingComp, selectHeatRef, selectRankRef, ses selectRankRef, session )}> - <div className="table-container"> - <table> - <thead> - <tr> - <th>New heat name *</th> - <th>Location</th> - <th>Planned start</th> - <th>Include top N</th> - <td></td> - </tr> - </thead> - <tbody> - <tr> - <td data-title="New heat name *"> - <input type="text" name="name" /> - </td> - <td data-title="Location"> - <input type="text" name="location" /> - </td> - <td data-title="Planned start"> - <input type="time" name="planned_start" /> - </td> - <td data-title="Include top N"> - <input type="number" name="size" /> - </td> - <td> - <button type="submit">&#43; new</button> - </td> - </tr> - </tbody> - </table> - </div> + <table> + <thead> + <tr> + <th>New heat name *</th> + <th>Location</th> + <th>Planned start</th> + <th>Include top N</th> + <td></td> + </tr> + </thead> + <tbody> + <tr> + <td data-title="New heat name *"> + <input type="text" name="name" /> + </td> + <td data-title="Location"> + <input type="text" name="location" /> + </td> + <td data-title="Planned start"> + <input type="time" name="planned_start" /> + </td> + <td data-title="Include top N"> + <input type="number" name="size" /> + </td> + <td> + <button type="submit">&#43; new</button> + </td> + </tr> + </tbody> + </table> </form> </div> ) @@ -384,62 +382,60 @@ function Leaderboard({session}) { id="rank" /> </header> - <div className="table-container"> - <table className={details ? "leaderboard" : "hide-rank"}> - <thead> - <tr> - <th className={details ? "right" : "hidden"}>Rank</th> - <th className="right">Start Nr.</th> - <th>Name</th> - <th className={details ? "" : "hidden"}>Birthday</th> - <th className={details ? "" : "hidden"}>School</th> + <table className={details ? "leaderboard" : "hide-rank"}> + <thead> + <tr> + <th className={details ? "right" : "hidden"}>Rank</th> + <th className="right">Start Nr.</th> + <th>Name</th> + <th className={details ? "" : "hidden"}>Birthday</th> + <th className={details ? "" : "hidden"}>School</th> + {heatSelection.map((h) => ( + <th className={details ? "right" : "hidden"} key={h.value}> + {h.label} + </th> + ))} + <th className={details ? "right" : "hidden"}>Best</th> + <th className={details ? "right" : "hidden"}>Worst</th> + <th className="right">Total</th> + </tr> + </thead> + <tbody> + {leaderboard.sort(rankByHeat(rankingComp)).map((i) => ( + <tr key={i.id}> + <td className={details ? "right" : "hidden"}></td> + <td data-title="Start Nr." className="right"> + {i.nr} + </td> + <td data-title="Name"> + {i.firstname} {i.lastname} + </td> + <td data-title="Birthday" className={details ? "" : "hidden"}> + {i.birthday ? new Date(i.birthday).toLocaleDateString( + locale, dateOptions) : ""} + </td> + <td data-title="School" className={details ? "" : "hidden"}> + {i.school} + </td> {heatSelection.map((h) => ( - <th className={details ? "right" : "hidden"} key={h.value}> - {h.label} - </th> + // list all scores from the judges seperated with '+' signs, show sum on right side + <td key={h.value} className={details ? "right" : "hidden"} data-title={h.label}> + {formatScores(i, h)} + </td> ))} - <th className={details ? "right" : "hidden"}>Best</th> - <th className={details ? "right" : "hidden"}>Worst</th> - <th className="right">Total</th> + <td className={details ? "right" : "hidden"} data-title="Best"> + {i.bestHeat} + </td> + <td className={details ? "right" : "hidden"} data-title="Worst"> + {i.worstHeat} + </td> + <td className="right total" data-title="Total"> + {i.sum} + </td> </tr> - </thead> - <tbody> - {leaderboard.sort(rankByHeat(rankingComp)).map((i) => ( - <tr key={i.id}> - <td className={details ? "right" : "hidden"}></td> - <td data-title="Start Nr." className="right"> - {i.nr} - </td> - <td data-title="Name"> - {i.firstname} {i.lastname} - </td> - <td data-title="Birthday" className={details ? "" : "hidden"}> - {i.birthday ? new Date(i.birthday).toLocaleDateString( - locale, dateOptions) : ""} - </td> - <td data-title="School" className={details ? "" : "hidden"}> - {i.school} - </td> - {heatSelection.map((h) => ( - // list all scores from the judges seperated with '+' signs, show sum on right side - <td key={h.value} className={details ? "right" : "hidden"} data-title={h.label}> - {formatScores(i, h)} - </td> - ))} - <td className={details ? "right" : "hidden"} data-title="Best"> - {i.bestHeat} - </td> - <td className={details ? "right" : "hidden"} data-title="Worst"> - {i.worstHeat} - </td> - <td className="right total" data-title="Total"> - {i.sum} - </td> - </tr> - ))} - </tbody> - </table> - </div> + ))} + </tbody> + </table> </div> <ExportForm leaderboard={leaderboard} diff --git a/src/frontend/Settings.jsx b/src/frontend/Settings.jsx @@ -92,55 +92,53 @@ function SettingsForm({session}) { <div className='Settings'> <button disabled={!loading} className='loading'>↺ loading</button> <form method='post' onSubmit={e => updateSetting(e, session)}> - <div className="table-container"> - <table> - <thead> - <tr> - <th></th> - <th>Setting *</th> - <th>Value *</th> - <th>New/delete</th> - </tr> - </thead> - <tbody> - {settings.map(s => ( - <tr key={s.name} data-name={s.name}> - <td></td> - <td data-title='Setting'> - {s.name} - </td> - <td data-title='Value'> - {s.value} - </td> - <td> - <button onClick={e => deleteSetting(e, s.name, session)}>&ndash; del</button> - </td> - </tr> - ))} - <tr className='input'> - <td className='right'><i>* required</i></td> - <td data-title='Setting *'> - <input type='text' name='name' /> - </td> - <td data-title='Value *'> - <input type='text' name='value' /> + <table> + <thead> + <tr> + <th></th> + <th>Setting *</th> + <th>Value *</th> + <th>New/delete</th> + </tr> + </thead> + <tbody> + {settings.map(s => ( + <tr key={s.name} data-name={s.name}> + <td></td> + <td data-title='Setting'> + {s.name} </td> - <td> - <button type='submit'>&#43; new</button> + <td data-title='Value'> + {s.value} </td> - </tr> - </tbody> - <tfoot> - <tr> - <td></td> - <td></td> - <td></td> <td> + <button onClick={e => deleteSetting(e, s.name, session)}>&ndash; del</button> </td> </tr> - </tfoot> - </table> - </div> + ))} + <tr className='input'> + <td className='right'><i>* required</i></td> + <td data-title='Setting *'> + <input type='text' name='name' /> + </td> + <td data-title='Value *'> + <input type='text' name='value' /> + </td> + <td> + <button type='submit'>&#43; new</button> + </td> + </tr> + </tbody> + <tfoot> + <tr> + <td></td> + <td></td> + <td></td> + <td> + </td> + </tr> + </tfoot> + </table> </form> </div> ) diff --git a/src/frontend/css/App.css b/src/frontend/css/App.css @@ -125,11 +125,6 @@ footer span button { padding: 0 20px; } -.table-container { - padding-top: 1em; - overflow-x: auto; -} - .Scoring ul { display: flex; flex-direction: row; diff --git a/src/frontend/css/index.css b/src/frontend/css/index.css @@ -8,6 +8,10 @@ font-size: 18px; } +main { + overflow-x: auto; +} + a { color: black; }