mirror of
https://github.com/gabehf/CostInCoffee.git
synced 2026-03-07 13:38:16 -08:00
Nearly done
This commit is contained in:
parent
3933247e4a
commit
8d130b1e7b
3 changed files with 226 additions and 37 deletions
79
index.css
79
index.css
|
|
@ -16,14 +16,14 @@
|
|||
body {
|
||||
background-color: var(--main-bg);
|
||||
font-family: 'Josefin Sans', sans-serif;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 800px;
|
||||
margin: auto;
|
||||
margin-top: 20px;
|
||||
margin-top: 18px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -37,7 +37,7 @@ body {
|
|||
h1 {
|
||||
font-family: 'Orelega One', serif;
|
||||
color: var(--brown);
|
||||
font-size: 64px;
|
||||
font-size: 56px;
|
||||
text-align: center;
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ h1 {
|
|||
h2 {
|
||||
font-family: 'Orelega One', serif;
|
||||
font-weight: normal;
|
||||
font-size: 32px;
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
color: var(--text-color);
|
||||
margin-top: 0rem;
|
||||
|
|
@ -58,7 +58,7 @@ button {
|
|||
border: 3px solid var(--brown);
|
||||
color: var(--brown);
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: var(--brown);
|
||||
|
|
@ -89,7 +89,7 @@ button:hover {
|
|||
margin: 10px auto;
|
||||
}
|
||||
|
||||
.cost-display {
|
||||
#cost-display {
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
|
|
@ -97,17 +97,23 @@ button:hover {
|
|||
width: 400px;
|
||||
}
|
||||
|
||||
.subscription-header {
|
||||
#subscription-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
border-bottom: 2px solid var(--text-light);
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
.subscription-header p {
|
||||
#subscription-header p {
|
||||
margin: 3px 0px;
|
||||
}
|
||||
|
||||
.no-subs-text {
|
||||
font-style: italic;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sub-item-container:nth-child(odd) {
|
||||
background-color: white;
|
||||
}
|
||||
|
|
@ -116,6 +122,61 @@ button:hover {
|
|||
width: 350px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#add-sub-form * {
|
||||
margin: 5px 0px;
|
||||
}
|
||||
|
||||
#add-sub-form button {
|
||||
height: 38px;
|
||||
margin-top: 4px;
|
||||
padding-top: 0px;
|
||||
background-color: var(--green);
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
#add-sub-form button:hover {
|
||||
background-color: var(--green-light);
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid var(--brown);
|
||||
border-radius: 5px;
|
||||
font-family: 'Josefin Sans', sans-serif;
|
||||
padding: 10px 0px 6px 1em;
|
||||
padding-left: 1em;
|
||||
font-size: 16px;
|
||||
}
|
||||
input:focus {
|
||||
outline: none;
|
||||
border: 2px solid var(--brown);
|
||||
}
|
||||
|
||||
#subPrice {
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
.ui-autocomplete {
|
||||
background-color: white;
|
||||
font-size: 16px;
|
||||
list-style: none;
|
||||
width: 125px;
|
||||
border: 2px solid var(--brown);
|
||||
border-radius: 5px;
|
||||
padding: 0px;
|
||||
}
|
||||
.ui-autocomplete li {
|
||||
padding: 10px 25px;
|
||||
}
|
||||
.ui-autocomplete li:hover {
|
||||
cursor: pointer;
|
||||
background-color: lightgrey;
|
||||
}
|
||||
.ui-helper-hidden-accessible { display:none; }
|
||||
|
||||
.error {
|
||||
border: 2px solid var(--red);
|
||||
}
|
||||
51
index.html
51
index.html
|
|
@ -6,6 +6,16 @@
|
|||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.7.1.min.js"
|
||||
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
<script
|
||||
src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"
|
||||
integrity="sha256-eTyxS0rkjpLEo16uXTS0uVCS4815lc40K2iVpWDvdSY="
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
<title>Cost in Coffee</title>
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
</head>
|
||||
|
|
@ -17,41 +27,26 @@
|
|||
</div>
|
||||
<div class="result">
|
||||
<p>Your subscriptions are equivalent to</p>
|
||||
<div id="coffee-count">5.21</div>
|
||||
<div id="coffee-count">0.00</div>
|
||||
<p>cups of coffee a day.</p>
|
||||
<p>That's <span class="cost-display">$11.54</span> of coffee.</p>
|
||||
<p>That's <span id="cost-display">$0.00</span> of coffee.</p>
|
||||
</div>
|
||||
<div class="subscriptions">
|
||||
<div class="subscription-header">
|
||||
<div id="subscription-header">
|
||||
<p>Your Subscriptions</p>
|
||||
<button type="button">Add</button>
|
||||
<button type="button" id="addSubButton">Add</button>
|
||||
</div>
|
||||
<div class="sub-item-container">
|
||||
<div class="sub-item">
|
||||
<p>LinkedIn</p>
|
||||
<p>$40.00</p>
|
||||
</div>
|
||||
<div class="add-sub-item-container" id="addSubFormContainer" hidden>
|
||||
<form action="none" id="add-sub-form" class="sub-item">
|
||||
<input type="text" name="subName" id="subName" placeholder="Subscription">
|
||||
<input type="text" name="subPrice" id="subPrice" placeholder="$0.00">
|
||||
<button type="button" id="confirmSubButton">✓</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="sub-item-container">
|
||||
<div class="sub-item">
|
||||
<p>Youtube Premium</p>
|
||||
<p>$12.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sub-item-container">
|
||||
<div class="sub-item">
|
||||
<p>Netflix</p>
|
||||
<p>$15.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sub-item-container">
|
||||
<div class="sub-item">
|
||||
<p>Crunchyroll</p>
|
||||
<p>$10.00</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <p>Start adding subscriptions and see the costs rise.</p> -->
|
||||
<p class="no-subs-text">Start adding subscriptions and see the costs rise.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
133
main.js
Normal file
133
main.js
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/********* CONSTANTS AND GLOBAL VARS *********/
|
||||
const SubList = [
|
||||
'LinkedIn Premium',
|
||||
'Netflix',
|
||||
'Hulu',
|
||||
'Crunchyroll',
|
||||
'Youtube Premium',
|
||||
'Skillshare',
|
||||
]
|
||||
|
||||
let subscriptions = []
|
||||
let numSubs = 0
|
||||
const pricePattern = /^(\$)?(\d+(\.\d{1,2})?)$/
|
||||
const avgDaysInMonth = 30.475
|
||||
let costOfCoffee = 2.50
|
||||
let costTotal = 0
|
||||
let addFormOpen = false
|
||||
|
||||
const PriceList = [
|
||||
'$5',
|
||||
'$10',
|
||||
'$12',
|
||||
'$15',
|
||||
'$20'
|
||||
]
|
||||
|
||||
/***************** FUNCTION DEFINITIONS **************/
|
||||
|
||||
function addSubscription(name, price) {
|
||||
// make sure no sub text is hidden
|
||||
$('.no-subs-text').hide()
|
||||
// inc. sub count
|
||||
numSubs++
|
||||
$('#addSubFormContainer').after(`
|
||||
<div class="sub-item-container" id="subscription-${numSubs}">
|
||||
<div class="sub-item">
|
||||
<p>${name}</p>
|
||||
<p>${formatPrice(price)}</p>
|
||||
</div>
|
||||
</div>`)
|
||||
costTotal += price
|
||||
|
||||
// update display
|
||||
let dailyCost = costTotal / avgDaysInMonth
|
||||
$('#cost-display').text(`${formatPrice(dailyCost)}`)
|
||||
$('#coffee-count').text(`${(dailyCost / costOfCoffee).toFixed(2)}`)
|
||||
}
|
||||
|
||||
function processSubValue() {
|
||||
let priceString = $('#subPrice').val()
|
||||
if (priceString[0] == '$') {
|
||||
priceString = priceString.slice(1)
|
||||
}
|
||||
return Number(priceString)
|
||||
}
|
||||
|
||||
function formatPrice(num) {
|
||||
return '$' + (Math.round(num * 100) / 100).toFixed(2)
|
||||
}
|
||||
|
||||
function validatePrice() {
|
||||
let priceString = $('#subPrice').val()
|
||||
if (!priceString.match(pricePattern)) {
|
||||
$('#subPrice').addClass('error')
|
||||
return false
|
||||
} else {
|
||||
$('#subPrice').removeClass('error')
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/*************** APP INITIALIZATION *************/
|
||||
|
||||
// Populate saved subscriptions from localStorage
|
||||
|
||||
if (localStorage.getItem('subscriptions') != null) {
|
||||
subscriptions = JSON.parse(localStorage.getItem('subscriptions'))
|
||||
|
||||
for (let sub of subscriptions) {
|
||||
addSubscription(sub.name, sub.price)
|
||||
}
|
||||
}
|
||||
|
||||
/******************* EVENT LISTENERS *****************/
|
||||
|
||||
$('#addSubButton').click(() => {
|
||||
if (!addFormOpen) {
|
||||
$('#addSubFormContainer').show()
|
||||
} else {
|
||||
$('#addSubFormContainer').hide()
|
||||
}
|
||||
addFormOpen = !addFormOpen
|
||||
})
|
||||
|
||||
$('#subName').autocomplete({
|
||||
source: SubList,
|
||||
delay: 0,
|
||||
minLength: 0,
|
||||
})
|
||||
|
||||
$('#subPrice').autocomplete({
|
||||
source: PriceList,
|
||||
delay: 0,
|
||||
minLength: 0,
|
||||
})
|
||||
|
||||
$('#subPrice').on('focus', () => {
|
||||
$('#subPrice').autocomplete('search', '')
|
||||
})
|
||||
|
||||
$('#confirmSubButton').click(() => {
|
||||
if (!validatePrice()) {
|
||||
// disallow submit
|
||||
console.log('nope')
|
||||
return
|
||||
}
|
||||
|
||||
let price = processSubValue()
|
||||
|
||||
addSubscription($('#subName').val(), price)
|
||||
|
||||
subscriptions.push({
|
||||
name: $('#subName').val(),
|
||||
price: price,
|
||||
})
|
||||
localStorage.setItem('subscriptions', JSON.stringify(subscriptions))
|
||||
|
||||
$('#subPrice').val('')
|
||||
$('#subName').val('')
|
||||
|
||||
$('#addSubFormContainer').hide()
|
||||
addFormOpen = !addFormOpen
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue