├── images ├── icon.png └── logo.png ├── README.md ├── index.html ├── style.css └── script.js /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmirhoseinHesami/Bankist/HEAD/images/icon.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmirhoseinHesami/Bankist/HEAD/images/logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀Bankist🚀 2 | 3 | A Fictional & Minimalist Bank 4 | 5 | ## 🎈Live Demo🎈 6 | 7 | **You Can See The `Bankist` Live On:** [Here](https://amirhoseinhesami.github.io/Bankist/) 8 | 9 | ## 👉Log-in credentials👈 10 | 11 | | Account | UserName | Password | 12 | | ------------- | -------- | -------- | 13 | | Admin Account | `aa` | `1111` | 14 | | Guest Account | `ga` | `2222` | 15 | 16 | ## Description 17 | 18 | **Bankist is a Fictional & Online Bank.** 19 | 20 | **Bankist is written in Javascript basically Javascript has the responsibility of the DOM manipulation and user interaction over the entire project.** 21 | 22 | > ⚠ Alert: The app has some browser compatibility issues as I've noticed, especially on mobile browsers and if you are not using the latest versions of the browser, the app may not work properly or not working at all. 23 | 24 | **Features:** 25 | 26 | - ✅ _Log-in_ 27 | - 🎉 _Transfer To Other Accounts_ 28 | - 🚀 _Request Loan_ 29 | - 🎈 _Delete Account_ 30 | - 🔁 _Log-out Timer_ 31 | - 🔥 _Sort Movements_ 32 | - 💥 _Internationalize Date & Currency_ 33 | - 🥳 _Both Mobile & Desktop Responsive_ 34 | 35 | **Technologies:** 36 | 37 | - HTML 38 | - CSS 39 | - JS (Main)🚀 40 | 41 | > ✅ **Feel Free To Fork and Contribute** 42 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bankist 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 31 | 32 |
33 | 34 |
35 |
36 |

Current balance

37 |

38 | As of 04/03/2025 39 |

40 |
41 |

0000€

42 |
43 | 44 | 45 |
46 |
47 |
2 deposit
48 |
3 days ago
49 |
4 000€
50 |
51 |
52 |
53 | 1 withdrawal 54 |
55 |
24/01/2037
56 |
-378€
57 |
58 |
59 | 60 | 61 |
62 |

In

63 |

0000€

64 |

Out

65 |

0000€

66 |

Interest

67 |

0000€

68 | 69 |
70 | 71 | 72 |
73 |

Transfer money

74 |
75 | 76 | 77 | 78 | 79 | 80 |
81 |
82 | 83 | 84 |
85 |

Request loan

86 |
87 | 88 | 89 | 90 |
91 |
92 | 93 | 94 |
95 |

Close account

96 |
97 | 98 | 99 | 100 | 101 | 102 |
103 |
104 | 105 | 106 |

107 | You will be logged out in 05:00 108 |

