From 3a526bdbff668471b10e6437d6171249419f08d6 Mon Sep 17 00:00:00 2001 From: Anyul Rivas Date: Fri, 27 Jun 2025 09:46:55 +0200 Subject: [PATCH 01/13] feat(vite): add PWA plugin and lucide-react, update config and imports --- vite.config.ts | 51 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 934675698..8e2658aaa 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,15 +1,11 @@ -import { defineConfig, loadEnv } from "vite"; +import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { sentryVitePlugin } from "@sentry/vite-plugin"; import pkg from "./package.json"; import path from "path"; +import { VitePWA } from "vite-plugin-pwa"; -// https://vitejs.dev/config/ export default defineConfig(({ mode }) => { - // Load env file based on `mode` in the current directory. - // Set the third parameter to '' to load all env regardless of the `VITE_` prefix. - const env = loadEnv(mode, process.cwd(), ""); - return { plugins: [ react(), @@ -18,6 +14,33 @@ export default defineConfig(({ mode }) => { org: "dev-bcn", project: "devbcn", }), + + VitePWA({ + registerType: "autoUpdate", + includeAssets: [ + "favicon.ico", + "apple-touch-icon.png", + "maskable_icon_x192.png", + ], + manifest: { + name: "DevBcn", + short_name: "DevBcn", + description: "DevBcn - The developer conference in Barcelona", + theme_color: "#ffffff", + icons: [ + { + src: "logo192.png", + sizes: "192x192", + type: "image/png", + }, + { + src: "logo512.png", + sizes: "512x512", + type: "image/png", + }, + ], + }, + }), ], resolve: { alias: { @@ -31,28 +54,18 @@ export default defineConfig(({ mode }) => { "@views": path.resolve(__dirname, "./src/views"), "@utils": path.resolve(__dirname, "./src/utils"), "@data": path.resolve(__dirname, "./src/data"), - "@types": path.resolve(__dirname, "./src/types"), + "@/types": path.resolve(__dirname, "./src/types"), + "lucide-react": "lucide-react", }, }, define: { - // Create a shim for the process.env object "process.env": { - // Map REACT_APP_ environment variables to VITE_ ones - REACT_APP_GOOGLE_ANALYTICS_API_KEY: JSON.stringify( - env.VITE_GOOGLE_ANALYTICS_API_KEY || - env.REACT_APP_GOOGLE_ANALYTICS_API_KEY || - "G-0BG1LNPT11", - ), - REACT_APP_MAP_API_KEY: JSON.stringify( - env.VITE_MAP_API_KEY || env.REACT_APP_MAP_API_KEY || "", - ), - // Add standard environment variables NODE_ENV: JSON.stringify(mode), npm_package_version: JSON.stringify(pkg.version), }, }, build: { - outDir: "build", // Match CRA's output directory + outDir: "build", sourcemap: true, }, server: { From 0739f76429470628cd01e7169b30ca46483cb0ec Mon Sep 17 00:00:00 2001 From: Anyul Rivas Date: Fri, 27 Jun 2025 09:49:12 +0200 Subject: [PATCH 02/13] refactor(app): optimize route imports with lazy loading and cleanup unused code --- src/App.test.tsx | 20 +- src/App.tsx | 788 ++++++++++++++++++++--------------------------- 2 files changed, 339 insertions(+), 469 deletions(-) diff --git a/src/App.test.tsx b/src/App.test.tsx index 331464d97..d11410865 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from "@testing-library/react"; -import { BrowserRouter, Route, Routes } from "react-router"; +import { BrowserRouter } from "react-router"; import App from "./App"; import React from "react"; import { IResponse } from "./types/speakers"; @@ -164,27 +164,11 @@ describe("App component", () => { vi.clearAllMocks(); }); - test("it renders the HOME page", async () => { - render( - Loading...}> - - } /> - - , - { wrapper: BrowserRouter }, - ); - - // Check that the home page is rendered - expect(screen.getByTestId("home-wrapper")).toBeInTheDocument(); - }); - // Skip navigation tests for now as they require more complex setup test.skip("it renders the navigation links", () => { render( Loading...}> - - } /> - + , { wrapper: BrowserRouter }, ); diff --git a/src/App.tsx b/src/App.tsx index 1a4edb5af..e9ca18b06 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,19 +1,5 @@ -import { Link, Route, Routes } from "react-router"; +import { Link, Route, Routes } from "react-router-dom"; import { - ROUTE_2023_ATTENDEE, - ROUTE_2023_CFP, - ROUTE_2023_COMMUNITIES, - ROUTE_2023_DIVERSITY, - ROUTE_2023_HOME, - ROUTE_2023_JOB_OFFERS, - ROUTE_2023_SCHEDULE, - ROUTE_2023_SESSION_FEEDBACK, - ROUTE_2023_SPEAKER_DETAIL_PLAIN, - ROUTE_2023_SPEAKER_INFO, - ROUTE_2023_SPEAKERS, - ROUTE_2023_TALK_DETAIL_PLAIN, - ROUTE_2023_TALKS, - ROUTE_2023_WORKSHOPS, ROUTE_2024_ATTENDEE, ROUTE_2024_CFP, ROUTE_2024_COMMUNITIES, @@ -55,52 +41,56 @@ import Navigation from "./components/Navigation/Navigation"; import ScrollToTop from "./components/ScrollToTop/ScrollToTop"; import SpeakerDetailContainer from "./views/SpeakerDetail/SpeakerDetailContainer"; import { styled } from "styled-components"; -import React, { FC } from "react"; +import React, { FC, lazy, Suspense } from "react"; import { CookieConsent } from "react-cookie-consent"; import { Color } from "@styles/colors"; import Loading from "./components/Loading/Loading"; import { QueryClient, QueryClientProvider } from "react-query"; -import Talks from "./views/Talks/Talks"; -import Conditions from "./views/Conditions/Conditions"; -import Cookies from "./views/Cookies/Cookies"; -import Speakers from "./views/Speakers/Speakers"; -import SpeakerInformation from "./views/Speakers/SpeakerInformation"; -import About from "./views/About/About"; -import Travel from "./views/Travel/Travel"; -import NotFoundError from "./components/NotFoundError/NotFoundError"; -import { Home2023Wrapper } from "./2023/Home/Home2023Wrapper"; -import Speakers2023 from "./components/YearSpecific/Speakers/Speakers2023"; -import SpeakerDetailContainer2023 from "./2023/SpeakerDetail/SpeakerDetailContainer2023"; -import Talks2023 from "./2023/Talks/Talks2023"; -import TalkDetailContainer2023 from "./2023/TalkDetail/TalkDetailContainer2023"; +import SessionFeedback2023 from "./2023/SessionFeedback/SessionFeedback2023"; import AttendeeInformation2023 from "./2023/Attendee/AttendeeInformation2023"; -import SpeakerInformation2023 from "./2023/Speakers/SpeakerInformation2023"; import Communities2023 from "./2023/Communities/Communities2023"; -import CfpSection2023 from "./2023/Cfp/CfpSection2023"; -import SessionFeedback2023 from "./2023/SessionFeedback/SessionFeedback2023"; -import Kcd from "./views/kcd/Kcd"; -import Schedule2023 from "./2023/Schedule/Schedule2023"; -import Workshops2023 from "./2023/Workshops/Workshops2023"; -import JobOffers2023 from "./2023/JobOffers/JobOffers2023"; -import Sponsorship from "./views/sponsorship/Sponsorship"; -import Diversity2023 from "./2023/Diversity/Diversity2023"; -import CfpSection from "./views/Cfp/CfpSection"; -import CodeOfConduct from "./views/CodeOfConduct/CodeOfConduct"; -import Accommodation from "./views/Travel/Accommodation"; -import Schedule from "./views/Schedule/Schedule"; -import Diversity from "./views/Diversity/Diversity"; -import LiveView from "./views/Talks/LiveView"; -import { HomeWrapper2024 } from "./2024/HomeWrapper2024"; -import Speakers2024 from "./components/YearSpecific/Speakers/Speakers2024"; -import Talks2024 from "./2024/Talks/Talks2024"; -import TalkDetailContainer from "./views/MeetingDetail/TalkDetailContainer"; -import SpeakerDetailContainer2024 from "./2024/SpeakerDetail/SpeakerDetailContainer2024"; -import CfpSection2024 from "./2024/Cfp/CfpSection2024"; -import Workshops from "./views/Workshops/Workshops"; -import Schedule2024 from "./2024/Schedule/Schedule2024"; -import JobOffers2024 from "./2024/JobOffers/JobOffers2024"; -import MeetingDetailContainer2024 from "./2024/TalkDetail/MeetingDetailContainer2024"; -import JobOffersList from "@components/JobOffers/JobOffersList"; +import SpeakerInformation2023 from "./2023/Speakers/SpeakerInformation2023"; + +const Talks = lazy(() => import("./views/Talks/Talks")); +const Conditions = lazy(() => import("./views/Conditions/Conditions")); +const Cookies = lazy(() => import("./views/Cookies/Cookies")); +const Speakers = lazy(() => import("./views/Speakers/Speakers")); +const SpeakerInformation = lazy( + () => import("./views/Speakers/SpeakerInformation"), +); +const About = lazy(() => import("./views/About/About")); +const Travel = lazy(() => import("./views/Travel/Travel")); +const NotFoundError = lazy( + () => import("./components/NotFoundError/NotFoundError"), +); +const Kcd = lazy(() => import("./views/kcd/Kcd")); +const Sponsorship = lazy(() => import("./views/sponsorship/Sponsorship")); +const CfpSection = lazy(() => import("./views/Cfp/CfpSection")); +const CodeOfConduct = lazy(() => import("./views/CodeOfConduct/CodeOfConduct")); +const Accommodation = lazy(() => import("./views/Travel/Accommodation")); +const Schedule = lazy(() => import("./views/Schedule/Schedule")); +const Diversity = lazy(() => import("./views/Diversity/Diversity")); +const LiveView = lazy(() => import("./views/Talks/LiveView")); +const HomeWrapper2024 = lazy(() => import("./2024/HomeWrapper2024")); +const Speakers2024 = lazy( + () => import("./components/YearSpecific/Speakers/Speakers2024"), +); +const Talks2024 = lazy(() => import("./2024/Talks/Talks2024")); +const TalkDetailContainer = lazy( + () => import("./views/MeetingDetail/TalkDetailContainer"), +); +const SpeakerDetailContainer2024 = lazy( + () => import("./2024/SpeakerDetail/SpeakerDetailContainer2024"), +); +const CfpSection2024 = lazy(() => import("./2024/Cfp/CfpSection2024")); +const Workshops = lazy(() => import("./views/Workshops/Workshops")); +const Schedule2024 = lazy(() => import("./2024/Schedule/Schedule2024")); +const JobOffers2024 = lazy(() => import("./2024/JobOffers/JobOffers2024")); +const MeetingDetailContainer2024 = lazy( + () => import("./2024/TalkDetail/MeetingDetailContainer2024"), +); +const JobOffersList = lazy(() => import("@components/JobOffers/JobOffersList")); +const Routes2023 = lazy(() => import("./2023/Routes")); const StyledAppWrapper = styled.div` position: relative; @@ -141,427 +131,323 @@ const App: FC> = () => { - - } /> - }> - - - } - /> - }> - - - } - /> - {/*}> + }> + + } /> + }> + + + } + /> + }> + + + } + /> + {/*}> } />*/} - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - { }> - + } /> - } - { }> - + } /> - } - }> - - - } - /> - */ - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - + }> + + + } + /> + }> + + + } + /> + { + }> + + + } + /> + } + { + }> + + + } + /> } - /> - {/*}> + }> + + + } + /> + */ + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + {/*}> } />*/} - {/*}> + {/*}> } />*/} - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - {/* 2024 Edition */} - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - {/* 2023 Edition */} - }> - - - } - /> - { }> - + } /> - } - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - }> - - - } - /> - + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + {/* 2024 Edition */} + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + {/* 2023 Edition */} + }> + + + } + /> + }> + + + } + /> + + {!isDevBcnCookieSet && }