Skip to content

Commit af4c181

Browse files
authored
refactor: reduce code duplication (#688)
1 parent 373c7ff commit af4c181

File tree

10 files changed

+544
-264
lines changed

10 files changed

+544
-264
lines changed

src/App.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import About from "./views/About/About";
6969
import Travel from "./views/Travel/Travel";
7070
import NotFoundError from "./components/NotFoundError/NotFoundError";
7171
import { Home2023Wrapper } from "./2023/Home/Home2023Wrapper";
72-
import Speakers2023 from "./2023/Speakers/Speakers2023";
72+
import Speakers2023 from "./components/YearSpecific/Speakers/Speakers2023";
7373
import SpeakerDetailContainer2023 from "./2023/SpeakerDetail/SpeakerDetailContainer2023";
7474
import Talks2023 from "./2023/Talks/Talks2023";
7575
import TalkDetailContainer2023 from "./2023/TalkDetail/TalkDetailContainer2023";
@@ -85,14 +85,14 @@ import JobOffers2023 from "./2023/JobOffers/JobOffers2023";
8585
import Sponsorship from "./views/sponsorship/Sponsorship";
8686
import Diversity2023 from "./2023/Diversity/Diversity2023";
8787
import CfpSection from "./views/Cfp/CfpSection";
88-
import { CodeOfConduct } from "./views/CodeOfConduct/CodeOfConduct";
89-
import { Accommodation } from "./views/Travel/Accommodation";
88+
import CodeOfConduct from "./views/CodeOfConduct/CodeOfConduct";
89+
import Accommodation from "./views/Travel/Accommodation";
9090
import Schedule from "./views/Schedule/Schedule";
9191
import Diversity from "./views/Diversity/Diversity";
9292
import LiveView from "./views/Talks/LiveView";
9393
import JobOffers from "./views/JobOffers/JobOffers";
9494
import { HomeWrapper2024 } from "./2024/HomeWrapper2024";
95-
import Speakers2024 from "./2024/Speakers/Speakers2024";
95+
import Speakers2024 from "./components/YearSpecific/Speakers/Speakers2024";
9696
import Talks2024 from "./2024/Talks/Talks2024";
9797
import TalkDetailContainer from "./views/MeetingDetail/TalkDetailContainer";
9898
import SpeakerDetailContainer2024 from "./2024/SpeakerDetail/SpeakerDetailContainer2024";
+18-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { BIG_BREAKPOINT } from "../../constants/BreakPoints";
21
import { NavigationItem } from "./NavigationData";
3-
import { useWindowSize } from "react-use";
42
import { NavMenu, StyledLink, SubLink, SubMenu } from "./Style.Navigation";
53
import { NavLink } from "react-router";
64
import { FC } from "react";
@@ -14,30 +12,25 @@ export const HorizontalMenu: FC<React.PropsWithChildren<Props>> = ({
1412
navItems,
1513
subMenuItems,
1614
}) => {
17-
const { width } = useWindowSize();
1815
return (
19-
<>
20-
{width > BIG_BREAKPOINT && (
21-
<div className="horizontal-navigation">
22-
{navItems.map((item) => (
23-
<StyledLink key={item.id} to={item.link}>
24-
{item.id}
25-
</StyledLink>
26-
))}
27-
{subMenuItems.length > 0 && (
28-
<NavMenu style={{ position: "relative" }}>
29-
News{" "}
30-
<SubMenu>
31-
{subMenuItems.map((item) => (
32-
<SubLink key={item.id}>
33-
<NavLink to={item.link}>{item.id}</NavLink>
34-
</SubLink>
35-
))}
36-
</SubMenu>
37-
</NavMenu>
38-
)}
39-
</div>
16+
<div className="horizontal-navigation">
17+
{navItems.map((item) => (
18+
<StyledLink key={item.id} to={item.link}>
19+
{item.id}
20+
</StyledLink>
21+
))}
22+
{subMenuItems.length > 0 && (
23+
<NavMenu style={{ position: "relative" }}>
24+
News{" "}
25+
<SubMenu>
26+
{subMenuItems.map((item) => (
27+
<SubLink key={item.id}>
28+
<NavLink to={item.link}>{item.id}</NavLink>
29+
</SubLink>
30+
))}
31+
</SubMenu>
32+
</NavMenu>
4033
)}
41-
</>
34+
</div>
4235
);
4336
};
+142-143
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,165 @@
1-
import {AnimatePresence} from "framer-motion";
2-
import {FC, useEffect, useState} from "react";
3-
import {MOBILE_BREAKPOINT} from "../../constants/BreakPoints";
4-
import {useLocation, useNavigate} from "react-router";
1+
import { AnimatePresence } from "framer-motion";
2+
import { FC, useEffect, useState } from "react";
3+
import { BIG_BREAKPOINT, MOBILE_BREAKPOINT } from "../../constants/BreakPoints";
4+
import { useLocation, useNavigate } from "react-router";
55
import Breadcrumbs from "./Breadcrumbs";
66
import CloseIcon from "../../assets/images/CloseIcon.svg";
77
import NavigationLogo from "../../assets/images/devBcn.png";
8-
import {ROUTE_HOME, ROUTE_HOME_ALTERNATE} from "../../constants/routes";
8+
import { ROUTE_HOME, ROUTE_HOME_ALTERNATE } from "../../constants/routes";
99
import TicketsImage from "../../assets/images/TicketsImage.svg";
10-
import {navigationItems2025, subMenuItems2025} from "./NavigationData";
10+
import { navigationItems2025, subMenuItems2025 } from "./NavigationData";
1111
import {
12-
navigationItems2023,
13-
subMenuItems2023,
12+
navigationItems2023,
13+
subMenuItems2023,
1414
} from "../../2023/Navigation/NavigationData2023";
15-
import {useWindowSize} from "react-use";
15+
import { useWindowSize } from "react-use";
1616
import {
17-
StyledClipPath,
18-
StyledHeader,
19-
StyledHeaderLogo,
20-
StyledHeaderWrapper,
21-
StyledLink,
22-
StyledMenuIcon,
23-
StyledNavigation,
24-
StyledNavigationContainer,
25-
StyledNavigationLogo,
26-
StyledNavLinkHighlightedImage,
27-
StyledTicketLink,
17+
StyledClipPath,
18+
StyledHeader,
19+
StyledHeaderLogo,
20+
StyledHeaderWrapper,
21+
StyledLink,
22+
StyledMenuIcon,
23+
StyledNavigation,
24+
StyledNavigationContainer,
25+
StyledNavigationLogo,
26+
StyledNavLinkHighlightedImage,
27+
StyledTicketLink,
2828
} from "./Style.Navigation";
29-
import {HorizontalMenu} from "./HorizontalMenu";
30-
import {HamburgerMenu} from "./HamburgerMenu";
29+
import { HorizontalMenu } from "./HorizontalMenu";
30+
import { HamburgerMenu } from "./HamburgerMenu";
3131
import {
32-
navigationItems2024,
33-
subMenuItems2024
32+
navigationItems2024,
33+
subMenuItems2024,
3434
} from "../../2024/Navigation/NavigationData";
3535

3636
const Navigation: FC<React.PropsWithChildren<unknown>> = () => {
37-
const {width} = useWindowSize();
38-
const [isOpened, setIsOpened] = useState(false);
39-
const [navItems, setNavItems] = useState(navigationItems2025);
40-
const [subNavItems, setSubNavItems] = useState(subMenuItems2025);
41-
const {pathname} = useLocation();
42-
const navigate = useNavigate();
43-
const handleLogoClick = () => {
44-
navigate(ROUTE_HOME);
45-
};
46-
const handleSetMenu = () => {
47-
setIsOpened(!isOpened);
48-
};
49-
const isHomePage = () => {
50-
return pathname === ROUTE_HOME || pathname === ROUTE_HOME_ALTERNATE;
51-
};
37+
const { width } = useWindowSize();
38+
const [isOpened, setIsOpened] = useState(false);
39+
const [navItems, setNavItems] = useState(navigationItems2025);
40+
const [subNavItems, setSubNavItems] = useState(subMenuItems2025);
41+
const { pathname } = useLocation();
42+
const navigate = useNavigate();
43+
const handleLogoClick = () => {
44+
navigate(ROUTE_HOME);
45+
};
46+
const handleSetMenu = () => {
47+
setIsOpened(!isOpened);
48+
};
49+
const isHomePage = () => {
50+
return pathname === ROUTE_HOME || pathname === ROUTE_HOME_ALTERNATE;
51+
};
5252

53-
useEffect(() => {
54-
const navMapping = {
55-
"/2024": {
56-
navItems: navigationItems2024,
57-
subNavItems: subMenuItems2024
58-
},
59-
"/2023": {
60-
navItems: navigationItems2023,
61-
subNavItems: subMenuItems2023
62-
},
63-
default: {
64-
navItems: navigationItems2025,
65-
subNavItems: subMenuItems2025
66-
},
67-
};
68-
69-
const {
70-
navItems,
71-
subNavItems
72-
} = Object.entries(navMapping).find(([key]) => pathname.startsWith(key))?.[1] || navMapping.default;
53+
useEffect(() => {
54+
const navMapping = {
55+
"/2024": {
56+
navItems: navigationItems2024,
57+
subNavItems: subMenuItems2024,
58+
},
59+
"/2023": {
60+
navItems: navigationItems2023,
61+
subNavItems: subMenuItems2023,
62+
},
63+
default: {
64+
navItems: navigationItems2025,
65+
subNavItems: subMenuItems2025,
66+
},
67+
};
7368

74-
setNavItems(navItems);
75-
setSubNavItems(subNavItems);
76-
}, [pathname]);
69+
const { navItems, subNavItems } =
70+
Object.entries(navMapping).find(([key]) =>
71+
pathname.startsWith(key),
72+
)?.[1] || navMapping.default;
7773

74+
setNavItems(navItems);
75+
setSubNavItems(subNavItems);
76+
}, [pathname]);
7877

79-
const getTicketURL = (): string => {
80-
if (pathname.startsWith("/2023")) {
81-
return "https://tickets.devbcn.com/event/devbcn-2023";
82-
}
83-
if (pathname.startsWith("/2024")) {
84-
return "https://tickets.devbcn.com/event/devbcn-2024";
85-
}
86-
return "https://tickets.devbcn.com/event/devbcn-2025";
78+
const getTicketURL = (): string => {
79+
if (pathname.startsWith("/2023")) {
80+
return "https://tickets.devbcn.com/event/devbcn-2023";
81+
}
82+
if (pathname.startsWith("/2024")) {
83+
return "https://tickets.devbcn.com/event/devbcn-2024";
8784
}
85+
return "https://tickets.devbcn.com/event/devbcn-2025";
86+
};
8887

89-
return (
90-
<>
91-
<StyledHeaderWrapper>
92-
<StyledHeader>
93-
<StyledHeaderLogo
94-
alt="DevBcn — logo"
95-
src={NavigationLogo}
96-
onClick={handleLogoClick}
97-
/>
98-
<HorizontalMenu navItems={navItems}
99-
subMenuItems={subNavItems}/>
100-
<HamburgerMenu onClick={handleSetMenu}/>
101-
</StyledHeader>
88+
return (
89+
<>
90+
<StyledHeaderWrapper>
91+
<StyledHeader>
92+
<StyledHeaderLogo
93+
alt="DevBcn — logo"
94+
src={NavigationLogo}
95+
onClick={handleLogoClick}
96+
/>
97+
{width > BIG_BREAKPOINT && (
98+
<HorizontalMenu navItems={navItems} subMenuItems={subNavItems} />
99+
)}
100+
<HamburgerMenu onClick={handleSetMenu} />
101+
</StyledHeader>
102102

103-
{!isHomePage() && <Breadcrumbs/>}
104-
</StyledHeaderWrapper>
105-
<AnimatePresence>
106-
{isOpened && (
107-
<StyledNavigationContainer
108-
transition={{duration: 0.5, ease: "easeIn"}}
109-
initial={{width: 0}}
110-
animate={
111-
width > MOBILE_BREAKPOINT
112-
? {width: "140vw"}
113-
: {width: "100vw"}
114-
}
115-
exit={{width: 0}}
116-
>
117-
<StyledNavigation>
118-
<StyledMenuIcon
119-
src={CloseIcon}
120-
onClick={handleSetMenu}
121-
whileTap={{scale: 0.8}}
122-
/>
123-
<StyledNavigationLogo
124-
src={NavigationLogo}
125-
onClick={() => {
126-
navigate(ROUTE_HOME);
127-
handleSetMenu();
128-
}}
129-
/>
130-
{navItems.map((item) => (
131-
<StyledLink
132-
key={item.id}
133-
to={item.link}
134-
onClick={handleSetMenu}
135-
>
136-
{item.id}
137-
</StyledLink>
138-
))}
139-
{subNavItems.map((item) => (
140-
<StyledLink
141-
key={item.id}
142-
to={item.link}
143-
onClick={handleSetMenu}
144-
>
145-
{item.id}
146-
</StyledLink>
147-
))}
103+
{!isHomePage() && <Breadcrumbs />}
104+
</StyledHeaderWrapper>
105+
<AnimatePresence>
106+
{isOpened && (
107+
<StyledNavigationContainer
108+
transition={{ duration: 0.5, ease: "easeIn" }}
109+
initial={{ width: 0 }}
110+
animate={
111+
width > MOBILE_BREAKPOINT
112+
? { width: "140vw" }
113+
: { width: "100vw" }
114+
}
115+
exit={{ width: 0 }}
116+
>
117+
<StyledNavigation>
118+
<StyledMenuIcon
119+
src={CloseIcon}
120+
onClick={handleSetMenu}
121+
whileTap={{ scale: 0.8 }}
122+
/>
123+
<StyledNavigationLogo
124+
src={NavigationLogo}
125+
onClick={() => {
126+
navigate(ROUTE_HOME);
127+
handleSetMenu();
128+
}}
129+
/>
130+
{navItems.map((item) => (
131+
<StyledLink
132+
key={item.id}
133+
to={item.link}
134+
onClick={handleSetMenu}
135+
>
136+
{item.id}
137+
</StyledLink>
138+
))}
139+
{subNavItems.map((item) => (
140+
<StyledLink
141+
key={item.id}
142+
to={item.link}
143+
onClick={handleSetMenu}
144+
>
145+
{item.id}
146+
</StyledLink>
147+
))}
148148

149-
<StyledTicketLink
150-
href={getTicketURL()}
151-
target="_blank"
152-
rel="noreferrer"
153-
>
154-
<StyledNavLinkHighlightedImage
155-
src={TicketsImage}/>
156-
</StyledTicketLink>
157-
</StyledNavigation>
158-
{width > MOBILE_BREAKPOINT && <StyledClipPath/>}
159-
</StyledNavigationContainer>
160-
)}
161-
</AnimatePresence>
162-
</>
163-
);
149+
<StyledTicketLink
150+
href={getTicketURL()}
151+
target="_blank"
152+
rel="noreferrer"
153+
>
154+
<StyledNavLinkHighlightedImage src={TicketsImage} />
155+
</StyledTicketLink>
156+
</StyledNavigation>
157+
{width > MOBILE_BREAKPOINT && <StyledClipPath />}
158+
</StyledNavigationContainer>
159+
)}
160+
</AnimatePresence>
161+
</>
162+
);
164163
};
165164

166165
export default Navigation;

0 commit comments

Comments
 (0)