Settings page and settings for default selected stores, chart start date, and chart type.

This commit is contained in:
Mario Zechner 2023-06-15 21:12:01 +02:00
parent ba5235b567
commit bd1fa721e4
9 changed files with 116 additions and 3 deletions

View File

@ -106,6 +106,7 @@ async function bundleJS(inputDir, outputDir, watch) {
carts: `${inputDir}/carts.js`,
cart: `${inputDir}/cart.js`,
changes: `${inputDir}/changes.js`,
settings: `${inputDir}/settings.js`,
index: `${inputDir}/index.js`,
},
bundle: true,

View File

@ -8,6 +8,10 @@ const express = require("express");
const compression = require("compression");
function copyItemsToSite(dataDir) {
fs.copyFileSync(
`${dataDir}/latest-canonical.json.${analysis.FILE_COMPRESSOR}`,
`site/output/data/latest-canonical.json.${analysis.FILE_COMPRESSOR}`
);
const items = analysis.readJSON(`${dataDir}/latest-canonical.json.${analysis.FILE_COMPRESSOR}`);
analysis.writeJSON(`site/output/data/latest-canonical.json`, items);
for (const store of analysis.STORE_KEYS) {

View File

@ -1,5 +1,6 @@
</div>
<div class="flex align-center justify-center gap-2 pt-4">
<a href="settings.html">Einstellungen</a>
<a href="imprint.html">Impressum</a>
<!--<a href="imprint.html">Datenschutz</a>-->
<a href="https://github.com/badlogic/heissepreise"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg></a>

View File

@ -1,10 +1,12 @@
const { Carts } = require("./carts");
const { Items } = require("./items");
const { Settings } = require("./settings");
exports.stores = require("./stores");
exports.categories = require("./categories");
exports.carts = new Carts();
exports.items = new Items();
exports.settings = new Settings();
exports.load = async () => {
await exports.items.load();

32
site/model/settings.js Normal file
View File

@ -0,0 +1,32 @@
const { STORE_KEYS, stores } = require("./stores");
const { Model } = require("./model");
export class Settings extends Model {
constructor() {
super();
this.startDate = "2017-01-01";
this.chartType = "stepped";
STORE_KEYS.forEach((store) => {
this[store] = stores[store].defaultChecked;
});
let settings = localStorage.getItem("settings");
if (settings) {
settings = JSON.parse(settings);
for (const prop of Object.getOwnPropertyNames(settings)) {
this[prop] = settings[prop];
}
}
}
save() {
const settings = {};
for (const prop of Object.getOwnPropertyNames(this)) {
if (prop.startsWith("_")) continue;
settings[prop] = this[prop];
}
localStorage.setItem("settings", JSON.stringify(settings));
}
}

9
site/settings.html Normal file
View File

@ -0,0 +1,9 @@
%%_templates/_header.html%% %%_templates/_menu.html%%
<div class="max-w-lg mx-auto my-8 px-4">
<h2 class="text-2xl font-bold text-center">Einstellungen</h2>
<settings-view></settings-view>
</div>
<script src="settings.js"></script>
%%_templates/_footer.html%%

59
site/settings.js Normal file
View File

@ -0,0 +1,59 @@
const { STORE_KEYS, stores } = require("./model/stores");
const { View } = require("./views/view");
const { Settings } = require("./model/settings");
require("./js/misc");
require("./views/custom-checkbox");
class SettingsView extends View {
constructor() {
super();
this.innerHTML = /*html*/ `
<div class="flex flex-col gap-4 p-4 rounded-xl md:mt-8 bg-gray-100">
<div>Vorselektierte Ketten</div>
<div x-id="stores" class="flex justify-center gap-2 flex-wrap">
${STORE_KEYS.map(
(store) => /*html*/ `
<custom-checkbox
x-id="${store}" x-state x-change
label="${stores[store].name}"
class="${stores[store].color}"
${stores[store].defaultChecked ? "checked" : ""}
></custom-checkbox>`
).join("")}
</div>
<label
>Start-Datum für Diagramme
<input
x-id="startDate"
x-change
x-state
type="date"
class="cursor-pointer inline-flex items-center gap-x-1 rounded-full bg-white border border-gray-400 px-2 py-1 text-xs font-medium text-gray-600"
/></label>
<label>
Diagramm Typ
<select x-id="chartType" x-change x-state>
<option value="stepped">Stufen</option>
<option value="lines">Linien</option>
</select>
</label>
</div>
`;
this.setupEventHandlers();
}
}
customElements.define("settings-view", SettingsView);
(async () => {
const settings = new Settings();
const settingsView = document.querySelector("settings-view");
settingsView.state = settings;
document.body.addEventListener("x-change", () => {
const state = settingsView.state;
for (const prop of Object.getOwnPropertyNames(state)) {
settings[prop] = state[prop];
}
settings.save();
});
})();

View File

@ -1,4 +1,5 @@
const { STORE_KEYS } = require("../model/stores");
const { settings } = require("../model");
const { today, log, deltaTime } = require("../js/misc");
const { View } = require("./view");
require("./custom-checkbox");
@ -30,6 +31,7 @@ class ItemsChart extends View {
</div>
</div>
`;
this.elements.startDate.value = settings.startDate;
this.setupEventHandlers();
this.addEventListener("x-change", () => {
this.render();
@ -147,14 +149,16 @@ class ItemsChart extends View {
const dataset = {
label: (item.store ? item.store + " " : "") + item.name,
data: dedupPrices.map((price, index) => {
data: dedupPrices.map((price) => {
return {
x: moment(price.date),
y: price.price,
};
}),
stepped: "before",
};
if (settings.chartType == "stepped") {
dataset.stepped = "before";
}
return dataset;
});

View File

@ -1,5 +1,6 @@
const { today, parseNumber, dom, getBooleanAttribute, queryItems, log, deltaTime } = require("../js/misc");
const { stores, STORE_KEYS, BUDGET_BRANDS } = require("../model/stores");
const { settings } = require("../model");
const { View } = require("./view");
class ItemsFilter extends View {
@ -32,7 +33,7 @@ class ItemsFilter extends View {
x-id="${store}" x-state x-change
label="${stores[store].name}"
class="${stores[store].color}"
${stores[store].defaultChecked ? "checked" : ""}
${settings[store] ? "checked" : ""}
></custom-checkbox>`
).join("")}
</div>