Skip to content

Commit 90388b1

Browse files
committed
refactor: Extract and centralize countdown components and date utilities into common modules.
1 parent c4f2197 commit 90388b1

10 files changed

Lines changed: 193 additions & 25 deletions

File tree

src/2023/Home/components/Home/Home.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import { styled } from "styled-components";
2121
import { Color } from "@styles/colors";
2222
import InfoButtons from "../InfoButtons/InfoButtons";
2323
import MultimediaInfoButtons from "../MultimediaInfoButtons/MultimediaInfoButtons";
24-
import CountDownCompleted from "@views/Home/components/Home/components/CountDownCompleted";
25-
import TimeCountDown from "@views/Home/components/Home/components/TimeCountdown";
24+
import {
25+
TimeCountDown,
26+
CountDownCompleted,
27+
} from "@components/common/countdown";
2628
import { BIG_BREAKPOINT, LARGE_BREAKPOINT } from "@constants/BreakPoints";
2729

2830
const StyledLogo = styled.img`

src/2024/Home/Home.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
StyledTopSlash,
1919
StyleHomeContainer,
2020
} from "./Style.Home";
21-
import { formatDateRange } from "./DateUtil";
21+
import { formatDateRange } from "@utils/dateUtils";
2222
import { Link } from "react-router";
2323
import data from "@data/2024.json";
2424
import { SectionWrapper } from "@components/SectionWrapper/SectionWrapper";
@@ -27,8 +27,10 @@ import { Color } from "@styles/colors";
2727
import ActionButtons from "@views/Home/components/ActionButtons/ActionButtons";
2828
import InfoButtons from "@views/Home/components/InfoButtons/InfoButtons";
2929
import { BIGGER_BREAKPOINT } from "@constants/BreakPoints";
30-
import CountDownCompleted from "@views/Home/components/Home/components/CountDownCompleted";
31-
import TimeCountDown from "@views/Home/components/Home/components/TimeCountdown";
30+
import {
31+
TimeCountDown,
32+
CountDownCompleted,
33+
} from "@components/common/countdown";
3234

3335
const Home: FC<React.PropsWithChildren<unknown>> = () => {
3436
const { width } = useWindowSize();

src/2025/Home/components/Home/Home.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import Countdown from "react-countdown";
22
import React, { FC } from "react";
33
import { SectionWrapper } from "@components/SectionWrapper/SectionWrapper";
44
import { BIGGER_BREAKPOINT } from "@constants/BreakPoints";
5-
import TimeCountDown from "@views/Home/components/Home/components/TimeCountdown";
5+
import {
6+
TimeCountDown,
7+
CountDownCompleted,
8+
} from "@components/common/countdown";
69
import { useWindowSize } from "react-use";
710
import { useDateInterval } from "@hooks/useDateInterval";
811
// @ts-expect-error some quirky import
@@ -24,10 +27,9 @@ import {
2427
import ActionButtons from "@views/Home/components/ActionButtons/ActionButtons";
2528
import { Color } from "@styles/colors";
2629
import InfoButtons from "../InfoButtons/InfoButtons";
27-
import { formatDateRange } from "./DateUtil";
30+
import { formatDateRange } from "@utils/dateUtils";
2831
import { Link } from "react-router";
2932
import edition from "@data/2025.json";
30-
import CountDownCompleted from "@views/Home/components/Home/components/CountDownCompleted";
3133

3234
const Home: FC<React.PropsWithChildren<unknown>> = () => {
3335
const { width } = useWindowSize();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { FC } from "react";
2+
import {
3+
StyledTimerContainer,
4+
StyledTimerLetters,
5+
StyleLine,
6+
TimeCountDownContainer,
7+
} from "./countdown.style";
8+
9+
const CountDownCompleted: FC = () => {
10+
return (
11+
<TimeCountDownContainer id="countdown-completed">
12+
<StyledTimerContainer>
13+
<p>0</p>
14+
<StyledTimerLetters>DAYS</StyledTimerLetters>
15+
</StyledTimerContainer>
16+
<StyleLine />
17+
<StyledTimerContainer>
18+
<p>0</p>
19+
<StyledTimerLetters>HOURS</StyledTimerLetters>
20+
</StyledTimerContainer>
21+
<StyleLine />
22+
<StyledTimerContainer>
23+
<p>0</p>
24+
<StyledTimerLetters>MINUTES</StyledTimerLetters>
25+
</StyledTimerContainer>
26+
<StyleLine />
27+
<StyledTimerContainer>
28+
<p>0</p>
29+
<StyledTimerLetters>SECONDS</StyledTimerLetters>
30+
</StyledTimerContainer>
31+
</TimeCountDownContainer>
32+
);
33+
};
34+
35+
export default CountDownCompleted;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { FC } from "react";
2+
import {
3+
StyledTimerContainer,
4+
StyledTimerNumber,
5+
StyledTimerLetters,
6+
StyleLine,
7+
TimeCountDownContainer,
8+
} from "./countdown.style";
9+
10+
interface TimeCountDownProps {
11+
days: number;
12+
hours: number;
13+
minutes: number;
14+
seconds: number;
15+
}
16+
17+
const TimeCountDown: FC<React.PropsWithChildren<TimeCountDownProps>> = ({
18+
days,
19+
hours,
20+
minutes,
21+
seconds,
22+
}) => {
23+
return (
24+
<TimeCountDownContainer id="countdown-ongoing">
25+
<StyledTimerContainer>
26+
<StyledTimerNumber>{days}</StyledTimerNumber>
27+
<StyledTimerLetters>DAYS</StyledTimerLetters>
28+
</StyledTimerContainer>
29+
<StyleLine />
30+
<StyledTimerContainer>
31+
<StyledTimerNumber>{hours}</StyledTimerNumber>
32+
<StyledTimerLetters>HOURS</StyledTimerLetters>
33+
</StyledTimerContainer>
34+
<StyleLine />
35+
<StyledTimerContainer>
36+
<StyledTimerNumber>{minutes}</StyledTimerNumber>
37+
<StyledTimerLetters>MINUTES</StyledTimerLetters>
38+
</StyledTimerContainer>
39+
<StyleLine />
40+
<StyledTimerContainer>
41+
<StyledTimerNumber>{seconds}</StyledTimerNumber>
42+
<StyledTimerLetters>SECONDS</StyledTimerLetters>
43+
</StyledTimerContainer>
44+
</TimeCountDownContainer>
45+
);
46+
};
47+
48+
export default TimeCountDown;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { styled } from "styled-components";
2+
import { Color } from "@styles/colors";
3+
4+
export const TimeCountDownContainer = styled.div`
5+
display: flex;
6+
align-items: center;
7+
padding-top: 1.2rem;
8+
`;
9+
10+
export const StyledTimerContainer = styled.div`
11+
align-items: center;
12+
background-color: rgba(50, 50, 50, 0.5);
13+
border-radius: 3rem;
14+
border: 1.5px solid ${Color.DARK_BLUE};
15+
box-shadow: 1px 1px 1px ${Color.LIGHT_BLUE};
16+
color: white;
17+
display: flex;
18+
flex-direction: column;
19+
font-family: "Square 721 Regular", sans-serif;
20+
font-size: 1.5em;
21+
height: 5rem;
22+
justify-content: center;
23+
width: 5rem;
24+
padding-top: 10px;
25+
`;
26+
27+
export const StyledTimerNumber = styled.p`
28+
color: white;
29+
margin-bottom: 5px;
30+
`;
31+
32+
export const StyleLine = styled.div`
33+
width: 0.75rem;
34+
background: ${Color.DARK_BLUE};
35+
height: 1.5px;
36+
`;
37+
38+
export const StyledTimerLetters = styled.p`
39+
font-size: 0.75rem;
40+
`;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as TimeCountDown } from "./TimeCountdown";
2+
export { default as CountDownCompleted } from "./CountDownCompleted";
3+
export * from "./countdown.style";

src/utils/dateUtils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { format } from "date-fns";
2+
3+
export function formatDateRange(startDate: Date, endDate: Date): string {
4+
const sameMonthAndYear =
5+
startDate.getMonth() === endDate.getMonth() &&
6+
startDate.getFullYear() === endDate.getFullYear();
7+
8+
if (sameMonthAndYear) {
9+
return `${format(startDate, "MMMM do")} - ${format(endDate, "do, yyyy")}`;
10+
} else {
11+
return `${format(startDate, "MMMM do, yyyy")} - ${format(
12+
endDate,
13+
"MMMM do, yyyy",
14+
)}`;
15+
}
16+
}

src/views/Home/components/HomeWTC/HomeWTC.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import Countdown from "react-countdown";
22
import React, { FC } from "react";
33
import { SectionWrapper } from "@components/SectionWrapper/SectionWrapper";
4-
import TimeCountDown from "./components/TimeCountdown";
5-
import { useWindowSize } from "react-use";
4+
import {
5+
TimeCountDown,
6+
CountDownCompleted,
7+
} from "@components/common/countdown";
68
import { useDateInterval } from "@hooks/useDateInterval";
79
// @ts-expect-error some quirky import
810
import { motion } from "motion/react";
@@ -18,13 +20,11 @@ import {
1820
import ActionButtons from "../ActionButtons/ActionButtons";
1921
import { Color } from "@styles/colors";
2022
import InfoButtons from "../InfoButtons/InfoButtons";
21-
import { formatDateRange } from "./DateUtil";
23+
import { formatDateRange } from "@utils/dateUtils";
2224
import { Link } from "react-router";
2325
import edition from "@data/2026.json";
24-
import CountDownCompleted from "./components/CountDownCompleted";
2526

2627
const HomeWTC: FC<React.PropsWithChildren<unknown>> = () => {
27-
useWindowSize();
2828
const { isTicketsDisabled, isSponsorDisabled, isCfpDisabled } =
2929
useDateInterval(new Date(), edition);
3030

@@ -39,7 +39,8 @@ const HomeWTC: FC<React.PropsWithChildren<unknown>> = () => {
3939
>
4040
<StyledDevBcnLogo src="images/logo.png" alt="DevBcn logo" />
4141
</StyledLogoDiv>
42-
<StyledTitleContainer color={Color.TRANSPARENT}
42+
<StyledTitleContainer
43+
color={Color.TRANSPARENT}
4344
initial={{ opacity: 0, y: 50 }}
4445
animate={{ opacity: 1, y: 0 }}
4546
transition={{ duration: 0.6, delay: 0.3 }}
@@ -51,15 +52,17 @@ const HomeWTC: FC<React.PropsWithChildren<unknown>> = () => {
5152
>
5253
The Barcelona Developers Conference {edition?.edition}
5354
</StyledTitle>
54-
<StyledSubtitle fontWeight={600}
55+
<StyledSubtitle
56+
fontWeight={600}
5557
initial={{ opacity: 0 }}
5658
animate={{ opacity: 1 }}
5759
transition={{ duration: 0.5, delay: 0.8 }}
5860
>
5961
{edition?.trackNumber} tracks with the following topics: <br />
6062
{edition?.tracks}
6163
</StyledSubtitle>
62-
<StyledSubtitle shadow={true}
64+
<StyledSubtitle
65+
shadow={true}
6366
initial={{ opacity: 0 }}
6467
animate={{ opacity: 1 }}
6568
transition={{ duration: 0.5, delay: 1 }}

src/views/Home/components/HomeWTC/Style.Home.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,39 @@ interface StyledSubtitleProps {
2222

2323
export const StyledHomeImage = styled.div`
2424
padding: 70px 0 40px;
25-
background-image:
26-
linear-gradient(-45deg, ${Color.LIGHT_BLUE}70, ${Color.MAGENTA}70, ${Color.DARK_BLUE}70, ${Color.GREEN}70),
25+
background-image:
26+
linear-gradient(
27+
-45deg,
28+
${Color.LIGHT_BLUE}70,
29+
${Color.MAGENTA}70,
30+
${Color.DARK_BLUE}70,
31+
${Color.GREEN}70
32+
),
2733
url(${images[Math.floor(Math.random() * images.length)]});
28-
background-size: 400% 400%, cover;
29-
background-position: 0 50%, center;
34+
background-size:
35+
400% 400%,
36+
cover;
37+
background-position:
38+
0 50%,
39+
center;
3040
background-repeat: no-repeat;
3141
animation: gradient 15s ease infinite;
3242
3343
@keyframes gradient {
3444
0% {
35-
background-position: 0 50%, center;
45+
background-position:
46+
0 50%,
47+
center;
3648
}
3749
50% {
38-
background-position: 100% 50%, center;
50+
background-position:
51+
100% 50%,
52+
center;
3953
}
4054
100% {
41-
background-position: 0 50%, center;
55+
background-position:
56+
0 50%,
57+
center;
4258
}
4359
}
4460
`;
@@ -70,12 +86,13 @@ export const StyledTitle = styled(motion.h1)`
7086
font-family: "Square 721 Regular", sans-serif;
7187
`;
7288

73-
export const StyledSubtitle = styled(motion.h2) <StyledSubtitleProps>`
89+
export const StyledSubtitle = styled(motion.h2)<StyledSubtitleProps>`
7490
color: ${(props) => props.color ?? Color.WHITE};
7591
font-family: "DejaVu Sans ExtraLight", sans-serif;
7692
font-size: 1.25rem;
7793
font-weight: ${(props) => props.fontWeight ?? 400};
78-
text-shadow: ${(props) => props.shadow ? '2px 2px 2px rgba(0, 0, 0, 0.5)' : 'none'};
94+
text-shadow: ${(props) =>
95+
props.shadow ? "2px 2px 2px rgba(0, 0, 0, 0.5)" : "none"};
7996
8097
padding: 0.25rem;
8198

0 commit comments

Comments
 (0)