mirror of
https://github.com/badlogic/heissepreise.git
synced 2024-06-23 00:45:41 +02:00
Settings page and settings for default selected stores, chart start date, and chart type.
This commit is contained in:
parent
ba5235b567
commit
bd1fa721e4
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
32
site/model/settings.js
Normal 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
9
site/settings.html
Normal 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
59
site/settings.js
Normal 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();
|
||||
});
|
||||
})();
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue
Block a user