Skip to content
This repository was archived by the owner on Oct 1, 2025. It is now read-only.

Commit 9c1fbad

Browse files
committed
feat: Completed Work in Timers Section of the Bankist Project
1 parent 71b69f9 commit 9c1fbad

File tree

6 files changed

+202
-71
lines changed

6 files changed

+202
-71
lines changed
Lines changed: 202 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,49 @@
44
/////////////////////////////////////////////////
55
// BANKIST APP
66

7-
// Data
7+
// DIFFERENT DATA! Contains movement dates, currency and locale
8+
89
const account1 = {
910
owner: 'Jonas Schmedtmann',
10-
movements: [200, 450, -400, 3000, -650, -130, 70, 1300],
11+
movements: [200, 455.23, -306.5, 25000, -642.21, -133.9, 79.97, 1300],
1112
interestRate: 1.2, // %
1213
pin: 1111,
14+
15+
movementsDates: [
16+
'2019-11-18T21:31:17.178Z',
17+
'2019-12-23T07:42:02.383Z',
18+
'2020-01-28T09:15:04.904Z',
19+
'2020-04-01T10:17:24.185Z',
20+
'2020-05-08T14:11:59.604Z',
21+
'2020-05-27T17:01:17.194Z',
22+
'2020-07-11T23:36:17.929Z',
23+
'2020-07-12T10:51:36.790Z',
24+
],
25+
currency: 'EUR',
26+
locale: 'pt-PT', // de-DE
1327
};
1428

1529
const account2 = {
1630
owner: 'Jessica Davis',
1731
movements: [5000, 3400, -150, -790, -3210, -1000, 8500, -30],
1832
interestRate: 1.5,
1933
pin: 2222,
20-
};
21-
22-
const account3 = {
23-
owner: 'Steven Thomas Williams',
24-
movements: [200, -200, 340, -300, -20, 50, 400, -460],
25-
interestRate: 0.7,
26-
pin: 3333,
27-
};
2834

29-
const account4 = {
30-
owner: 'Sarah Smith',
31-
movements: [430, 1000, 700, 50, 90],
32-
interestRate: 1,
33-
pin: 4444,
35+
movementsDates: [
36+
'2019-11-01T13:15:33.035Z',
37+
'2019-11-30T09:48:16.867Z',
38+
'2019-12-25T06:04:23.907Z',
39+
'2020-01-25T14:18:46.235Z',
40+
'2020-02-05T16:33:06.386Z',
41+
'2020-04-10T14:43:26.374Z',
42+
'2023-12-18T18:49:59.371Z',
43+
'2023-12-21T12:01:20.894Z',
44+
],
45+
currency: 'USD',
46+
locale: 'en-US',
3447
};
3548

36-
const accounts = [account1, account2, account3, account4];
49+
const accounts = [account1, account2];
3750

3851
// Elements
3952
const labelWelcome = document.querySelector('.welcome');
@@ -65,26 +78,167 @@ const inputClosePin = document.querySelector('.form__input--pin');
6578
/////////////////////////////////////////////////
6679
// LECTURES
6780

81+
const minToLogOut = 5;
82+
83+
let sorted = false;
84+
let currencyOptions = {};
85+
let currAccount, currMinute, logout, time, timer;
86+
6887
const currencies = new Map([
6988
['USD', 'United States dollar'],
7089
['EUR', 'Euro'],
7190
['GBP', 'Pound sterling'],
7291
]);
7392

93+
const labelDateOptions = {
94+
year: 'numeric',
95+
month: 'long',
96+
day: 'numeric',
97+
weekday: 'long',
98+
hour: 'numeric',
99+
minute: 'numeric'
100+
};
101+
102+
const movDateOptions = {
103+
year: 'numeric',
104+
month: 'numeric',
105+
day: 'numeric'
106+
};
107+
108+
const getLocaleDate = (date, locale, options) => new Intl.DateTimeFormat(locale, options).format(date);
109+
110+
const getCurrencyOptions = (acc) =>
111+
{
112+
currencyOptions.style = 'currency';
113+
currencyOptions.currency = acc.currency;
114+
};
115+
116+
const getLocaleNumber = (acc, number) => new Intl.NumberFormat(acc.locale, currencyOptions).format(number);;
117+
118+
const getDaysDiff = (date1, date2) => Math.round(Math.abs(date2 - date1) / (1000 * 60 * 60 * 24));
119+
120+
const formatMovDate = date =>
121+
{
122+
console.log(date);
123+
124+
const now = new Date();
125+
const daysDiff = getDaysDiff(now, date);
126+
console.log(daysDiff);
127+
128+
if (daysDiff <= 1) return daysDiff === 0 ? 'Today' : 'Yesterday';
129+
else if (daysDiff <= 7) return `${ daysDiff } days ago`;
130+
131+
return getLocaleDate(date, currAccount.locale, movDateOptions);
132+
};
133+
74134
const createUsernames = accounts =>
75135
accounts.forEach(account =>
76136
account.username = account.owner.toLowerCase().split(' ').map(name => name[0]).join(''));
77137
createUsernames(accounts);
78-
console.log(accounts);
138+
139+
const updateLabelContent = () =>
140+
{
141+
const now = new Date();
142+
labelDate.textContent = getLocaleDate(now, currAccount.locale, labelDateOptions);
143+
};
79144

