Skip to content

Commit 63c57f7

Browse files
authored
Release: v4.2.0
* Allow for multiple countdowns * Updated endowed positions list
2 parents c418f63 + 7a8864c commit 63c57f7

File tree

2 files changed

+1483
-1461
lines changed

2 files changed

+1483
-1461
lines changed

src/components/giving-tuesday/Countdown.js

Lines changed: 76 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,107 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useMemo, useState } from 'react';
22
import classNames from 'classnames';
33
import SbEditable from 'storyblok-react';
44

55
import CountdownPie from './CountdownPie';
66
import UseCountdown from '../../hooks/useCountdown';
77

8+
// use useId when it becomes available
9+
const generateClassName = (key) =>
10+
`${key}-${Math.floor(Math.random() * 100000, 5)}`;
11+
812
const getDescriptorString = (descriptor, time) => {
913
return time !== 1 ? `${descriptor}s` : descriptor;
1014
};
1115

1216
const convertDaysToHours = (days) => (days ? days * 24 : 0);
1317

1418
const Countdown = ({ blok }) => {
15-
const { date, hasDays, hourPieRange, useNew } = blok;
19+
const { date, dayPieRange, hasDays, hourPieRange, isDST } = blok;
1620
const [countdownDate, setCountdownDate] = useState(null);
1721
const [days, hours, minutes, seconds] = UseCountdown(countdownDate) || [];
1822
const displayHours = hasDays ? hours : convertDaysToHours(days) + hours;
1923
const displayHourPieRange = hasDays ? 24 : hourPieRange;
24+
const noTime = days + hours + minutes + seconds <= 0;
25+
const daysClassName = useMemo(() => generateClassName('days'), []);
26+
const hoursClassName = useMemo(() => generateClassName('hours'), []);
27+
const minutesClassName = useMemo(() => generateClassName('minutes'), []);
28+
const secondsClassName = useMemo(() => generateClassName('seconds'), []);
29+
const pacificTimeOffset = useMemo(() => {
30+
const pacificTime = isDST ? 420 : 480;
31+
return pacificTime * 60 * 1000;
32+
}, [isDST]);
2033

2134
useEffect(() => {
2235
if (!countdownDate) {
23-
if (!date) {
24-
if (useNew) {
25-
/**
26-
* manually set date to 04/05/2024 7PM w/ a UTC offset (no daylight savings)
27-
* this should only stay for the current campaign, can remove this and make
28-
* component purely storyblok configurable after campaign
29-
*/
30-
setCountdownDate(new Date(Date.UTC(2024, 3, 6, 2, 0, 0)));
31-
} else {
32-
/**
33-
* manually set date to 04/04/2024 7AM w/ a UTC offset (no daylight savings)
34-
* this should only stay for the current campaign, can remove this and make
35-
* component purely storyblok configurable after campaign
36-
*/
37-
setCountdownDate(new Date(Date.UTC(2024, 3, 4, 14, 0, 0)));
38-
}
39-
} else {
40-
/**
41-
* the date prop returns in the following format: "2023-11-21 23:56"
42-
* we have convert it to be usable for the js Date object
43-
*/
44-
const dateArray = date.split(' ');
45-
46-
setCountdownDate(new Date(`${dateArray[0]}T${dateArray[1]}`));
47-
}
36+
/**
37+
* the date prop returns in the following format: "2023-11-21 23:56"
38+
* we have convert it to be a usable for the js Date object
39+
*/
40+
const blokDateArray = date?.split(' ');
41+
const dateArray = blokDateArray?.[0]?.split('-');
42+
const timeArray = blokDateArray?.[1]?.split(':');
43+
const blokDateObj = new Date(
44+
`${dateArray?.[0]}-${dateArray?.[1]}-${dateArray?.[2]} ${timeArray?.[0]}:${timeArray?.[1]}`
45+
);
46+
const utcOffset = blokDateObj?.getTimezoneOffset() * 60 * 1000;
47+
const timezoneDifference = utcOffset - pacificTimeOffset;
48+
const utcDateObj = new Date(
49+
blokDateObj?.getTime() + utcOffset - timezoneDifference
50+
);
51+
setCountdownDate(
52+
new Date(
53+
Date.UTC(
54+
utcDateObj?.getFullYear(),
55+
utcDateObj?.getMonth(),
56+
utcDateObj?.getDate(),
57+
utcDateObj?.getHours(),
58+
utcDateObj?.getMinutes()
59+
)
60+
)
61+
);
4862
}
49-
}, [countdownDate, setCountdownDate]);
63+
}, [date, countdownDate, setCountdownDate]);
5064

