mirror of
https://github.com/cloudmaker97/DurstRechner.git
synced 2025-12-05 23:48:39 +00:00
Hinzufügen einer Option zum Berechnen von Pfand
This commit is contained in:
parent
f93fc66af3
commit
97e3971f6f
7 changed files with 91 additions and 12 deletions
|
|
@ -3,60 +3,70 @@
|
|||
"id": 75086086956949000,
|
||||
"name": "Wasser",
|
||||
"price": "0.5",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/wasser.webp"
|
||||
},
|
||||
{
|
||||
"id": 403980494034923100,
|
||||
"name": "Cola",
|
||||
"price": "1",
|
||||
"deposit": "0.25",
|
||||
"image": "./assets/example/images/cola.webp"
|
||||
},
|
||||
{
|
||||
"id": 174111295271372860,
|
||||
"name": "Fanta",
|
||||
"price": "1",
|
||||
"deposit": "0.25",
|
||||
"image": "./assets/example/images/fanta.webp"
|
||||
},
|
||||
{
|
||||
"id": 13086165444583086,
|
||||
"name": "Bier",
|
||||
"price": "1.5",
|
||||
"deposit": "0.07",
|
||||
"image": "./assets/example/images/bier.webp"
|
||||
},
|
||||
{
|
||||
"id": 227920082494117630,
|
||||
"name": "Helles Bier",
|
||||
"price": "1.2",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/bier_helles.webp"
|
||||
},
|
||||
{
|
||||
"id": 27617349687000040,
|
||||
"name": "Apfelsaft",
|
||||
"price": "1.2",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/apfelsaft.webp"
|
||||
},
|
||||
{
|
||||
"id": 191783545996520450,
|
||||
"name": "Eistee",
|
||||
"price": "1.5",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/eistee.webp"
|
||||
},
|
||||
{
|
||||
"id": 203321763516746460,
|
||||
"name": "Cider",
|
||||
"price": "1.8",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/cider.webp"
|
||||
},
|
||||
{
|
||||
"id": 615216202376277900,
|
||||
"name": "Zitronenlimonade",
|
||||
"price": "1",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/limonade.webp"
|
||||
},
|
||||
{
|
||||
"id": 363150314621734500,
|
||||
"name": "Wodka Lemon",
|
||||
"price": "3",
|
||||
"deposit": null,
|
||||
"image": "./assets/example/images/wodka_lemon.webp"
|
||||
}
|
||||
]
|
||||
|
|
@ -3,60 +3,70 @@
|
|||
"id": 75086086956949000,
|
||||
"name": "Wasser",
|
||||
"price": "0.5",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=1"
|
||||
},
|
||||
{
|
||||
"id": 403980494034923100,
|
||||
"name": "Cola",
|
||||
"price": "1",
|
||||
"deposit": "0.25",
|
||||
"image": "https://placehold.co/250x250?text=2"
|
||||
},
|
||||
{
|
||||
"id": 174111295271372860,
|
||||
"name": "Fanta",
|
||||
"price": "1",
|
||||
"deposit": "0.25",
|
||||
"image": "https://placehold.co/250x250?text=3"
|
||||
},
|
||||
{
|
||||
"id": 13086165444583086,
|
||||
"name": "Bier",
|
||||
"price": "1.5",
|
||||
"deposit": "0.07",
|
||||
"image": "https://placehold.co/250x250?text=4"
|
||||
},
|
||||
{
|
||||
"id": 227920082494117630,
|
||||
"name": "Helles Bier",
|
||||
"price": "1.2",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=5"
|
||||
},
|
||||
{
|
||||
"id": 27617349687000040,
|
||||
"name": "Apfelsaft",
|
||||
"price": "1.2",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=6"
|
||||
},
|
||||
{
|
||||
"id": 191783545996520450,
|
||||
"name": "Eistee",
|
||||
"price": "1.5",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=7"
|
||||
},
|
||||
{
|
||||
"id": 203321763516746460,
|
||||
"name": "Cider",
|
||||
"price": "1.8",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=8"
|
||||
},
|
||||
{
|
||||
"id": 615216202376277900,
|
||||
"name": "Zitronenlimonade",
|
||||
"price": "1",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=9"
|
||||
},
|
||||
{
|
||||
"id": 363150314621734500,
|
||||
"name": "Wodka Lemon",
|
||||
"price": "3",
|
||||
"deposit": null,
|
||||
"image": "https://placehold.co/250x250?text=10"
|
||||
}
|
||||
]
|
||||
|
|
@ -77,15 +77,34 @@ class Element {
|
|||
return document.querySelector('.navbar-brand');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons for importing test data
|
||||
* @returns {Element}
|
||||
*/
|
||||
static getButtonsImportTestdata() {
|
||||
return document.querySelectorAll('[data-action=import-testdata]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buttons for showing the test data
|
||||
* @returns {Element}
|
||||
*/
|
||||
static getButtonShowTestdata() {
|
||||
return document.querySelectorAll('[data-action=import-show-testdata]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the button for clearing the test data
|
||||
* @returns {Element}
|
||||
*/
|
||||
static getButtonClearTestdata() {
|
||||
return document.querySelectorAll('[data-action=import-clear]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the button for accessing the GitHub repository
|
||||
* @returns {Element}
|
||||
*/
|
||||
static getGitHubReferenceLink() {
|
||||
return document.querySelector('[data-github-ref]');
|
||||
}
|
||||
|
|
@ -122,6 +141,15 @@ class TemplateElement {
|
|||
return this.removeTemplate(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the deposit element template
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
static getDepositTemplate() {
|
||||
const element = document.querySelector('[data-template=product-deposit]').cloneNode(true);
|
||||
return this.removeTemplate(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the template attribute from the element
|
||||
* @param element {HTMLElement}
|
||||
|
|
@ -143,11 +171,12 @@ class Product {
|
|||
* @param price {number} Price of the product
|
||||
* @param image {string} Image of the product (source url or base64)
|
||||
*/
|
||||
constructor(name, price, image) {
|
||||
constructor(name, price, deposit, image) {
|
||||
this.id = Product.generateId();
|
||||
this.name = name;
|
||||
this.price = price;
|
||||
this.image = image;
|
||||
this.deposit = deposit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -324,7 +353,7 @@ class ProductManager {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async convertAndSaveProductImages(json) {
|
||||
const products = json.map(e => new Product(e.name, e.price, e.image));
|
||||
const products = json.map(e => new Product(e.name, e.price, e.deposit, e.image));
|
||||
for (const product of products) {
|
||||
if (!product.image.toString().startsWith('data:image/')) {
|
||||
product.image = await Base64Image.imageResize(await Base64Image.fromImageUrl(product.image))
|
||||
|
|
@ -349,7 +378,7 @@ class ProductManager {
|
|||
try {
|
||||
parse = JSON.parse(json);
|
||||
} catch (e) {}
|
||||
this.products = parse.map(e => new Product(e.name, e.price, e.image));
|
||||
this.products = parse.map(e => new Product(e.name, e.price, e.deposit, e.image));
|
||||
this.renderProductList();
|
||||
}
|
||||
|
||||
|
|
@ -362,6 +391,7 @@ class ProductManager {
|
|||
|
||||
const name = document.querySelector('#product-name').value;
|
||||
const price = document.querySelector('#product-price').value;
|
||||
const deposit = document.querySelector('#product-deposit').value;
|
||||
const image = document.querySelector('#product-image').files[0];
|
||||
|
||||
// Validate price
|
||||
|
|
@ -374,12 +404,12 @@ class ProductManager {
|
|||
if (image) {
|
||||
const imageSrcWithBase64 = Base64Image.fromFile(image);
|
||||
imageSrcWithBase64.then(async imageSrcWithBase64 => {
|
||||
productManager.addProduct(new Product(name, price, await Base64Image.imageResize(imageSrcWithBase64)));
|
||||
productManager.addProduct(new Product(name, price, deposit, await Base64Image.imageResize(imageSrcWithBase64)));
|
||||
ProductManager.resetProductSettingsForm();
|
||||
});
|
||||
} else {
|
||||
let image1 = await Base64Image.imageResize(await Base64Image.fromImageUrl(`https://placehold.co/250x250?text=${name}`));
|
||||
productManager.addProduct(new Product(name, price, image1));
|
||||
let imageDemoBase64 = await Base64Image.imageResize(await Base64Image.fromImageUrl(`https://placehold.co/250x250?text=${name}`));
|
||||
productManager.addProduct(new Product(name, price, deposit, imageDemoBase64));
|
||||
ProductManager.resetProductSettingsForm();
|
||||
}
|
||||
});
|
||||
|
|
@ -450,7 +480,7 @@ class CartManager {
|
|||
registerCartResetEvent() {
|
||||
Element.getCartButton().addEventListener('click', () => {
|
||||
CartHistoryManager.addToTotal(this.cartLines.reduce((acc, cartLine) => {
|
||||
return acc + (cartLine.product.price * cartLine.quantity);
|
||||
return acc + (cartLine.product.price * cartLine.quantity) + (cartLine.product.deposit * cartLine.quantity);
|
||||
}, 0));
|
||||
this.cartLines = [];
|
||||
this.renderCart();
|
||||
|
|
@ -491,10 +521,12 @@ class CartManager {
|
|||
*/
|
||||
renderCart() {
|
||||
// Clear the cart element before rendering except the template
|
||||
Element.getCartElement().querySelectorAll('[data-id]').forEach(e => {
|
||||
Element.getCartElement().querySelectorAll('[data-id], .product-deposit').forEach(e => {
|
||||
if (e.getAttribute('data-template') === null) {
|
||||
e.remove();
|
||||
}
|
||||
|
||||
console.log(e)
|
||||
});
|
||||
|
||||
if(this.cartLines.length === 0) {
|
||||
|
|
@ -509,6 +541,16 @@ class CartManager {
|
|||
const cartLineElement = this.getCartLineElement(cartLine);
|
||||
Element.getCartElement().appendChild(cartLineElement);
|
||||
});
|
||||
|
||||
let depositTotal = 0;
|
||||
this.cartLines.forEach(cartLine => {
|
||||
depositTotal += cartLine.product.deposit * cartLine.quantity;
|
||||
});
|
||||
if(depositTotal !== 0) {
|
||||
let depositElement = TemplateElement.getDepositTemplate();
|
||||
depositElement.querySelector('[data-attr=deposit]').textContent = CartManager.getNumberFormatter().format(depositTotal);
|
||||
Element.getCartElement().appendChild(depositElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -533,7 +575,7 @@ class CartManager {
|
|||
*/
|
||||
calculateCartValue() {
|
||||
let cartValue = this.cartLines.reduce((acc, cartLine) => {
|
||||
return acc + (cartLine.product.price * cartLine.quantity);
|
||||
return acc + (cartLine.product.price * cartLine.quantity) + (cartLine.product.deposit * cartLine.quantity);
|
||||
}, 0);
|
||||
Element.getCartButton().querySelector('[data-total-value]').textContent = CartManager.getNumberFormatter().format(cartValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ const FILES_TO_CACHE = [
|
|||
`${BASE_PATH}/`,
|
||||
`${BASE_PATH}/index.html`,
|
||||
`${BASE_PATH}/assets/manifest.json`,
|
||||
`${BASE_PATH}/assets/script/all.js`,
|
||||
`${BASE_PATH}/assets/script/service-worker.js`,
|
||||
`${BASE_PATH}/assets/style/stylesheet.css`,
|
||||
`${BASE_PATH}/assets/script/all.js`,
|
||||
`${BASE_PATH}/node_modules/bootstrap/dist/css/bootstrap.min.css`,
|
||||
`${BASE_PATH}/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js`,
|
||||
`${BASE_PATH}/node_modules/bootstrap-icons/font/bootstrap-icons.min.css`,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.product-deposit {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Product list contains all available products,
|
||||
|
|
|
|||
14
index.html
14
index.html
|
|
@ -45,7 +45,12 @@
|
|||
</span>
|
||||
<i class="bi bi-dash-circle"></i>
|
||||
</li>
|
||||
<ul class="list-group cart-items"></ul>
|
||||
<li class="list-group-item product-deposit" data-template="product-deposit">
|
||||
Zzgl. <span data-attr="deposit" class="currency-value">0,00</span> Pfand
|
||||
</li>
|
||||
|
||||
<ul class="list-group cart-items">
|
||||
</ul>
|
||||
<div class="alert alert-info cart-empty">Keine Produkte ausgewählt</div>
|
||||
<hr>
|
||||
<button class="btn btn-secondary btn-lg w-100 cart-value mb-3">
|
||||
|
|
@ -85,6 +90,13 @@
|
|||
<input type="number" class="form-control" step="0.01" value="" id="product-price" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="product-deposit" class="form-label">Pfand</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text" id="basic-addon2">€</span>
|
||||
<input type="number" class="form-control" step="0.01" value="" id="product-deposit" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="product-image" class="form-label">Bild auswählen</label>
|
||||
<input type="file" class="form-control" placeholder="Tolles Produkt" id="product-image">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"name": "durst-rechner",
|
||||
"version": "1.0.0",
|
||||
"scripts": {},
|
||||
"scripts": {
|
||||
"dev": "npx http-server -o ."
|
||||
},
|
||||
"keywords": [
|
||||
"calculator",
|
||||
"feuerwehr",
|
||||
|
|
|
|||
Loading…
Reference in a new issue