Skip to content

Instantly share code, notes, and snippets.

@JudahSan
Last active July 23, 2023 00:28
Show Gist options
  • Select an option

  • Save JudahSan/a9ab1e4568c1307fd3c61738205bb403 to your computer and use it in GitHub Desktop.

Select an option

Save JudahSan/a9ab1e4568c1307fd3c61738205bb403 to your computer and use it in GitHub Desktop.
LocalStorage

🆘localStorage 😱

Problem Statement:

The localStorage for this sample app, Simple ATM Simulator , is acting all wonky! While I can store the keys just fine, I'm hitting a brick wall when it comes to saving the values!

Screenshot from 2023-07-22 21-15-51

What's Happening:

The sample app is a kacool banking thingy from udemy, and I added localStorage to save usernames and PINs for quick auto-login. When users log in, I call the setItem() method to store the credentials – username as the key, PIN as the value. I works okay with the theme.

credentials:

username pin
km 1111
ad 2222
jm 4444
'use strict';
const account1 = {
owner: 'Kimoney Macharia',
movements: [200, 450, -400, 3000, -650, -130, 70, 1300],
interestRate: 1.2, // %
pin: 1111,
};
const account2 = {
owner: 'Anthony Davista',
movements: [5000, 3400, -150, -790, -3210, -1000, 8500, -30],
interestRate: 1.5,
pin: 2222,
};
const account3 = {
owner: 'Wallah Bean Wallah',
movements: [200, -200, 340, -300, -20, 50, 400, -460],
interestRate: 0.7,
pin: 3333,
};
const account4 = {
owner: 'Jayden MuSmith',
movements: [430, 1000, 700, 50, 90],
interestRate: 1,
pin: 4444,
};
const accounts = [account1, account2, account3, account4];
// Elements
const labelWelcome = document.querySelector('.welcome');
const labelDate = document.querySelector('.date');
const labelBalance = document.querySelector('.balance__value');
const labelSumIn = document.querySelector('.summary__value--in');
const labelSumOut = document.querySelector('.summary__value--out');
const labelSumInterest = document.querySelector('.summary__value--interest');
const labelTimer = document.querySelector('.timer');
const containerApp = document.querySelector('.app');
const containerMovements = document.querySelector('.movements');
const btnLogin = document.querySelector('.login__btn');
const btnTransfer = document.querySelector('.form__btn--transfer');
const btnLoan = document.querySelector('.form__btn--loan');
const btnClose = document.querySelector('.form__btn--close');
const btnSort = document.querySelector('.btn--sort');
const inputLoginUsername = document.querySelector('.login__input--user');
const inputLoginPin = document.querySelector('.login__input--pin');
const inputTransferTo = document.querySelector('.form__input--to');
const inputTransferAmount = document.querySelector('.form__input--amount');
const inputLoanAmount = document.querySelector('.form__input--loan-amount');
const inputCloseUsername = document.querySelector('.form__input--user');
const inputClosePin = document.querySelector('.form__input--pin');
// Save successful login creds to localStorage
const saveLoginCreds = (username, pin) => {
localStorage.setItem('username', username);
localStorage.setItem('pin', pin);
};
// Auto-login: check for saved creds and attempt login
const autoLogin = () => {
const savedUsername = localStorage.getItem('username');
const savedPin = localStorage.getItem('pin');
if (savedUsername && savedPin) {
currentAccount = accounts.find(acc => acc.username === savedUsername);
if (currentAccount?.pin === Number(savedPin)) {
// Auto-login successful, now display account dets
labelWelcome.textContent = `Welcome Back, ${
currentAccount.owner.split(' ')[0]
}`;
// Clear data in fields
inputLoginUsername.value = inputLoginPin.value = '';
// Remove cursor focus
inputLoginPin.blur();
containerApp.style.opacity = 100;
// Show movements
displayMovements(currentAccount.movements);
// Show the balance
calcDisplayBalance(currentAccount.movements);
// Show bank summary
calcDisplaySummary(currentAccount);
}
}
};
const displayMovements = movements => {
containerMovements.innerHTML = '';
movements.forEach(function (mov, i) {
const type = mov > 0 ? 'deposit' : 'withdrawal';
const html = `
<div class="movements__row">
<div class="movements__type movements__type--${type}">${
i + 1
} ${type} </div>
<div class="movements__value">${mov}€</div>
</div>
`;
containerMovements.insertAdjacentHTML('afterbegin', html);
});
};
// calculate and print balance
const calcDisplayBalance = movements => {
const balance = movements.reduce((acc, cur) => acc + cur, 0);
labelBalance.textContent = `${balance} €`;
};
const calcDisplaySummary = acc => {
const incomes = acc.movements
.filter(mov => mov > 0)
.reduce((acc, mov) => acc + mov, 0);
labelSumIn.textContent = `${incomes} €`;
const out = acc.movements
.filter(mov => mov < 0)
.reduce((acc, mov) => acc + mov, 0);
labelSumOut.textContent = `${Math.abs(out)}€`;
// Interest paid on each deposit
// Interest should be > 1
const interest = acc.movements
.filter(mov => mov > 0)
.map(deposit => (deposit * acc.interestRate) / 100)
.filter((int, i, arr) => {
console.log(arr);
return int >= 1;
})
.reduce((acc, int) => acc + int, 0);
labelSumInterest.textContent = `${interest}€`;
};
// Function to create usernames
const createUsername = acc => {
acc.forEach(acc => {
acc.username = acc.owner
.toLowerCase()
.split(' ')
.map(name => name[0])
.join('');
});
};
createUsername(accounts);
// console.log(accounts);
// Event handlers
let currentAccount;
btnLogin.addEventListener('click', e => {
// Prevent form from submitting
e.preventDefault();
// console.log('LOGIN');
currentAccount = accounts.find(
acc => acc.username === inputLoginUsername.value
);
console.log(currentAccount);
if (currentAccount?.pin === Number(inputLoginPin.value)) {
// Display bank details
labelWelcome.textContent = `Welcome Back, ${
currentAccount.owner.split(' ')[0]
}`;
// Clear data in fields
inputLoginUsername.value = inputLoginPin.value = '';
// Remove cursor focus
inputLoginPin.blur();
containerApp.style.opacity = 100;
// Show movements
displayMovements(currentAccount.movements);
// Show the balance
calcDisplayBalance(currentAccount.movements);
// Show bank summary
calcDisplaySummary(currentAccount);
// Save login creds to localStorage
saveLoginCreds(inputLoginUsername.value, inputLoginPin.value);
// Debugging
console.log('LOGIN');
} else {
// Create error alert
const alertElement = document.createElement('div');
alertElement.classList.add('alert', 'alert-danger');
alertElement.textContent = 'Incorrect credentials. Please try again.';
alertElement.style.fontSize = '16px';
alertElement.style.position = 'fixed';
alertElement.style.top = '50%';
alertElement.style.left = '50%';
alertElement.style.transform = 'translate(-50%, -50%)';
document.body.appendChild(alertElement);
// Timeout to disappear the alert
setTimeout(() => {
alertElement.style.display = 'none';
}, 3000);
}
// TODO: cash transfer
// btnTransfer.addEventListener('click', e => {
// e.preventDefault();
// const amount = Number(inputTransferAmount.value);
// });
// const loginStatus = currentAccount?.pin === Number(inputLoginPin.value) ? 'LOGIN' : 'INVALID PIN';
// console.log(loginStatus);
});
document.addEventListener('DOMContentLoaded', autoLogin);
// Dark mode
const toggle = document.getElementById('toggleDark');
const body = document.querySelector('body');
const movement = document.querySelector('.movements');
// Function to set the theme
const setTheme = theme => {
toggle.classList.toggle('bi-moon', theme === 'dark');
toggle.classList.toggle('bi-brightness-high-fill', theme === 'light');
movement.style.background = theme === 'dark' ? 'black' : 'white';
movement.style.color = theme === 'dark' ? 'white' : 'black';
body.style.background = theme === 'dark' ? 'black' : 'white';
body.style.color = theme === 'dark' ? 'white' : 'black';
body.style.transition = '0s'; // Set default transition time to 0 seconds
if (localStorage.getItem('toggleClicked')) {
body.style.transition = '2s'; // Set transition time to 2 seconds if the toggle button is clicked
localStorage.removeItem('toggleClicked'); // Remove the 'toggleClicked' flag from local storage
}
};
// Function to toggle the theme
const toggleTheme = () => {
const currentTheme = toggle.classList.contains('bi-brightness-high-fill')
? 'light'
: 'dark';
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
localStorage.setItem('toggleClicked', true); // Set 'toggleClicked' flag in local storage
};
// Event listener for the toggle button
toggle.addEventListener('click', toggleTheme);
// Check if theme is stored in local storage
const theme = localStorage.getItem('theme');
if (theme === 'dark' || theme === 'light') {
setTheme(theme);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment