Compare commits

..
9 Commits
3 changed files with 190 additions and 106 deletions
+39 -28
View File
@@ -13,8 +13,7 @@
<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">
@@ -53,16 +52,40 @@
</div> </div>
</form> </form>
</div> </div>
<div class="standard-activities-div">
<h3>Standardaktiviteter:</h3>
<template x-for="activityTemplate in $store.state.data.activityTemplates" :key="activityTemplate.id">
<p x-data="{ clicked: false }">
<template x-if="clicked">
<div class="registered-grid">
<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>
</template>
</div>
<div class="registered-activities-div"> <div class="registered-activities-div">
<h3>Registrerte aktiviteter:</h3> <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> <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> <table>
<tr> <tr>
<th>Dato</th> <th>Dato</th>
<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>
@@ -72,32 +95,20 @@
<td x-text="activity.description"></td> <td x-text="activity.description"></td>
<td x-text="`${activity.numberOfUnits} ${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} 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>
</div> </div>
</div> </div>
<div class="standard-activities-div">
<h3>Standardaktiviteter:</h3>
<template x-for="activityTemplate in $store.state.data.activityTemplates" :key="activityTemplate.id">
<p>
<button x-on:click="$store.state.registerTemplateActivity(activityTemplate)">Registrer</button>
<span x-text="`${activityTemplate.name}, ${activityTemplate.activityType.name.toLowerCase()}, ${activityTemplate.numberOfUnits} ${activityTemplate.activityType.unit}`"></span>
<button x-on:click="$store.state.deleteTemplateActivity(activityTemplate)">Fjern</button>
</p>
</template>
</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,19 +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>
<template x-if="$store.state.data.otherUser.isHidden"> <template x-if="otherUser.isHidden">
<td> <td>
<i x-text="otherUser.name"></i> <i x-text="otherUser.name"></i>
</td> </td>
</template> </template>
<template x-if="!$store.state.data.otherUser.isHidden"> <template x-if="!otherUser.isHidden">
<td x-text="otherUser.name"></td> <td x-text="otherUser.name"></td>
</template> </template>
<td x-text="otherUser.totalKilometers.toFixed(1)"></td> <td x-text="otherUser.totalKilometers.toFixed(1)"></td>
<td x-text="otherUser.earliestActivity"></td> <td class="removable-on-small-screen" x-text="otherUser.earliestActivity"></td>
<td x-text="otherUser.latestActivity"></td> <td class="removable-on-small-screen" x-text="otherUser.latestActivity"></td>
</tr> </tr>
</template> </template>
</template> </template>
@@ -183,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>
@@ -193,9 +204,9 @@
<td x-text="activity.description"></td> <td x-text="activity.description"></td>
<td x-text="`${activity.numberOfUnits} ${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)} 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>
+30
View File
@@ -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
View File
@@ -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;