109 |
110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: inherit; 5 | } 6 | 7 | html { 8 | font-size: 62.5%; 9 | box-sizing: border-box; 10 | } 11 | 12 | body { 13 | font-family: "Poppins", sans-serif; 14 | color: #444; 15 | background-color: #f3f3f3; 16 | height: 100vh; 17 | padding: 2rem; 18 | } 19 | 20 | nav { 21 | display: flex; 22 | justify-content: space-between; 23 | align-items: center; 24 | padding: 0 2rem; 25 | } 26 | 27 | .welcome { 28 | font-size: 1.9rem; 29 | font-weight: 500; 30 | } 31 | 32 | .logo { 33 | height: 5.25rem; 34 | } 35 | 36 | .login { 37 | display: flex; 38 | } 39 | 40 | .login__input { 41 | border: none; 42 | padding: 0.5rem 2rem; 43 | font-size: 1.6rem; 44 | font-family: inherit; 45 | text-align: center; 46 | width: 12rem; 47 | border-radius: 10rem; 48 | margin-right: 1rem; 49 | color: inherit; 50 | border: 1px solid #fff; 51 | transition: all 0.3s; 52 | } 53 | 54 | .login__input:focus { 55 | outline: none; 56 | border: 1px solid #ccc; 57 | } 58 | 59 | .login__input::placeholder { 60 | color: #bbb; 61 | } 62 | 63 | .login__btn { 64 | border: none; 65 | background: none; 66 | font-size: 2.2rem; 67 | color: inherit; 68 | cursor: pointer; 69 | transition: all 0.3s; 70 | } 71 | 72 | .login__btn:hover, 73 | .login__btn:focus, 74 | .btn--sort:hover, 75 | .btn--sort:focus { 76 | outline: none; 77 | color: #777; 78 | } 79 | 80 | /* MAIN */ 81 | .app { 82 | position: relative; 83 | max-width: 100rem; 84 | margin: 4rem auto; 85 | display: grid; 86 | grid-template-columns: 4fr 3fr; 87 | grid-template-rows: auto repeat(3, 15rem) auto; 88 | gap: 2rem; 89 | 90 | /* NOTE This creates the fade in/out anumation */ 91 | opacity: 0; 92 | transition: all 1s; 93 | } 94 | 95 | .balance { 96 | grid-column: 1 / span 2; 97 | display: flex; 98 | align-items: flex-end; 99 | justify-content: space-between; 100 | margin-bottom: 2rem; 101 | } 102 | 103 | .balance__label { 104 | font-size: 2.2rem; 105 | font-weight: 500; 106 | margin-bottom: -0.2rem; 107 | } 108 | 109 | .balance__date { 110 | font-size: 1.4rem; 111 | color: #888; 112 | } 113 | 114 | .balance__value { 115 | font-size: 4.5rem; 116 | font-weight: 400; 117 | } 118 | 119 | /* MOVEMENTS */ 120 | .movements { 121 | grid-row: 2 / span 3; 122 | background-color: #fff; 123 | border-radius: 1rem; 124 | overflow-y: scroll; 125 | } 126 | 127 | .movements__row { 128 | padding: 2.25rem 4rem; 129 | display: flex; 130 | align-items: center; 131 | border-bottom: 1px solid #eee; 132 | } 133 | 134 | .movements__type { 135 | font-size: 1.1rem; 136 | text-transform: uppercase; 137 | font-weight: 500; 138 | color: #fff; 139 | padding: 0.1rem 1rem; 140 | border-radius: 10rem; 141 | margin-right: 2rem; 142 | } 143 | 144 | .movements__date { 145 | font-size: 1.1rem; 146 | text-transform: uppercase; 147 | font-weight: 500; 148 | color: #666; 149 | } 150 | 151 | .movements__type--deposit { 152 | background-image: linear-gradient(to top left, #39b385, #9be15d); 153 | } 154 | 155 | .movements__type--withdrawal { 156 | background-image: linear-gradient(to top left, #e52a5a, #ff585f); 157 | } 158 | 159 | .movements__value { 160 | font-size: 1.7rem; 161 | margin-left: auto; 162 | } 163 | 164 | /* SUMMARY */ 165 | .summary { 166 | grid-row: 5 / 6; 167 | display: flex; 168 | align-items: baseline; 169 | padding: 0 0.3rem; 170 | margin-top: 1rem; 171 | } 172 | 173 | .summary__label { 174 | font-size: 1.2rem; 175 | font-weight: 500; 176 | text-transform: uppercase; 177 | margin-right: 0.8rem; 178 | } 179 | 180 | .summary__value { 181 | font-size: 2.2rem; 182 | margin-right: 2.5rem; 183 | } 184 | 185 | .summary__value--in, 186 | .summary__value--interest { 187 | color: #66c873; 188 | } 189 | 190 | .summary__value--out { 191 | color: #f5465d; 192 | } 193 | 194 | .btn--sort { 195 | margin-left: auto; 196 | border: none; 197 | background: none; 198 | font-size: 1.3rem; 199 | font-weight: 500; 200 | cursor: pointer; 201 | } 202 | 203 | /* OPERATIONS */ 204 | .operation { 205 | border-radius: 1rem; 206 | padding: 3rem 4rem; 207 | color: #333; 208 | } 209 | 210 | .operation--transfer { 211 | background-image: linear-gradient(to top left, #ffb003, #ffcb03); 212 | } 213 | 214 | .operation--loan { 215 | background-image: linear-gradient(to top left, #39b385, #9be15d); 216 | } 217 | 218 | .operation--close { 219 | background-image: linear-gradient(to top left, #e52a5a, #ff585f); 220 | } 221 | 222 | h2 { 223 | margin-bottom: 1.5rem; 224 | font-size: 1.7rem; 225 | font-weight: 600; 226 | color: #333; 227 | } 228 | 229 | .form { 230 | display: grid; 231 | grid-template-columns: 2.5fr 2.5fr 1fr; 232 | grid-template-rows: auto auto; 233 | gap: 0.4rem 1rem; 234 | } 235 | 236 | /* Exceptions for interst */ 237 | .form.form--loan { 238 | grid-template-columns: 2.5fr 1fr 2.5fr; 239 | } 240 | .form__label--loan { 241 | grid-row: 2; 242 | } 243 | /* End exceptions */ 244 | 245 | .form__input { 246 | width: 100%; 247 | border: none; 248 | background-color: rgba(255, 255, 255, 0.4); 249 | font-family: inherit; 250 | font-size: 1.5rem; 251 | text-align: center; 252 | color: #333; 253 | padding: 0.3rem 1rem; 254 | border-radius: 0.7rem; 255 | transition: all 0.3s; 256 | } 257 | 258 | .form__input:focus { 259 | outline: none; 260 | background-color: rgba(255, 255, 255, 0.6); 261 | } 262 | 263 | .form__label { 264 | font-size: 1.3rem; 265 | text-align: center; 266 | } 267 | 268 | .form__btn { 269 | border: none; 270 | border-radius: 0.7rem; 271 | font-size: 1.8rem; 272 | background-color: #fff; 273 | cursor: pointer; 274 | transition: all 0.3s; 275 | } 276 | 277 | .form__btn:focus { 278 | outline: none; 279 | background-color: rgba(255, 255, 255, 0.8); 280 | } 281 | 282 | .logout-timer { 283 | padding: 0 0.3rem; 284 | margin-top: 1.9rem; 285 | text-align: right; 286 | font-size: 1.25rem; 287 | } 288 | 289 | .timer { 290 | font-weight: 600; 291 | } 292 | 293 | /* Media query */ 294 | @media only screen and (max-width: 920px) { 295 | nav { 296 | padding: 0; 297 | } 298 | 299 | .app { 300 | grid-template-columns: 55%; 301 | } 302 | 303 | .summary { 304 | flex-wrap: wrap; 305 | } 306 | 307 | .operation { 308 | padding: 3rem 3rem; 309 | } 310 | } 311 | 312 | @media only screen and (max-width: 750px) { 313 | nav { 314 | flex-direction: column; 315 | padding: 0; 316 | } 317 | 318 | .logo { 319 | margin: 10px 0; 320 | } 321 | 322 | .app { 323 | display: flex; 324 | flex-direction: column; 325 | flex-wrap: wrap; 326 | align-content: center; 327 | } 328 | 329 | .balance__label { 330 | font-size: 1.7rem; 331 | } 332 | 333 | .balance__date { 334 | font-size: 1.4rem; 335 | } 336 | 337 | .balance__value { 338 | font-size: 3.2rem; 339 | } 340 | 341 | .movements { 342 | height: 50vh; 343 | width: 90vw; 344 | } 345 | 346 | .movements__date { 347 | margin-right: 10px; 348 | } 349 | 350 | .movements__row { 351 | justify-content: space-between; 352 | padding: 2rem 3rem; 353 | align-items: center; 354 | flex-wrap: wrap; 355 | } 356 | 357 | .summary { 358 | margin-top: 2rem; 359 | margin-bottom: 2rem; 360 | flex-wrap: wrap; 361 | flex-direction: row; 362 | } 363 | 364 | .operation { 365 | padding: 3rem 2rem; 366 | } 367 | 368 | .operation--loan, 369 | .operation--close { 370 | margin-top: 0; 371 | } 372 | 373 | .form.form--loan { 374 | grid-template-columns: 3.5fr 1fr 1.5fr; 375 | } 376 | 377 | .logout-timer { 378 | margin-bottom: 1rem; 379 | text-align: center; 380 | margin-top: 0; 381 | } 382 | } 383 | 384 | @media only screen and (max-width: 420px) { 385 | .balance { 386 | flex-wrap: wrap; 387 | flex-direction: column; 388 | align-content: center; 389 | align-items: center; 390 | } 391 | 392 | .balance__value { 393 | margin-top: 1rem; 394 | font-size: 3.5rem; 395 | } 396 | 397 | .balance__label { 398 | font-size: 1.9rem; 399 | } 400 | 401 | .balance__date { 402 | font-size: 1.6rem; 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | ///////////////////////////////////////////////// 4 | ///////////////////////////////////////////////// 5 | // BANKIST APP 6 | 7 | ///////////////////////////////////////////////// 8 | // Data 9 | 10 | const account1 = { 11 | owner: "Admin Account", 12 | movements: [150, 465.25, -302.5, 23000, -645.21, -133.9, 79.97, 1250], 13 | interestRate: 1.2, // % 14 | pin: 1111, 15 | 16 | movementsDates: [ 17 | "2021-11-18T21:31:17.178Z", 18 | "2021-12-23T07:42:02.383Z", 19 | "2022-01-20T09:15:04.904Z", 20 | "2022-01-28T10:17:24.185Z", 21 | "2022-02-08T14:11:59.604Z", 22 | "2022-03-02T17:01:17.194Z", 23 | "2022-03-04T23:36:17.929Z", 24 | "2022-03-06T10:51:36.790Z", 25 | ], 26 | currency: "EUR", 27 | locale: "de-DE", 28 | }; 29 | 30 | const account2 = { 31 | owner: "Guest Account", 32 | movements: [5000, 3400, -150, -790, -3210, -1000, 8500, -30], 33 | interestRate: 1.5, 34 | pin: 2222, 35 | 36 | movementsDates: [ 37 | "2021-11-01T13:15:33.035Z", 38 | "2021-11-30T09:48:16.867Z", 39 | "2021-12-25T06:04:23.907Z", 40 | "2022-01-25T14:18:46.235Z", 41 | "2022-02-05T16:33:06.386Z", 42 | "2022-02-10T14:43:26.374Z", 43 | "2022-03-03T18:49:59.371Z", 44 | "2022-03-05T12:01:20.894Z", 45 | ], 46 | currency: "USD", 47 | locale: "en-US", 48 | }; 49 | 50 | const accounts = [account1, account2]; 51 | 52 | ///////////////////////////////////////////////// 53 | // Elements 54 | const labelWelcome = document.querySelector(".welcome"); 55 | const labelDate = document.querySelector(".date"); 56 | const labelBalance = document.querySelector(".balance__value"); 57 | const labelSumIn = document.querySelector(".summary__value--in"); 58 | const labelSumOut = document.querySelector(".summary__value--out"); 59 | const labelSumInterest = document.querySelector(".summary__value--interest"); 60 | const labelTimer = document.querySelector(".timer"); 61 | 62 | const containerApp = document.querySelector(".app"); 63 | const containerMovements = document.querySelector(".movements"); 64 | 65 | const btnLogin = document.querySelector(".login__btn"); 66 | const btnTransfer = document.querySelector(".form__btn--transfer"); 67 | const btnLoan = document.querySelector(".form__btn--loan"); 68 | const btnClose = document.querySelector(".form__btn--close"); 69 | const btnSort = document.querySelector(".btn--sort"); 70 | 71 | const inputLoginUsername = document.querySelector(".login__input--user"); 72 | const inputLoginPin = document.querySelector(".login__input--pin"); 73 | const inputTransferTo = document.querySelector(".form__input--to"); 74 | const inputTransferAmount = document.querySelector(".form__input--amount"); 75 | const inputLoanAmount = document.querySelector(".form__input--loan-amount"); 76 | const inputCloseUsername = document.querySelector(".form__input--user"); 77 | const inputClosePin = document.querySelector(".form__input--pin"); 78 | 79 | ///////////////////////////////////////////////// 80 | // Functions 81 | 82 | const formatMovementsDate = function (locale, date) { 83 | const calcDays = (date1, date2) => 84 | Math.round(Math.abs(date2 - date1) / (1000 * 60 * 60 * 24)); 85 | 86 | const daysPassed = calcDays(date, new Date()); 87 | 88 | if (daysPassed === 0) return "Today"; 89 | if (daysPassed === 1) return "Yesterday"; 90 | if (daysPassed <= 7) return `${daysPassed} days ago`; 91 | 92 | return new Intl.DateTimeFormat(locale).format(date); 93 | }; 94 | 95 | const formatCurrency = function (value, locale, curr) { 96 | return new Intl.NumberFormat(locale, { 97 | style: "currency", 98 | currency: curr, 99 | }).format(value); 100 | }; 101 | 102 | const displayMovements = function (account, sort = false) { 103 | containerMovements.innerHTML = ""; 104 | 105 | const movs = sort 106 | ? account.movements.slice().sort((a, b) => a - b) 107 | : account.movements; 108 | 109 | movs.forEach(function (acc, i) { 110 | const status = acc > 0 ? "deposit" : "withdrawal"; 111 | 112 | const displayDate = formatMovementsDate( 113 | account.locale, 114 | new Date(account.movementsDates[i]) 115 | ); 116 | 117 | const formattedMov = formatCurrency(acc, account.locale, account.currency); 118 | 119 | const element = `
120 |
${ 121 | i + 1 122 | } ${status}
123 |
${displayDate}
124 |
${formattedMov}
125 |
`; 126 | containerMovements.insertAdjacentHTML("afterbegin", element); 127 | }); 128 | }; 129 | 130 | const calcBalance = function (account) { 131 | account.balance = account.movements.reduce((acc, cur) => acc + cur, 0); 132 | labelBalance.textContent = formatCurrency( 133 | account.balance, 134 | account.locale, 135 | account.currency 136 | ); 137 | }; 138 | 139 | const createUserName = function (account) { 140 | account.forEach((acc) => { 141 | acc.username = acc.owner 142 | .toLowerCase() 143 | .split(" ") 144 | .map((name) => name[0]) 145 | .join(""); 146 | }); 147 | }; 148 | createUserName(accounts); 149 | 150 | const displaySummary = function (account) { 151 | const inMov = account.movements 152 | .filter((acc) => acc > 0) 153 | .reduce((acc, cur) => acc + cur, 0); 154 | labelSumIn.textContent = formatCurrency( 155 | inMov, 156 | account.locale, 157 | account.currency 158 | ); 159 | 160 | const outMov = account.movements 161 | .filter((acc) => acc < 0) 162 | .reduce((acc, cur) => acc + cur, 0); 163 | labelSumOut.textContent = formatCurrency( 164 | Math.abs(outMov), 165 | account.locale, 166 | account.currency 167 | ); 168 | 169 | const interest = account.movements 170 | .filter((acc) => acc > 0) 171 | .map((mov) => mov * (account.interestRate / 100)) 172 | .filter((acc) => acc > 1) 173 | .reduce((acc, cur) => acc + cur, 0); 174 | labelSumInterest.textContent = formatCurrency( 175 | interest, 176 | account.locale, 177 | account.currency 178 | ); 179 | }; 180 | 181 | const updateUI = function (acc) { 182 | // Display movements 183 | displayMovements(acc); 184 | 185 | // Display balance 186 | calcBalance(acc); 187 | 188 | // Display summary 189 | displaySummary(acc); 190 | }; 191 | 192 | const startLogOutTimer = function () { 193 | function tik() { 194 | const min = String(Math.floor(time / 60)).padStart(2, 0); 195 | const sec = String(time % 60).padStart(2, 0); 196 | 197 | // In each call, print the remaining time to UI 198 | labelTimer.textContent = `${min}:${sec}`; 199 | 200 | // When 0 seconds, stop timer and log out user 201 | if (time === 0) { 202 | clearInterval(timer); 203 | containerApp.style.opacity = 0; 204 | labelWelcome.textContent = "Log in to get started"; 205 | } 206 | 207 | // Decrease 1s 208 | time--; 209 | } 210 | 211 | // Set time to 2 minutes 212 | let time = 120; 213 | 214 | // Call the timer every second 215 | tik(); 216 | const timer = setInterval(tik, 1000); 217 | 218 | return timer; 219 | }; 220 | 221 | const printWelcome = function (name) { 222 | const now = new Date(); 223 | const greeting = new Map([ 224 | [[6, 7, 8, 9, 10], "Good Morning"], 225 | [[11, 12, 13, 14], "Good Day"], 226 | [[15, 16, 17, 18], "Good Afternoon"], 227 | [[19, 20, 21, 22], "Good Evening"], 228 | [[23, 0, 1, 2, 3, 4, 5], "Good Night"], 229 | ]); 230 | 231 | const arr = [...greeting.keys()].find((key) => key.includes(now.getHours())); 232 | const greet = greeting.get(arr); 233 | 234 | labelWelcome.textContent = `${greet}, ${name}!`; 235 | }; 236 | 237 | /////////////////////////////////////// 238 | // Event handlers 239 | let currentUser, timer; 240 | 241 | btnLogin.addEventListener("click", function (e) { 242 | // Prevent form from submitting 243 | e.preventDefault(); 244 | 245 | const userInput = inputLoginUsername.value.toLowerCase().trim(); 246 | const pin = Number(inputLoginPin.value); 247 | 248 | currentUser = accounts.find((acc) => acc.username === userInput); 249 | 250 | if (currentUser?.pin === pin) { 251 | // Display UI and message 252 | containerApp.style.opacity = 1; 253 | printWelcome(currentUser.owner.split(" ")[0]); 254 | 255 | // Display date 256 | const option = { 257 | year: "numeric", 258 | month: "numeric", 259 | day: "numeric", 260 | hour: "numeric", 261 | minute: "numeric", 262 | }; 263 | const date = new Intl.DateTimeFormat(currentUser.locale, option).format( 264 | new Date() 265 | ); 266 | labelDate.textContent = date; 267 | 268 | // Reset sort 269 | sort = false; 270 | 271 | // Update UI 272 | updateUI(currentUser); 273 | 274 | // Logout timer 275 | if (timer) clearInterval(timer); 276 | timer = startLogOutTimer(); 277 | } else { 278 | containerApp.style.opacity = 0; 279 | labelWelcome.textContent = "Log in to get started"; 280 | } 281 | 282 | // Clear input fields 283 | inputLoginPin.value = inputLoginUsername.value = ""; 284 | inputLoginPin.blur(); 285 | inputLoginUsername.blur(); 286 | }); 287 | 288 | btnTransfer.addEventListener("click", function (e) { 289 | e.preventDefault(); 290 | 291 | const amount = Number(inputTransferAmount.value); 292 | const recieverAccount = accounts.find( 293 | (acc) => acc.username === inputTransferTo.value.toLowerCase().trim() 294 | ); 295 | 296 | if ( 297 | recieverAccount && 298 | amount > 0 && 299 | amount <= currentUser.balance && 300 | recieverAccount?.username !== currentUser.username 301 | ) { 302 | // Doing the transfer 303 | recieverAccount.movements.push(amount); 304 | currentUser.movements.push(-amount); 305 | 306 | // Push dates 307 | recieverAccount.movementsDates.push(new Date().toISOString()); 308 | currentUser.movementsDates.push(new Date().toISOString()); 309 | 310 | // Reset sort 311 | sort = false; 312 | 313 | // Update UI 314 | updateUI(currentUser); 315 | 316 | // Logout timer 317 | clearInterval(timer); 318 | timer = startLogOutTimer(); 319 | } 320 | 321 | // Clear input fields 322 | inputTransferAmount.value = inputTransferTo.value = ""; 323 | inputTransferAmount.blur(); 324 | inputTransferTo.blur(); 325 | }); 326 | 327 | btnLoan.addEventListener("click", function (e) { 328 | e.preventDefault(); 329 | 330 | const amount = Math.floor(Number(inputLoanAmount.value)); 331 | 332 | if (amount > 0 && currentUser.movements.some((mov) => mov >= amount / 10)) { 333 | setTimeout(function () { 334 | // Add movement 335 | currentUser.movements.push(amount); 336 | 337 | // Date 338 | currentUser.movementsDates.push(new Date().toISOString()); 339 | 340 | // Reset sort 341 | sort = false; 342 | 343 | // Update UI 344 | updateUI(currentUser); 345 | 346 | // Reset timer 347 | clearInterval(timer); 348 | timer = startLogOutTimer(); 349 | }, 3000); 350 | } 351 | 352 | // Clear input fields 353 | inputLoanAmount.value = ""; 354 | inputLoanAmount.blur(); 355 | }); 356 | 357 | btnClose.addEventListener("click", function (e) { 358 | e.preventDefault(); 359 | 360 | const closeUserName = inputCloseUsername.value.toLowerCase().trim(); 361 | const closePin = Number(inputClosePin.value); 362 | 363 | if (currentUser.username === closeUserName && currentUser.pin === closePin) { 364 | const index = accounts.findIndex((acc) => acc.username === closeUserName); 365 | 366 | // Delete account 367 | accounts.splice(index, 1); 368 | 369 | // Hide UI 370 | containerApp.style.opacity = 0; 371 | labelWelcome.textContent = "Log in to get started"; 372 | } 373 | 374 | // Clear input fields 375 | inputClosePin.value = inputCloseUsername.value = ""; 376 | inputClosePin.blur(); 377 | inputCloseUsername.blur(); 378 | }); 379 | 380 | let sort = false; 381 | btnSort.addEventListener("click", function (e) { 382 | e.preventDefault(); 383 | displayMovements(currentUser, !sort); 384 | sort = !sort; 385 | }); 386 | --------------------------------------------------------------------------------