5165
return (
5266
<SbEditable content={blok}>
53-
{days + hours + minutes + seconds <= 0 ? (
54-
<div
55-
className={classNames('countdown-wrapper', {
56-
['has-days']: days > 0,
57-
})}
58-
>
59-
{days > 0 && hasDays && (
60-
<CountdownPie className="pie-days" descriptor="days" percent={0}>
61-
0
62-
</CountdownPie>
63-
)}
64-
<CountdownPie clasName="pie-hours" descriptor="hours" percent={0}>
65-
0
66-
</CountdownPie>
67-
<CountdownPie clasName="pie-minutes" descriptor="minutes" percent={0}>
68-
0
69-
</CountdownPie>
67+
<div
68+
aria-atomic="true"
69+
className={classNames('countdown-wrapper', {
70+
['has-days']: days > 0 && hasDays,
71+
})}
72+
role="timer"
73+
>
74+
{days > 0 && hasDays && (
7075
<CountdownPie
71-
className="pie-seconds"
72-
descriptor="seconds"
73-
percent={0}
76+
className={daysClassName}
77+
descriptor={getDescriptorString('day', days)}
78+
percent={noTime ? 0 : (days / dayPieRange) * 100}
7479
>
75-
0
80+
{noTime ? 0 : days}
7681
</CountdownPie>
77-
</div>
78-
) : (
79-
<div
80-
aria-atomic="true"
81-
className={classNames('countdown-wrapper', {
82-
['has-days']: days > 0,
83-
})}
84-
role="timer"
82+
)}
83+
<CountdownPie
84+
className={hoursClassName}
85+
descriptor={getDescriptorString('hour', displayHours)}
86+
percent={noTime ? 0 : (displayHours / displayHourPieRange) * 100}
8587
>
86-
{days > 0 && hasDays && (
87-
<CountdownPie
88-
className="pie-days"
89-
descriptor={getDescriptorString('day', days)}
90-
percent={(days / 29) * 100}
91-
>
92-
{days}
93-
</CountdownPie>
94-
)}
95-
<CountdownPie
96-
className="pie-hours"
97-
descriptor={getDescriptorString('hour', displayHours)}
98-
percent={(displayHours / displayHourPieRange) * 100}
99-
>
100-
{displayHours}
101-
</CountdownPie>
102-
<CountdownPie
103-
className="pie-minutes"
104-
descriptor={getDescriptorString('minute', minutes)}
105-
percent={(minutes / 60) * 100}
106-
>
107-
{minutes}
108-
</CountdownPie>
109-
<CountdownPie
110-
className="pie-seconds"
111-
descriptor={getDescriptorString('second', seconds)}
112-
percent={(seconds / 60) * 100}
113-
>
114-
{seconds}
115-
</CountdownPie>
116-
</div>
117-
)}
88+
{noTime ? 0 : displayHours}
89+
</CountdownPie>
90+
<CountdownPie
91+
className={minutesClassName}
92+
descriptor={getDescriptorString('minute', minutes)}
93+
percent={noTime ? 0 : (minutes / 60) * 100}
94+
>
95+
{noTime ? 0 : minutes}
96+
</CountdownPie>
97+
<CountdownPie
98+
className={secondsClassName}
99+
descriptor={getDescriptorString('second', seconds)}
100+
percent={noTime ? 0 : (seconds / 60) * 100}
101+
>
102+
{noTime ? 0 : seconds}
103+
</CountdownPie>
104+
</div>
118105
</SbEditable>
119106
);
120107
};

0 commit comments

Comments
 (0)