+draws
=setup: add heats =priority: load heats
This commit is contained in:
parent
50a1d74e65
commit
c6f4800273
16 changed files with 436 additions and 146 deletions
97
frontend/src/routes/draws/+page.svelte
Normal file
97
frontend/src/routes/draws/+page.svelte
Normal file
|
@ -0,0 +1,97 @@
|
|||
<script>
|
||||
import Logo from "$lib/img/topscorer_logo_web.png"
|
||||
|
||||
$: heats = [];
|
||||
|
||||
loadHeats();
|
||||
|
||||
async function loadHeats() {
|
||||
const res = await fetch(`/api/loadheats`);
|
||||
const data = await res.json();
|
||||
for (let i in data) {
|
||||
heats = [...heats, data[i]];
|
||||
console.log(`${i} retval: ${JSON.stringify(data[i])}`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="header">
|
||||
<img class="img" src={Logo} alt="logo">
|
||||
<span class="title" style="color: aliceblue;">Heat Draws</span>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{#each heats as heat}
|
||||
<table>
|
||||
<tr>
|
||||
{#if heat.status === 'running'}
|
||||
<th colspan="2" class="running">
|
||||
{heat.name} ({heat.number}) {heat.category}
|
||||
</th>
|
||||
{:else if heat.status === 'ended'}
|
||||
<th colspan="2" class="ended">
|
||||
{heat.name} ({heat.number}) {heat.category}
|
||||
</th>
|
||||
{:else}
|
||||
<th colspan="2">
|
||||
{heat.name} ({heat.number}) {heat.category}
|
||||
</th>
|
||||
{/if}
|
||||
</tr>
|
||||
|
||||
{#each heat.surfers as surfer }
|
||||
<tr>
|
||||
<td>
|
||||
{surfer.name}
|
||||
</td>
|
||||
<td style="background-color: {surfer.color};">
|
||||
{surfer.color}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
<hr>
|
||||
{/each}
|
||||
|
||||
<style>
|
||||
.header {
|
||||
background-color: black;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header .img {
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.header .title {
|
||||
font-size: 3rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th.running {
|
||||
background-color: green;
|
||||
animation: blinker 2s linear infinite;
|
||||
}
|
||||
|
||||
th.ended {
|
||||
background-color: red;
|
||||
text-decoration: line-through 2px yellow;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -30,6 +30,8 @@
|
|||
let end = false;
|
||||
let start = false;
|
||||
|
||||
loadHeats();
|
||||
|
||||
function Subscribe() {
|
||||
const sse = new EventSource(`/api/sse`);
|
||||
console.log('subscribe');
|
||||
|
@ -71,7 +73,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function startCounter() {
|
||||
async function startHeat() {
|
||||
const res = await fetch(`/api/start`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
|
@ -88,7 +90,7 @@
|
|||
}
|
||||
|
||||
async function loadHeats() {
|
||||
const res = await fetch(`/api/load`);
|
||||
const res = await fetch(`/api/loadheats`);
|
||||
const data = await res.json();
|
||||
for (let i in data) {
|
||||
heats[i] = data[i];
|
||||
|
@ -98,7 +100,9 @@
|
|||
|
||||
function setHeat(id) {
|
||||
console.log(`setHeat: ${id}`);
|
||||
if (id === 99) {
|
||||
if (id === "99") {
|
||||
min = 0;
|
||||
surfers = []
|
||||
return;
|
||||
}
|
||||
min = heats[id].timer;
|
||||
|
@ -170,11 +174,11 @@
|
|||
<svelte:window bind:innerWidth={width} />
|
||||
|
||||
<div class="header">
|
||||
<button class="button" on:click={() => loadHeats()} disabled={start}>Load</button>
|
||||
<!-- <button class="button" on:click={() => loadHeats()} disabled={start}>Load</button> -->
|
||||
<select name="heats" id="heats" bind:value={heat_number} on:change={() => setHeat(heat_number)}>
|
||||
<option value=99>Select</option>
|
||||
<option value="99">Select Heat</option>
|
||||
{#each heats as heat, id}
|
||||
<option value={id}>{heat.name} {heat.category} {heat.number}</option>
|
||||
<option value={id}>{heat.name} {heat.number} {heat.category}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{#if !end}
|
||||
|
@ -182,7 +186,7 @@
|
|||
{:else}
|
||||
<div class="timer" style="color: red">{pad2(min)}:{pad2(sec)}</div>
|
||||
{/if}
|
||||
<button class="button" on:click={() => startCounter()} disabled={start}>Start</button>
|
||||
<button class="button" on:click={() => startHeat()} disabled={start}>Start</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
|
|
@ -1,45 +1,91 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import Logo from "$lib/img/topscorer_logo_web.png"
|
||||
|
||||
$: surfers = 2;
|
||||
|
||||
let surfer_list = new Array();
|
||||
$: heats = [];
|
||||
let surfer_list = [];
|
||||
$: heat = {};
|
||||
|
||||
surfer_list.push({
|
||||
name: '',
|
||||
color: '#000000',
|
||||
score: '',
|
||||
priority: ''
|
||||
});
|
||||
resetHeat();
|
||||
loadHeats();
|
||||
|
||||
surfer_list.push({
|
||||
name: '',
|
||||
color: '#ffffff',
|
||||
score: '',
|
||||
priority: ''
|
||||
});
|
||||
function resetHeat() {
|
||||
surfers = 2;
|
||||
surfer_list = new Array();
|
||||
surfer_list.push({
|
||||
name: '',
|
||||
color: '',
|
||||
score: '',
|
||||
priority: ''
|
||||
});
|
||||
surfer_list.push({
|
||||
name: '',
|
||||
color: '',
|
||||
score: '',
|
||||
priority: ''
|
||||
});
|
||||
|
||||
let heat = {
|
||||
number: '',
|
||||
name: '',
|
||||
category: '',
|
||||
timer: '',
|
||||
surfers: surfer_list
|
||||
heat = {
|
||||
number: '',
|
||||
name: '',
|
||||
category: '',
|
||||
timer: '',
|
||||
surfers: surfer_list
|
||||
}
|
||||
}
|
||||
|
||||
async function loadHeats() {
|
||||
const res = await fetch(`/api/loadheats`);
|
||||
const data = await res.json();
|
||||
for (let i in data) {
|
||||
heats[i] = data[i];
|
||||
console.log(`${i} retval: ${JSON.stringify(data[i])}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteHeat(id) {
|
||||
const res = await fetch(`/api/deleteheat`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(heats[id]),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
console.log(`retval: ${JSON.stringify(res)}`);
|
||||
|
||||
console.log(JSON.stringify(heats[id]));
|
||||
resetHeat();
|
||||
loadHeats();
|
||||
}
|
||||
|
||||
function setHeat(id) {
|
||||
resetHeat();
|
||||
console.log(`setHeat: ${id}`);
|
||||
console.log(heats[id]);
|
||||
heat.number = heats[id].number;
|
||||
heat.name = heats[id].name;
|
||||
heat.category = heats[id].category;
|
||||
heat.timer = heats[id].timer;
|
||||
surfer_list = heats[id].surfers;
|
||||
surfers = surfer_list.length;
|
||||
}
|
||||
|
||||
function addSurfers() {
|
||||
surfers++;
|
||||
surfer_list.push({
|
||||
name: '',
|
||||
color: '#000000',
|
||||
color: '',
|
||||
score: '',
|
||||
priority: ''
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeSurfers() {
|
||||
surfers--;
|
||||
if (surfers < 2) surfers = 2;
|
||||
surfer_list.pop();
|
||||
}
|
||||
|
||||
async function save() {
|
||||
|
@ -73,7 +119,9 @@
|
|||
return;
|
||||
}
|
||||
|
||||
const res = await fetch(`/api/setup`, {
|
||||
heat.surfers = surfer_list;
|
||||
|
||||
const res = await fetch(`/api/saveheat`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(heat),
|
||||
headers: {
|
||||
|
@ -83,6 +131,9 @@
|
|||
console.log(`retval: ${JSON.stringify(res)}`);
|
||||
|
||||
console.log(JSON.stringify(heat));
|
||||
|
||||
resetHeat();
|
||||
loadHeats();
|
||||
}
|
||||
|
||||
function hasDuplicateColors(arr) {
|
||||
|
@ -109,40 +160,69 @@
|
|||
console.log(`element: ${element[elementName]}`);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
resetHeat();
|
||||
loadHeats();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<div class="header">
|
||||
<img class="img" src={Logo} alt="logo">
|
||||
<span class="title" >Heat setup</span>
|
||||
<span class="title" style="color: aliceblue;">Heat setup</span>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="heat">
|
||||
<label class="label" for="name">Name</label>
|
||||
<input bind:value={heat.name} on:change={capitalize(heat, "name")} id="name" type="text">
|
||||
<label class="label" for="number">Number</label>
|
||||
<input bind:value={heat.number} id="number" type="number" min="1" max="20">
|
||||
<label class="label" for="category">Category</label>
|
||||
<input bind:value={heat.category} on:change={capitalize(heat, "category")} id="category" type="text">
|
||||
<label class="label" for="number">Number</label>
|
||||
<input bind:value={heat.number} id="number" on:keydown={(event) => {event.preventDefault()}} type="number" min="1" max="20">
|
||||
<label class="label" for="timer">Timer</label>
|
||||
<input bind:value={heat.timer} id="timer" on:keydown={(event) => {event.preventDefault()}} type="number" min="5" max="60" step="5">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<button class="plus" on:click={() => {addSurfers();}}>+</button>
|
||||
<button class="plus" on:click={() => {removeSurfers();}}>-</button>
|
||||
<span class="surfers">{surfers}</span>
|
||||
|
||||
{#each Array(surfers) as _, surfer}
|
||||
<div class="surfer">
|
||||
<label class="label" for="name{surfer}">Name</label>
|
||||
<input bind:value={surfer_list[surfer].name} on:change={capitalize(heat.surfers[surfer], "name")} id="name{surfer}" type="text">
|
||||
<input bind:value={surfer_list[surfer].name} on:change={capitalize(surfer_list[surfer], "name")} id="name{surfer}" type="text">
|
||||
<label class="label" for="color{surfer}">Color</label>
|
||||
<input bind:value={surfer_list[surfer].color} type="color" id="color{surfer}">
|
||||
<select name="color" id="color{surfer}" bind:value={surfer_list[surfer].color} style="background-color: {surfer_list[surfer].color};">
|
||||
<!-- <option value="red" style="background-color: red;">Select color</option> -->
|
||||
<option value="red" style="background-color: red;">Red</option>
|
||||
<option value="blue" style="background-color: blue;">Blue</option>
|
||||
<option value="green" style="background-color: green;">Green</option>
|
||||
<option value="yellow" style="background-color: yellow;">Yellow</option>
|
||||
<option value="orange" style="background-color: orange;">Orange</option>
|
||||
<option value="violet" style="background-color: violet;">Violet</option>
|
||||
</select>
|
||||
<!-- <input bind:value={surfer_list[surfer].color} type="color" id="color{surfer}"> -->
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
</div>
|
||||
|
||||
<button class="plus" on:click={() => {save();}}>SET</button>
|
||||
<button class="plus" on:click={() => {resetHeat();}}>RESET</button>
|
||||
<hr>
|
||||
{#each heats as h, id}
|
||||
<div class="surfer">
|
||||
<button on:click={() => {setHeat(id);}}>{h.name} {h.number} {h.category}</button>
|
||||
<button class="plus" on:click={() => {deleteHeat(id);}}>X</button>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<!-- <hr> -->
|
||||
|
||||
<!-- <h2>{JSON.stringify(surfer_list)}</h2> -->
|
||||
|
||||
<style>
|
||||
|
||||
|
@ -152,7 +232,6 @@
|
|||
|
||||
.header {
|
||||
background-color: black;
|
||||
color: aliceblue;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
|
@ -170,19 +249,20 @@
|
|||
}
|
||||
|
||||
.label {
|
||||
border: 2px solid #111;
|
||||
background-color: #111;
|
||||
border: 2px solid #555;
|
||||
background-color: gray;
|
||||
border-radius: 8px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.heat {
|
||||
font-size: 1.3rem;
|
||||
margin-top: 2px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 2px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
color: lightcyan;
|
||||
/* color: lightcyan; */
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
@ -199,7 +279,7 @@
|
|||
font-size: 1.3rem;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
color: lightcyan;
|
||||
/* color: lightcyan; */
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
|
@ -217,29 +297,19 @@
|
|||
|
||||
}
|
||||
|
||||
/* select {
|
||||
font-size: 1.2rem;
|
||||
border-radius: 6px;
|
||||
margin-left: 0.1rem;
|
||||
margin-right: 0.1rem;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
option {
|
||||
width: 1rem;
|
||||
padding-left: 25px;
|
||||
background-size: 1.2rem 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0px 0px;
|
||||
transition: border 0.3s
|
||||
} */
|
||||
|
||||
.plus {
|
||||
border-radius: 8px;
|
||||
margin-left: 0.2rem;
|
||||
margin-right: 0.2rem;
|
||||
margin-bottom: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.surfers {
|
||||
border: 1px solid #111;
|
||||
background-color: yellow;
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue