├── 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 |
81 |
82 |
83 |
84 |
85 |
Request loan
86 |
91 |
92 |
93 |
94 |
95 |
Close account
96 |
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 |
--------------------------------------------------------------------------------