80145
const updateUI = () =>
81146
{
82-
displayMovements(currAccount.movements);
147+
updateLabelContent();
148+
149+
currMinute = setInterval(updateLabelContent(), 1000 * 60);
150+
151+
displayMovements(currAccount);
83152
calcDisplayBalance(currAccount.movements);
84153
calcDisplaySummary(currAccount.movements);
85154
};
86155

87-
let currAccount;
156+
const clearUI = () =>
157+
{
158+
containerApp.style.opacity = 0;
159+
labelWelcome.textContent = 'Log in to get started';
160+
};
161+
162+
const displayMovements = (acc, sort = false) =>
163+
{
164+
containerMovements.innerHTML = '';
165+
166+
const dates = acc.movementsDates;
167+
const temp = dates.slice();
168+
const datesIndices = Array.from({ length: dates.length }, (_, i) => i);
169+
const movs = sort ? acc.movements.slice().sort((a, b) => a - b) : acc.movements;
170+
sort ? datesIndices.sort((a, b) => acc.movements[a] - acc.movements[b]) : datesIndices;
171+
172+
console.log(dates);
173+
174+
let i = 0;
175+
for (let index of datesIndices)
176+
dates[i++] = temp[index];
177+
178+
movs.forEach((mov, i) =>
179+
{
180+
const type = mov > 0 ? 'deposit' : 'withdrawal';
181+
182+
console.log(dates[i]);
183+
const dateFormatted = formatMovDate(new Date(dates[i]));
184+
const movFormatted = getLocaleNumber(acc, mov);
185+
186+
const html = `
187+
<div class="movements__row">
188+
<div class="movements__type movements__type--${ type }">${ i + 1 } ${ type }</div>
189+
<div class="movements__date">${ dateFormatted }</div>
190+
<div class="movements__value">${ movFormatted }</div>
191+
</div>
192+
`;
193+
194+
containerMovements.insertAdjacentHTML('afterbegin', html);
195+
});
196+
};
197+
198+
const calcDisplayBalance = movements =>
199+
{
200+
const balance = movements.reduce((acc, mov) => acc + mov, 0);
201+
202+
currAccount.balance = balance;
203+
labelBalance.textContent = `${ getLocaleNumber(currAccount, balance) }`;
204+
};
205+
206+
const calcDisplaySummary = movements =>
207+
{
208+
const income = movements.filter(mov => mov > 0).reduce((acc, mov) => acc + mov, 0);
209+
const outcome = movements.filter(mov => mov < 0).reduce((acc, mov) => acc + mov, 0);
210+
const interest = movements.filter(mov => mov > 0)
211+
.map(mov => mov * currAccount.interestRate / 100)
212+
.filter(mov => mov >= 1)
213+
.reduce((acc, mov) => acc + mov, 0);
214+
215+
labelSumIn.textContent = `${ getLocaleNumber(currAccount, income) }`;
216+
labelSumOut.textContent = `${ getLocaleNumber(currAccount, Math.abs(outcome)) }`;
217+
labelSumInterest.textContent = `${ getLocaleNumber(currAccount, interest) }`;
218+
};
219+
220+
const tick = () =>
221+
{
222+
const min = String(Math.trunc(time / 60)).padStart(2, '0');
223+
const sec = String(time % 60).padStart(2, '0');
224+
225+
labelTimer.textContent = `${ min }:${ sec }`;
226+
227+
if (time === 0)
228+
{
229+
clearInterval(timer);
230+
clearUI();
231+
}
232+
time--;
233+
};
234+
235+
const startTimer = () =>
236+
{
237+
time = minToLogOut * 60;
238+
239+
tick();
240+
timer = setInterval(tick, 1000);
241+
};
88242

