Hello! Thanks for replying. It’s my first time posting here. Thought it added automatically lol. Here it is:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Cash Register</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="mainContainer">
<div class="centerFlex gap10">
<h1>Customer</h1>
<span><label for="cash">Cash </label><input id="cash" placeholder="0"></span>
<button id="purchase-btn">PURCHASE</button>
</div>
<div class="centerFlex">
<h1>Product</h1>
<p id="price"></p>
</div>
<div class="centerFlex gap10">
<h1>Register</h1>
<div class="digitalDisplay">
<p>— Change Due: <span id="dueTotal"></span> —</p>
<p id="change-due">Status: </p>
</div>
<p>Total in drawer: <span id="totalCash" style="color: gold;"></span></p>
<div id="cash-in-drawer"></div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS
:root {
--cd: #161616;
--cm: #808080;
--cl: #f2f2f2;
--ca: #00FFFF;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-size: 16px;
font-family: 'Consolas', sans-serif;
background-color: #1b1b32;
color: #fff;
height: 100vh;
}
#purchase-btn {
padding: 2%;
color: #1b1b32;
background-color: gold;
border: none;
}
#purchase-btn:active {
opacity: 0.75;
}
.mainContainer {
padding: 25px;
width: 100%;
display: flex;
flex-flow: column nowrap;
gap: 20px;
background-color: rgb(0,0,0,0.25);
backdrop-filter: multiply;
}
.centerFlex {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
background-color: #1b1b32;
padding: 5%;
}
.gap50 {
gap: 50px;
}
.gap25 {
gap: 25px;
}
.gap10 {
gap: 10px;
}
.digitalDisplay {
background-color: black;
display: block;
width: 250px;
min-height: 75px;
color: #00ff00;
text-align: right;
padding: 5px;
}
.digitalDisplay:first-child {
display: block;
width: 100%;
}
#cash-in-drawer {
display: flex;
flex-flow: column nowrap;
position: relative;
}
#cash-in-drawer > p {
flex: 1 0 100%;
display: flex;
justify-content: space-between;
gap: 20px;
}
.coinNum {
color: #00ffff;
position: absolute;
right: -20px;
text-align: left;
vertical-align: super;
font-size: 0.7em;
}
JavaScript
let price = 1.87;
let cid = [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
];
const cash = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");
const changeDue = document.getElementById("change-due");
const dueTotal = document.getElementById("dueTotal");
const productPrice = document.getElementById("price");
const totalCashIn = document.getElementById("totalCash");
const cashDrawer = document.getElementById("cash-in-drawer");
// ========== PENNYFY VALUES FOR EXACT TRANSACTIONS ==========
const pricePenny = price * 100;
let cashPenny = 0;
let cidPenny = [];
const denominations = [1,5,10,25,100,500,1000,2000,10000];
const updateCidPenny = () => {
cidPenny = [...cid.map((slot) => [Math.round(slot[1]*100)])];
cidPenny.forEach((slot,index) => slot.unshift(cid[index][0]))
cidPenny.forEach((v,i) => v.push(denominations[i]));
};
updateCidPenny();
// ========== DRAWER TOTAL AMOUNT ==========
const sumArr = (arr) => arr.reduce((t,c) => t + c[1], 0);
let cidTotal = sumArr(cidPenny);
const cointer = () => {
let arr = [...cidPenny];
return arr.map((coin, index) => coin[1] / denominations[index])
};
// ========== CHANGE DUE FUNCTIONS & VALUES ==========
const isChangeDue = (money, price) => {
return money >= price;
};
const calculateChange = () => {
return cashPenny - pricePenny;
};
// ==== CHANGE MANAGER
const changeManager = (change) => {
let stillDue = change;
let coinHolder = []; /* PRINT PURPOSES */
let currentDrawer = sumArr(cidPenny);
let cancelTransaction = false;
if(change > cidTotal) {
return "INSUFFICIENT_FUNDS";
} else {
let retrieveCoins = [...cidPenny].reverse();
let fromNextTier = currentDrawer;
// ===== CYCLE BEGINS
retrieveCoins.forEach((coin,index) => {
if(cancelTransaction) {
console.log("*************CANCELED**********************")
return;
}
fromNextTier -= coin[1];
if(stillDue > 0 && stillDue >= coin[2]) {
let neededFromCoin = stillDue - (stillDue % coin[2]);
let taken = neededFromCoin > coin[1] ? coin[1] : neededFromCoin;
coinHolder.unshift([taken]);
coinHolder[0].unshift(coin[0]);
stillDue -= taken;
cidPenny[Math.abs(index - 8)][1] -= taken;
cid[Math.abs(index - 8)][1] -= taken/100;
} else {
if(stillDue > fromNextTier) {
cancelTransaction = true;
}
}
});
// ===== CYCLE ENDS
}
if(cancelTransaction) {
return "INSUFFICIENT_FUNDS";
}
const prePrint = coinHolder.reverse().map((coin) => {
if(coin[1] == 0) {
return ""
}
return `${coin[0]}: \$${coin[1]/100}`;
});
return prePrint.join(" ");
};
// ========== UPDATE & DRAW VALUES IN HTML ==========
// Proper Case method from https://stackoverflow.com/a/5574446
String.prototype.toProperCase = function () {
return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
};
// Update values from drawer first
const updateDrawer = () => {
cashDrawer.innerHTML = "";
cid.forEach((coin,index) => {
cashDrawer.innerHTML += `<p><span class="coinTag">${coin[0].toProperCase()}</span> \$${coin[1].toFixed(2)} <span class="coinNum">${cointer()[index]}</span></p>`;
})
totalCashIn.innerText = "$" + cidTotal/100;
}
const updateAll = () => {
productPrice.textContent = `\$${price}`;
updateDrawer();
updateCidPenny();
cidTotal = sumArr(cidPenny);
}
// ========== INTERACTIONS ==========
updateAll();
purchaseBtn.addEventListener("click", (e) => {
e.preventDefault();
cashPenny = (cash.value) * 100;
changeDue.textContent = "Status: "
if(isChangeDue(cashPenny, pricePenny)) {
let due = calculateChange();
dueTotal.textContent = due/100;
switch(due) {
case 0:
changeDue.textContent = "No change due - customer paid with exact cash";
break;
default:
const screenPrint = changeManager(due);
const drawerStatus = () => {
return cidTotal > 0 ? "OPEN" : "CLOSED";
}
updateAll();
changeDue.textContent += `${drawerStatus()} ${screenPrint}`;
}
} else {
alert("Customer does not have enough money to purchase the item")
}
updateAll();
});
Thank you!