Compare commits
11
Commits
d517a0e7fe
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce9cd823f0 | ||
|
|
ef7b4bb2bd | ||
|
|
1002e908fa | ||
|
|
90ffc3a2dd | ||
|
|
368d07a0e4 | ||
|
|
eb87a831ef | ||
|
|
1b662ed4ea | ||
|
|
bd6477e9a4 | ||
|
|
589b8deaae | ||
|
|
5a886c3481 | ||
|
|
aeb2b16634 |
+98
-80
@@ -13,91 +13,102 @@
|
|||||||
<div x-data="{ unitType: $store.state.data.activityTypes[0]?.unit ?? 'km' }" id="content-div" style="display: none;">
|
<div x-data="{ unitType: $store.state.data.activityTypes[0]?.unit ?? 'km' }" id="content-div" style="display: none;">
|
||||||
<h1>Velkommen, <span x-text="$store.state.data.name"></span></h1>
|
<h1>Velkommen, <span x-text="$store.state.data.name"></span></h1>
|
||||||
<div class="outer-vertical-flex">
|
<div class="outer-vertical-flex">
|
||||||
<div class="flex-container">
|
<div class="grid-container">
|
||||||
<div class="vertical-flex">
|
<div class="register-activity-div">
|
||||||
<div class="register-activity-div">
|
<h3>Registrer ny aktivitet:</h3>
|
||||||
<h3>Registrer ny aktivitet:</h3>
|
<form id="activity-form">
|
||||||
<form id="activity-form">
|
<div class="activity-type-div">
|
||||||
<div class="activity-type-div">
|
<label for="activity-type">Type aktivitet: </label>
|
||||||
<label for="activity-type">Type aktivitet: </label>
|
<template x-if="$store.state.data.activityTypes.length > 1">
|
||||||
<template x-if="$store.state.data.activityTypes.length > 1">
|
<select name="activity-type" id="activity-type" x-on:change="unitType = event.target[event.target.selectedIndex].dataset.unit;">
|
||||||
<select name="activity-type" id="activity-type" x-on:change="unitType = event.target[event.target.selectedIndex].dataset.unit;">
|
<template x-for="activityType in $store.state.data.activityTypes" :key="activityType.id">
|
||||||
<template x-for="activityType in $store.state.data.activityTypes" :key="activityType.id">
|
<option x-text="activityType.name" x-bind:value="activityType.id" x-bind:data-unit="activityType.unit"></option>
|
||||||
<option x-text="activityType.name" x-bind:value="activityType.id" x-bind:data-unit="activityType.unit"></option>
|
|
||||||
</template>
|
|
||||||
</select>
|
|
||||||
</template>
|
|
||||||
<template x-if="$store.state.data.activityTypes.length == 1">
|
|
||||||
<span><span x-text="$store.state.data.activityTypes[0].name"></span><input type="hidden" name="activity-type" x-bind:value="$store.state.data.activityTypes[0].id" /></span>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="distance-div">
|
|
||||||
<label for="activity-distance">Avstand: </label>
|
|
||||||
<input id="activity-distance" name="activity-distance" type="number" min="0" step="0.1" />
|
|
||||||
<span x-text="unitType"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="description-div">
|
|
||||||
<label for="activity-description">Beskrivelse:</label>
|
|
||||||
<input type="text" id="activity-description" name="activity-description" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="date-div">
|
|
||||||
<label for="activity-date">Dato:</label>
|
|
||||||
<input type="date" id="activity-date" name="activity-date" />
|
|
||||||
</div>
|
|
||||||
<div class="submit-buttons-container">
|
|
||||||
<button id="submit-activity-button">Registrer aktivitet</button>
|
|
||||||
<button id="submit-activity-template-button">Legg til som standardaktivitet</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="registered-activities-div">
|
|
||||||
<h3>Registrerte aktiviteter:</h3>
|
|
||||||
<p>Til sammen: <span x-text="$store.state.data.activities.reduce((p, a) => p + a.numberOfUnits * a.activityType.conversionFactor, 0).toFixed(1)"></span> km</p>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Dato</th>
|
|
||||||
<th>Beskrivelse</th>
|
|
||||||
<th>Avstand</th>
|
|
||||||
<template x-if="$store.state.data.unitConversionNecessary">
|
|
||||||
<th>Ekvivalent</th>
|
|
||||||
</template>
|
|
||||||
<th>Fjern registrert aktivitet</th>
|
|
||||||
</tr>
|
|
||||||
<template x-for="activity in $store.state.data.activities">
|
|
||||||
<tr>
|
|
||||||
<td x-text="activity.date"></td>
|
|
||||||
<td x-text="activity.description"></td>
|
|
||||||
<td x-text="`${activity.numberOfUnits} ${activity.activityType.unit}`"></td>
|
|
||||||
<template x-if="$store.state.data.unitConversionNecessary">
|
|
||||||
<td x-text="`${activity.numberOfUnits * activity.activityType.conversionFactor} km`"></td>
|
|
||||||
</template>
|
</template>
|
||||||
<td><button x-on:click="$store.state.deleteActivity(activity)">Fjern</button></td>
|
</select>
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</table>
|
<template x-if="$store.state.data.activityTypes.length == 1">
|
||||||
</div>
|
<span><span x-text="$store.state.data.activityTypes[0].name"></span><input type="hidden" name="activity-type" x-bind:value="$store.state.data.activityTypes[0].id" /></span>
|
||||||
</div>
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="distance-div">
|
||||||
|
<label for="activity-distance">Avstand: </label>
|
||||||
|
<input id="activity-distance" name="activity-distance" type="number" min="0" step="0.1" />
|
||||||
|
<span x-text="unitType"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="description-div">
|
||||||
|
<label for="activity-description">Beskrivelse:</label>
|
||||||
|
<input type="text" id="activity-description" name="activity-description" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="date-div">
|
||||||
|
<label for="activity-date">Dato:</label>
|
||||||
|
<input type="date" id="activity-date" name="activity-date" />
|
||||||
|
</div>
|
||||||
|
<div class="submit-buttons-container">
|
||||||
|
<button id="submit-activity-button">Registrer aktivitet</button>
|
||||||
|
<button id="submit-activity-template-button">Legg til som standardaktivitet</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div class="standard-activities-div">
|
<div class="standard-activities-div">
|
||||||
<h3>Standardaktiviteter:</h3>
|
<h3>Standardaktiviteter:</h3>
|
||||||
<template x-for="activityTemplate in $store.state.data.activityTemplates" :key="activityTemplate.id">
|
<template x-for="activityTemplate in $store.state.data.activityTemplates" :key="activityTemplate.id">
|
||||||
<p>
|
<p x-data="{ clicked: false }">
|
||||||
<button x-on:click="$store.state.registerTemplateActivity(activityTemplate)">Registrer</button>
|
<template x-if="clicked">
|
||||||
<span x-text="`${activityTemplate.name}, ${activityTemplate.activityType.name.toLowerCase()}, ${activityTemplate.numberOfUnits} ${activityTemplate.activityType.unit}`"></span>
|
<div class="registered-grid">
|
||||||
<button x-on:click="$store.state.deleteTemplateActivity(activityTemplate)">Fjern</button>
|
<button disabled="true">Tur registrert!</button>
|
||||||
|
<span x-text="`${activityTemplate.name}, ${activityTemplate.activityType.name.toLowerCase()}, ${activityTemplate.numberOfUnits} ${activityTemplate.activityType.unit}`" style="color: green; text-shadow: 1px 1px 2px greenyellow;"></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template x-if="!clicked">
|
||||||
|
<div class="registered-grid">
|
||||||
|
<span>
|
||||||
|
<button x-on:click="$store.state.registerTemplateActivity(activityTemplate); clicked=true; setTimeout(() => {clicked = false;}, 1000)">Registrer</button>
|
||||||
|
</span>
|
||||||
|
<span x-text="`${activityTemplate.name}, ${activityTemplate.activityType.name.toLowerCase()}, ${activityTemplate.numberOfUnits} ${activityTemplate.activityType.unit}`"></span>
|
||||||
|
<span>
|
||||||
|
<button x-on:click="$store.state.deleteTemplateActivity(activityTemplate)">Fjern</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="registered-activities-div">
|
||||||
|
<h3>Registrerte aktiviteter:</h3>
|
||||||
|
<p>Til sammen (sykkelekvivalent): <span x-text="$store.state.data.activities.reduce((p, a) => p + a.numberOfUnits * a.activityType.conversionFactor, 0).toFixed(1)"></span> km</p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Dato</th>
|
||||||
|
<th>Beskrivelse</th>
|
||||||
|
<th>Avstand</th>
|
||||||
|
<template x-if="$store.state.data.unitConversionNecessary">
|
||||||
|
<th class="removable-on-small-screen">Ekvivalent</th>
|
||||||
|
</template>
|
||||||
|
<th>Fjern registrert aktivitet</th>
|
||||||
|
</tr>
|
||||||
|
<template x-for="activity in $store.state.data.activities">
|
||||||
|
<tr>
|
||||||
|
<td x-text="activity.date"></td>
|
||||||
|
<td x-text="activity.description"></td>
|
||||||
|
<td x-text="`${activity.numberOfUnits} ${activity.activityType.unit}`"></td>
|
||||||
|
<template x-if="$store.state.data.unitConversionNecessary">
|
||||||
|
<td class="removable-on-small-screen" x-text="`${activity.numberOfUnits * activity.activityType.conversionFactor} km`"></td>
|
||||||
|
</template>
|
||||||
|
<td class="remove-button-cell"><button x-on:click="$store.state.deleteActivity(activity)">Fjern</button></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="other-users-div">
|
<div class="other-users-div">
|
||||||
<h3>Andre aktive:</h3>
|
<h3>Andre aktive:</h3>
|
||||||
<input type="checkbox" id="hideMeCheckbox" x-model="$store.state.data.isHidden" x-on:click="$store.state.onClickHideCheckbox" /><label id="hideMeLabel" for="hideMeCheckbox">Skjul meg fra den globale listen</label>
|
<input type="checkbox" id="hideMeCheckbox" x-model="$store.state.data.isHidden" x-on:click="$store.state.onClickHideCheckbox" /><label id="hideMeLabel" for="hideMeCheckbox">Skjul meg fra den globale listen</label>
|
||||||
<table>
|
<table id="active-users-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Navn</th><th>Total avstand</th><th>Første aktivitet</th><th>Siste aktivitet</th>
|
<th>Navn</th><th>Total avstand</th><th class="removable-on-small-screen">Første aktivitet</th><th class="removable-on-small-screen">Siste aktivitet</th>
|
||||||
</tr>
|
</tr>
|
||||||
<template x-if="$store.state.data.otherUsers.length == 0">
|
<template x-if="$store.state.data.otherUsers.length == 0">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -105,12 +116,19 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
<template x-if="$store.state.data.otherUsers.length > 0">
|
<template x-if="$store.state.data.otherUsers.length > 0">
|
||||||
<template x-for="otherUser in $store.state.data.otherUsers">
|
<template x-for="otherUser in $store.state.scoreTable">
|
||||||
<tr>
|
<tr>
|
||||||
<td x-text="otherUser.name"></td>
|
<template x-if="otherUser.isHidden">
|
||||||
<td x-text="otherUser.totalKilometers"></td>
|
<td>
|
||||||
<td x-text="otherUser.earliestActivity"></td>
|
<i x-text="otherUser.name"></i>
|
||||||
<td x-text="otherUser.latestActivity"></td>
|
</td>
|
||||||
|
</template>
|
||||||
|
<template x-if="!otherUser.isHidden">
|
||||||
|
<td x-text="otherUser.name"></td>
|
||||||
|
</template>
|
||||||
|
<td x-text="otherUser.totalKilometers.toFixed(1)"></td>
|
||||||
|
<td class="removable-on-small-screen" x-text="otherUser.earliestActivity"></td>
|
||||||
|
<td class="removable-on-small-screen" x-text="otherUser.latestActivity"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@@ -176,7 +194,7 @@
|
|||||||
<th>Beskrivelse</th>
|
<th>Beskrivelse</th>
|
||||||
<th>Avstand</th>
|
<th>Avstand</th>
|
||||||
<template x-if="$store.state.data.unitConversionNecessary">
|
<template x-if="$store.state.data.unitConversionNecessary">
|
||||||
<th>Ekvivalent</th>
|
<th class="removable-on-small-screen">Ekvivalent</th>
|
||||||
</template>
|
</template>
|
||||||
<th>Fjern registrert aktivitet</th>
|
<th>Fjern registrert aktivitet</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -184,11 +202,11 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td x-text="activity.date"></td>
|
<td x-text="activity.date"></td>
|
||||||
<td x-text="activity.description"></td>
|
<td x-text="activity.description"></td>
|
||||||
<td x-text="`${activity.numberOfUnits.toFixed(1)} ${activity.activityType.unit}`"></td>
|
<td x-text="`${activity.numberOfUnits} ${activity.activityType.unit}`"></td>
|
||||||
<template x-if="$store.state.data.unitConversionNecessary">
|
<template x-if="$store.state.data.unitConversionNecessary">
|
||||||
<td x-text="`${(activity.numberOfUnits * activity.activityType.conversionFactor).toFixed(1)} km`"></td>
|
<td class="removable-on-small-screen" x-text="`${(activity.numberOfUnits * activity.activityType.conversionFactor)} km`"></td>
|
||||||
</template>
|
</template>
|
||||||
<td><button x-on:click="$store.state.deleteActivity(activity)">Fjern</button></td>
|
<td class="remove-button-cell"><button x-on:click="$store.state.deleteActivity(activity)">Fjern</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -21,9 +21,18 @@ document.getElementById("submit-activity-template-button")?.addEventListener("cl
|
|||||||
let loadingDiv = document.getElementById("loading-div");
|
let loadingDiv = document.getElementById("loading-div");
|
||||||
let contentDiv = document.getElementById("content-div");
|
let contentDiv = document.getElementById("content-div");
|
||||||
|
|
||||||
|
interface ScoreTableEntry {
|
||||||
|
name: string,
|
||||||
|
isHidden?: boolean,
|
||||||
|
totalKilometers?: number,
|
||||||
|
earliestActivity?: string,
|
||||||
|
latestActivity?: string
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------- ALPINE STATE -----------------------
|
// ---------------- ALPINE STATE -----------------------
|
||||||
interface AlpineState {
|
interface AlpineState {
|
||||||
data: Sykkelaksjon,
|
data: Sykkelaksjon,
|
||||||
|
scoreTable: ScoreTableEntry[],
|
||||||
registerTemplateActivity: (template: ActivityTemplate) => void,
|
registerTemplateActivity: (template: ActivityTemplate) => void,
|
||||||
deleteTemplateActivity: (template: ActivityTemplate) => void,
|
deleteTemplateActivity: (template: ActivityTemplate) => void,
|
||||||
deleteActivity: (activity: Activity) => void,
|
deleteActivity: (activity: Activity) => void,
|
||||||
@@ -52,6 +61,7 @@ let defaultData: Sykkelaksjon = {
|
|||||||
|
|
||||||
let alpineState: AlpineState = {
|
let alpineState: AlpineState = {
|
||||||
data: defaultData,
|
data: defaultData,
|
||||||
|
scoreTable: [],
|
||||||
registerTemplateActivity: registerTemplateActivity,
|
registerTemplateActivity: registerTemplateActivity,
|
||||||
deleteTemplateActivity: deleteTemplateActivity,
|
deleteTemplateActivity: deleteTemplateActivity,
|
||||||
deleteActivity: deleteActivity,
|
deleteActivity: deleteActivity,
|
||||||
@@ -68,6 +78,26 @@ let alpineState: AlpineState = {
|
|||||||
},
|
},
|
||||||
setServerMessage(newMessage: Sykkelaksjon) {
|
setServerMessage(newMessage: Sykkelaksjon) {
|
||||||
this.data = newMessage;
|
this.data = newMessage;
|
||||||
|
|
||||||
|
let scoreTable: ScoreTableEntry[] = [];
|
||||||
|
newMessage.otherUsers.forEach(user => scoreTable.push(user));
|
||||||
|
|
||||||
|
let totalKilometers = newMessage.activities.reduce((sum, activity) => {
|
||||||
|
return sum += activity.numberOfUnits * activity.activityType.conversionFactor;
|
||||||
|
}, 0.0);
|
||||||
|
let dates = newMessage.activities.map(a => a.date).toSorted();
|
||||||
|
let firstDate = dates.at(0);
|
||||||
|
let lastDate = dates.at(dates.length - 1);
|
||||||
|
scoreTable.push({
|
||||||
|
name: newMessage.name,
|
||||||
|
isHidden: newMessage.isHidden,
|
||||||
|
totalKilometers: totalKilometers,
|
||||||
|
earliestActivity: firstDate,
|
||||||
|
latestActivity: lastDate
|
||||||
|
});
|
||||||
|
|
||||||
|
scoreTable.sort((a, b) => {return (b.totalKilometers ?? 0) - (a.totalKilometers ?? 0)});
|
||||||
|
this.scoreTable = scoreTable;
|
||||||
},
|
},
|
||||||
getServerMessage(): Sykkelaksjon {
|
getServerMessage(): Sykkelaksjon {
|
||||||
return this.data;
|
return this.data;
|
||||||
|
|||||||
+70
-27
@@ -13,20 +13,69 @@ body {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-container {
|
.grid-container {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: row;
|
column-gap: 20px;
|
||||||
flex-wrap: wrap;
|
row-gap: 20px;
|
||||||
gap: 20px;
|
|
||||||
justify-content: center;
|
|
||||||
flex: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vertical-flex {
|
@media (min-width: 1000px) {
|
||||||
display: flex;
|
.grid-container {
|
||||||
flex-direction: column;
|
grid-template-columns: auto auto;
|
||||||
flex-wrap: wrap;
|
grid-template-rows: auto auto;
|
||||||
gap: 20px;
|
}
|
||||||
|
|
||||||
|
.standard-activities-div {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1 / -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 999px) {
|
||||||
|
.grid-container {
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: auto auto auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
.register-activity-div input {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registered-activities-div td button {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registered-activities-div td {
|
||||||
|
padding-right:10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 699px) {
|
||||||
|
.register-activity-div input {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.removable-on-small-screen {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registered-activities-div td button {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registered-activities-div td {
|
||||||
|
padding-right:0px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-activity-div {
|
.register-activity-div {
|
||||||
@@ -35,22 +84,25 @@ body {
|
|||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-activity-div input {
|
.registered-grid {
|
||||||
width: 200px;
|
display: grid;
|
||||||
|
grid-template-columns: fit-content(90px) auto fit-content(90px);
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-button-cell {
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 200px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit-buttons-container {
|
.submit-buttons-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
justify-content: space-around;
|
||||||
margin-left: 20px;
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.standard-activities-div {
|
.standard-activities-div {
|
||||||
@@ -71,15 +123,6 @@ table,td,th {
|
|||||||
border: 1px solid lightgray;
|
border: 1px solid lightgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.registered-activities-div td {
|
|
||||||
padding-right:10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.registered-activities-div td button {
|
|
||||||
margin-left:50px;
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.other-users-div {
|
.other-users-div {
|
||||||
border: 1px gray solid;
|
border: 1px gray solid;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|||||||
Reference in New Issue
Block a user