89243
btnLogin.addEventListener('click', event =>
90244
{
@@ -95,7 +249,12 @@ btnLogin.addEventListener('click', event =>
95249
if (currAccount?.pin !== Number(inputLoginPin.value))
96250
return;
97251

252+
if (currMinute) clearInterval(currMinute);
253+
if (timer) clearInterval(timer);
254+
startTimer();
255+
98256
labelWelcome.textContent = `Welcome back, ${ currAccount.owner.split(' ')[0] }`;
257+
getCurrencyOptions(currAccount);
99258

100259
containerApp.style.opacity = 1;
101260

@@ -146,10 +305,18 @@ btnTransfer.addEventListener('click', event =>
146305
if (!toAccount)
147306
return;
148307

308+
clearInterval(timer);
309+
startTimer();
310+
149311
if (currAccount.balance >= amount && toAccount?.username !== currAccount.username)
150312
{
151-
currAccount.movements.push(-1 * amount);
152-
toAccount.movements.push(amount);
313+
const now = new Date().toISOString();
314+
315+
currAccount.movements.push(- amount.toFixed(2));
316+
currAccount.movementsDates.push(now);
317+
318+
toAccount.movements.push(+amount.toFixed(2));
319+
toAccount.movementsDates.push(now);
153320
updateUI();
154321

155322
console.log('Transfer Valid');
@@ -160,11 +327,15 @@ btnLoan.addEventListener('click', event =>
160327
{
161328
event.preventDefault();
162329

163-
const amount = Number(inputLoanAmount.value);
330+
clearInterval(timer);
331+
startTimer();
332+
333+
const amount = Math.round(inputLoanAmount.value);
164334

165335
if (amount > 0 && currAccount.movements.some(mov => mov >= amount * 0.1))
166336
{
167337
currAccount.movements.push(amount);
338+
currAccount.movementsDates.push(new Date().toISOString());
168339

169340
inputLoanAmount.value = '';
170341
updateUI();
@@ -177,72 +348,32 @@ btnClose.addEventListener('click', event =>
177348
{
178349
event.preventDefault();
179350

351+
clearInterval(timer);
352+
startTimer();
353+
180354
if (currAccount.username === inputCloseUsername.value && currAccount.pin === Number(inputClosePin.value))
181355
{
182356
const index = accounts.findIndex(acc => acc.username === currAccount.username);
183357
accounts.splice(index, 1);
184358

185359
inputCloseUsername.value = inputClosePin.value = '';
186-
containerApp.style.opacity = 0;
187-
188-
labelBalance.textContent = 'Log in to get started';
360+
clearUI();
189361

190362
console.log('Account Deleted');
191363
}
192364
});
193365

194-
let sorted = false;
195366

196367
btnSort.addEventListener('click', event =>
197368
{
198369
event.preventDefault();
199-
sorted = !sorted;
200-
displayMovements(currAccount.movements, sorted);
201-
});
202-
203-
const displayMovements = (movements, sort = false) =>
204-
{
205-
containerMovements.innerHTML = '';
206370

207-
const movs = sort ? movements.slice().sort((a, b) => a - b) : movements;
371+
clearInterval(timer);
372+
startTimer();
208373

209-
movs.forEach((mov, i) =>
210-
{
211-
const type = mov > 0 ? 'deposit' : 'withdrawal';
212-
213-
const html = `
214-
<div class="movements__row">
215-
<div class="movements__type movements__type--${ type }">${ i + 1 } ${ type }</div>
216-
<div class="movements__value">${ mov }€</div>
217-
</div>
218-
`;
219-
// <div class="movements__date">3 days ago</div>
220-
221-
containerMovements.insertAdjacentHTML('afterbegin', html);
222-
});
223-
};
224-
225-
const calcDisplayBalance = movements =>
226-
{
227-
const balance = movements.reduce((acc, mov) => acc + mov, 0);
228-
229-
currAccount.balance = balance;
230-
labelBalance.textContent = `${ balance }€`;
231-
};
232-
233-
const calcDisplaySummary = movements =>
234-
{
235-
const income = movements.filter(mov => mov > 0).reduce((acc, mov) => acc + mov, 0);
236-
const outcome = movements.filter(mov => mov < 0).reduce((acc, mov) => acc + mov, 0);
237-
const interest = movements.filter(mov => mov > 0)
238-
.map(mov => mov * currAccount.interestRate / 100)
239-
.filter(mov => mov >= 1)
240-
.reduce((acc, mov) => acc + mov, 0);
241-
242-
labelSumIn.textContent = `${ income }€`;
243-
labelSumOut.textContent = `${ Math.abs(outcome) }€`;
244-
labelSumInterest.textContent = `${ interest }€`;
245-
};
374+
sorted = !sorted;
375+
displayMovements(currAccount, sorted);
376+
});
246377

247378
const overallBalance = accounts.flatMap(acc => acc.movements).reduce((acc, curr) => acc += curr, 0);
248379
console.log(`Overall Balance: ${ overallBalance }`);

0 commit comments

Comments
 (0)