From a9cc155f2a44f3e3a2027ff1bbfaaaf4571b2769 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 5 Feb 2025 15:19:11 +0300 Subject: [PATCH 1/7] website content update feedback --- website2/src/views/about/AboutPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website2/src/views/about/AboutPage.tsx b/website2/src/views/about/AboutPage.tsx index db2874a372..55da3ea15e 100644 --- a/website2/src/views/about/AboutPage.tsx +++ b/website2/src/views/about/AboutPage.tsx @@ -268,7 +268,7 @@ const AboutPage: React.FC = () => { pollution challenges.

- They provide accurate, hyperlocal, and timely data providing + We provide accurate, hyperlocal, and timely data providing evidence of the magnitude and scale of air pollution across the continent.

From 60bd540e2b3855e821addba819708722608f83c7 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Thu, 6 Feb 2025 15:06:44 +0300 Subject: [PATCH 2/7] updates --- .../src/app/clean-air-forum/glossary/page.tsx | 85 +++++++++++++++---- website2/src/app/clean-air-forum/layout.tsx | 59 +++++++++++-- website2/src/store/index.ts | 2 + website2/src/store/slices/forumSlice.ts | 43 ++++++++++ website2/src/views/Forum/AboutPage.tsx | 2 - website2/src/views/Forum/TabNavigation.tsx | 4 +- 6 files changed, 165 insertions(+), 30 deletions(-) create mode 100644 website2/src/store/slices/forumSlice.ts diff --git a/website2/src/app/clean-air-forum/glossary/page.tsx b/website2/src/app/clean-air-forum/glossary/page.tsx index 5c278261dc..8fb9113fca 100644 --- a/website2/src/app/clean-air-forum/glossary/page.tsx +++ b/website2/src/app/clean-air-forum/glossary/page.tsx @@ -1,36 +1,85 @@ 'use client'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; import React from 'react'; import { Divider } from '@/components/ui'; -import { useForumData } from '@/context/ForumDataContext'; +import { useDispatch, useSelector } from '@/hooks/reduxHooks'; +import { selectEvent } from '@/store/slices/forumSlice'; import { renderContent } from '@/utils/quillUtils'; -const Page = () => { - const data = useForumData(); +const Page: React.FC = () => { + const router = useRouter(); + const dispatch = useDispatch(); + // Retrieve forum events and selected event index from Redux. + const { events, selectedEventIndex } = useSelector((state) => state.forum); - if (!data) { + if (events.length === 0) { return null; } + const selectedEvent = events[selectedEventIndex]; + + // Utility function to create a slug from event title. + const createSlug = (title: string) => { + return title.split(',')[0].trim().toLowerCase().replace(/\s+/g, '-'); + }; + return (
- {/* Split Section - Vaccination */} -
-
-
-

- Clear Air Glossary -

-
-
+ {/* Clean Air Forum Events Section */} +
+ {/* Left column: Heading */} +
+

Clean Air Forum Events

+
+ {/* Right column: List of events */} +
+
    + {events.map((event, index) => { + const slug = createSlug(event.title); + const href = `/clean-air-forum?slug=${encodeURIComponent(slug)}`; + return ( +
  • + { + e.preventDefault(); + dispatch(selectEvent(index)); + router.push('/clean-air-forum'); + }} + className={`text-blue-600 hover:underline ${ + selectedEventIndex === index ? 'font-bold' : '' + }`} + > + {event.title} + +
  • + ); + })} +
+
+
+ + + + {/* Clear Air Glossary Section */} +
+ {/* Left column: Heading */} +
+

+ Clear Air Glossary +

+ {/* Right column: Glossary content */} +
); diff --git a/website2/src/app/clean-air-forum/layout.tsx b/website2/src/app/clean-air-forum/layout.tsx index de10122c07..efe2fb8fe3 100644 --- a/website2/src/app/clean-air-forum/layout.tsx +++ b/website2/src/app/clean-air-forum/layout.tsx @@ -1,6 +1,6 @@ 'use client'; - -import React, { ReactNode } from 'react'; +import { useSearchParams } from 'next/navigation'; +import React, { ReactNode, useEffect } from 'react'; import Footer from '@/components/layouts/Footer'; import Navbar from '@/components/layouts/Navbar'; @@ -8,7 +8,9 @@ import NewsLetter from '@/components/layouts/NewsLetter'; import Loading from '@/components/loading'; import mainConfig from '@/configs/mainConfigs'; import { ForumDataProvider } from '@/context/ForumDataContext'; +import { useDispatch, useSelector } from '@/hooks/reduxHooks'; import { useForumEvents } from '@/hooks/useApiHooks'; +import { selectEvent, setEvents } from '@/store/slices/forumSlice'; import BannerSection from '@/views/Forum/BannerSection'; type CleanAirLayoutProps = { @@ -16,19 +18,60 @@ type CleanAirLayoutProps = { }; const CleanAirLayout: React.FC = ({ children }) => { - // Using the `useForumEvents` hook + // Fetch forum events from the API. const { data: forumEvents, isLoading } = useForumEvents(); + const dispatch = useDispatch(); + const searchParams = useSearchParams(); + + // When events are fetched, update the Redux slice. + useEffect(() => { + if (forumEvents && forumEvents.length > 0) { + dispatch(setEvents(forumEvents)); + } + }, [forumEvents, dispatch]); + + // Get the slug query parameter. + const slug = searchParams.get('slug'); + const events = useSelector((state) => state.forum.events); + const selectedEventIndex = useSelector( + (state) => state.forum.selectedEventIndex, + ); - // Extract the first event (if available) - const eventData = forumEvents?.[0] || null; + // Only run the slug-based selection if a slug is provided. + useEffect(() => { + if (slug && events.length > 0) { + // Normalize the slug by replacing hyphens with spaces and lowercasing. + const normalizedSlug = slug.replace(/-/g, ' ').toLowerCase(); + // Find the event whose title (taking the part before a comma) matches. + const index = events.findIndex((event) => { + const cleanTitle = event.title + .split(',')[0] + .trim() + .toLowerCase() + .replace(/-/g, ' '); + return cleanTitle === normalizedSlug; + }); + if (index !== -1 && index !== selectedEventIndex) { + dispatch(selectEvent(index)); + } + // If no slug match is found, you may choose to do nothing + // rather than resetting to index 0. + } + // Note: we do not reset the index if slug is missing. + }, [slug, events, selectedEventIndex, dispatch]); + + const selectedEvent = events[selectedEventIndex]; - // Loading state if (isLoading) { return ; } + if (!selectedEvent) { + return null; + } + return ( - +
{/* Navbar */}
@@ -36,7 +79,7 @@ const CleanAirLayout: React.FC = ({ children }) => {
{/* Banner Section */} - + {/* Main Content */}
diff --git a/website2/src/store/index.ts b/website2/src/store/index.ts index 2413bca4fe..d6f0f77c0d 100644 --- a/website2/src/store/index.ts +++ b/website2/src/store/index.ts @@ -1,12 +1,14 @@ import { configureStore } from '@reduxjs/toolkit'; import countryReducer from './slices/countrySlice'; +import forum from './slices/forumSlice'; import modalReducer from './slices/modalSlice'; const store = configureStore({ reducer: { modal: modalReducer, country: countryReducer, + forum: forum, }, }); diff --git a/website2/src/store/slices/forumSlice.ts b/website2/src/store/slices/forumSlice.ts new file mode 100644 index 0000000000..0bab20935d --- /dev/null +++ b/website2/src/store/slices/forumSlice.ts @@ -0,0 +1,43 @@ +// redux/forumSlice.ts +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +/** Define a minimal ForumEvent type based on your data */ +export interface ForumEvent { + id: number; + title: string; + glossary_details: string; + // Add additional fields as needed (e.g. introduction, banner, etc.) +} + +interface ForumState { + events: ForumEvent[]; + selectedEventIndex: number; + activeTab: string; +} + +const initialState: ForumState = { + events: [], + selectedEventIndex: 0, + activeTab: 'About', +}; + +const forumSlice = createSlice({ + name: 'forum', + initialState, + reducers: { + setEvents: (state, action: PayloadAction) => { + state.events = action.payload; + }, + selectEvent: (state, action: PayloadAction) => { + state.selectedEventIndex = action.payload; + // Reset active tab whenever a new event is selected + state.activeTab = 'About'; + }, + setActiveTab: (state, action: PayloadAction) => { + state.activeTab = action.payload; + }, + }, +}); + +export const { setEvents, selectEvent, setActiveTab } = forumSlice.actions; +export default forumSlice.reducer; diff --git a/website2/src/views/Forum/AboutPage.tsx b/website2/src/views/Forum/AboutPage.tsx index af62adae1f..0746e64330 100644 --- a/website2/src/views/Forum/AboutPage.tsx +++ b/website2/src/views/Forum/AboutPage.tsx @@ -27,8 +27,6 @@ const AboutPage = () => { return ; } - console.info(data); - // Objectives Section: Render each objective as a SectionRow const renderObjectives = () => { const objectives = data?.engagement?.objectives || []; diff --git a/website2/src/views/Forum/TabNavigation.tsx b/website2/src/views/Forum/TabNavigation.tsx index 8eaef6eeef..9756204d8c 100644 --- a/website2/src/views/Forum/TabNavigation.tsx +++ b/website2/src/views/Forum/TabNavigation.tsx @@ -3,10 +3,10 @@ import Link from 'next/link'; import { usePathname } from 'next/navigation'; import React from 'react'; -const TabNavigation = () => { +const TabNavigation: React.FC = () => { const pathname = usePathname(); - // Function to check if the tab is active based on the current pathname + // Function to check if the tab is active based on the current pathname. const isActiveTab = (path: string) => pathname === path; return ( From 1d791911db5e9e70dc763482de2594306d030fbd Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Thu, 6 Feb 2025 16:04:06 +0300 Subject: [PATCH 3/7] updates --- .../src/app/clean-air-forum/partners/page.tsx | 42 +------------- .../src/app/clean-air-forum/schedule/page.tsx | 19 +------ .../app/clean-air-forum/sponsorships/page.tsx | 56 +++++++++++++++++++ website2/src/views/Forum/TabNavigation.tsx | 56 +++++++++---------- 4 files changed, 85 insertions(+), 88 deletions(-) create mode 100644 website2/src/app/clean-air-forum/sponsorships/page.tsx diff --git a/website2/src/app/clean-air-forum/partners/page.tsx b/website2/src/app/clean-air-forum/partners/page.tsx index ceb0eb8c94..579dabcb39 100644 --- a/website2/src/app/clean-air-forum/partners/page.tsx +++ b/website2/src/app/clean-air-forum/partners/page.tsx @@ -29,13 +29,6 @@ const Page = () => { logoUrl: partner.partner_logo_url, })); - const sponsorPartner = data.partners - ?.filter((partner: any) => partner.category === 'Sponsor Partner') - .map((partner: any) => ({ - id: partner.id, - logoUrl: partner.partner_logo_url, - })); - // Filter Funding Partners (if available) const fundingPartners = data.partners ?.filter((partner: any) => partner.category === 'Funding Partner') @@ -46,8 +39,6 @@ const Page = () => { return (
- - {/* Partners Text Section */}

Partners

@@ -58,16 +49,6 @@ const Page = () => { />
- {/* Sponsorship Opportunities Text Section */} -
-

Sponsorship opportunities

-
-
- {/* Convening Partners Section */} {conveningPartners?.length > 0 && ( <> @@ -76,7 +57,7 @@ const Page = () => {

- Convening partners + Convening partners and Collaborators

{ )} - {/* Sponsors Section */} - {sponsorPartner?.length > 0 && ( - <> - -
-
-
-

Sponsors

-
- -
-
- - )} - {/* Funding Partners Section */} {fundingPartners?.length > 0 && ( <> @@ -137,7 +99,7 @@ const Page = () => {

- Funding partners + Funding Partners and Sponsors

{ } return ( -
+
{/* Schedule Section */}

Schedule

@@ -120,23 +120,6 @@ const Page = () => { />
- - - - {/* Sponsorship Section */} -
-
-
-

Sponsorship opportunities

-
-
-
-
); }; diff --git a/website2/src/app/clean-air-forum/sponsorships/page.tsx b/website2/src/app/clean-air-forum/sponsorships/page.tsx new file mode 100644 index 0000000000..c2cc93cbc2 --- /dev/null +++ b/website2/src/app/clean-air-forum/sponsorships/page.tsx @@ -0,0 +1,56 @@ +'use client'; +import React from 'react'; + +import { Divider } from '@/components/ui'; +import { useForumData } from '@/context/ForumDataContext'; +import { renderContent } from '@/utils/quillUtils'; +import PaginatedSection from '@/views/cleanairforum/PaginatedSection'; + +const Page = () => { + const data = useForumData(); + + const sponsorPartner = data.partners + ?.filter((partner: any) => partner.category === 'Sponsor Partner') + .map((partner: any) => ({ + id: partner.id, + logoUrl: partner.partner_logo_url, + })); + + if (!data) { + return null; + } + return ( +
+ {/* Sponsorship Opportunities Text Section */} +
+

Sponsorship opportunities

+
+
+ + {/* Sponsors Section */} + {sponsorPartner?.length > 0 && ( + <> + +
+
+
+

Sponsors

+
+ +
+
+ + )} +
+ ); +}; + +export default Page; diff --git a/website2/src/views/Forum/TabNavigation.tsx b/website2/src/views/Forum/TabNavigation.tsx index 9756204d8c..1ede3b0e71 100644 --- a/website2/src/views/Forum/TabNavigation.tsx +++ b/website2/src/views/Forum/TabNavigation.tsx @@ -9,39 +9,35 @@ const TabNavigation: React.FC = () => { // Function to check if the tab is active based on the current pathname. const isActiveTab = (path: string) => pathname === path; + // Define the tabs list. + const tabs = [ + { href: '/clean-air-forum', text: 'About' }, + { href: '/clean-air-forum/program-committee', text: 'Programme Committee' }, + { href: '/clean-air-forum/schedule', text: 'Schedule & Registration' }, + { href: '/clean-air-forum/speakers', text: 'Speakers' }, + { href: '/clean-air-forum/partners', text: 'Partners' }, + { href: '/clean-air-forum/sponsorships', text: 'Sponsorships' }, + { href: '/clean-air-forum/logistics', text: 'Travel Logistics' }, + { href: '/clean-air-forum/glossary', text: 'Glossary' }, + { href: '/clean-air-forum/resources', text: 'Resources' }, + ]; + return (
-
- {[ - { href: '/clean-air-forum', text: 'About' }, - { - href: '/clean-air-forum/program-committee', - text: 'Programme Committee', - }, - { - href: '/clean-air-forum/schedule', - text: 'Schedule & Registration', - }, - { href: '/clean-air-forum/speakers', text: 'Speakers' }, - { href: '/clean-air-forum/partners', text: 'Partners' }, - { href: '/clean-air-forum/logistics', text: 'Travel Logistics' }, - { href: '/clean-air-forum/glossary', text: 'Glossary' }, - { href: '/clean-air-forum/resources', text: 'Resources' }, - ].map((link, index) => ( - - - {link.text} - {isActiveTab(link.href) && ( - - )} - +
+ {tabs.map((link, index) => ( + + {link.text} + {isActiveTab(link.href) && ( + + )} ))}
From 1575b4172a4367fab595584b0647d75b48d2b919 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Thu, 6 Feb 2025 16:14:02 +0300 Subject: [PATCH 4/7] updates --- .../views/cleanairforum/PaginatedSection.tsx | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/website2/src/views/cleanairforum/PaginatedSection.tsx b/website2/src/views/cleanairforum/PaginatedSection.tsx index e3fd192e57..233638a69f 100644 --- a/website2/src/views/cleanairforum/PaginatedSection.tsx +++ b/website2/src/views/cleanairforum/PaginatedSection.tsx @@ -1,18 +1,21 @@ +'use client'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; -import { ReactNode, useState } from 'react'; +import React, { ReactNode, useState } from 'react'; +import { Pagination } from '@/components/ui'; import mainConfig from '@/configs/mainConfigs'; import { cn } from '@/lib/utils'; -import { Pagination } from '../../components/ui'; - const logosPerPage = 8; type PaginatedSectionProps = { title?: ReactNode; description?: ReactNode; - logos: any[]; + logos: { + id?: number; + logoUrl: string; + }[]; bgColor?: string; sectionClassName?: string; noClick?: boolean; @@ -44,34 +47,35 @@ const PaginatedSection: React.FC = ({
)} -
+ {/* Logo Grid */} +
{paginatedLogos.map((partner, index) => (
!noClick && router.push(`/partners/${partner.id}`) } - className="flex justify-center items-center cursor-pointer overflow-hidden w-full h-[144px] border border-gray-300 px-2 py-4" + className="relative w-[271px] h-[144px] border border-gray-300 cursor-pointer overflow-hidden" > {'logo'}
))}
- {/* Conditional Pagination */} + {/* Pagination */} {logos.length > logosPerPage && (
Date: Thu, 6 Feb 2025 16:16:59 +0300 Subject: [PATCH 5/7] updates --- website2/src/app/clean-air-forum/glossary/page.tsx | 1 + website2/src/views/Forum/TabNavigation.tsx | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/website2/src/app/clean-air-forum/glossary/page.tsx b/website2/src/app/clean-air-forum/glossary/page.tsx index 8fb9113fca..f812841112 100644 --- a/website2/src/app/clean-air-forum/glossary/page.tsx +++ b/website2/src/app/clean-air-forum/glossary/page.tsx @@ -49,6 +49,7 @@ const Page: React.FC = () => { e.preventDefault(); dispatch(selectEvent(index)); router.push('/clean-air-forum'); + window.scrollTo({ top: 0, behavior: 'smooth' }); }} className={`text-blue-600 hover:underline ${ selectedEventIndex === index ? 'font-bold' : '' diff --git a/website2/src/views/Forum/TabNavigation.tsx b/website2/src/views/Forum/TabNavigation.tsx index 1ede3b0e71..c2dcc3365a 100644 --- a/website2/src/views/Forum/TabNavigation.tsx +++ b/website2/src/views/Forum/TabNavigation.tsx @@ -22,6 +22,10 @@ const TabNavigation: React.FC = () => { { href: '/clean-air-forum/resources', text: 'Resources' }, ]; + const handleTabClick = () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }; + return (
@@ -33,6 +37,7 @@ const TabNavigation: React.FC = () => { className={`relative flex-shrink-0 text-gray-700 hover:text-gray-900 transition ${ isActiveTab(link.href) ? 'font-semibold text-gray-900' : '' }`} + onClick={handleTabClick} > {link.text} {isActiveTab(link.href) && ( From 38b1ecff235f7ceb42ea6145018c2aeea9168627 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Thu, 6 Feb 2025 18:32:51 +0300 Subject: [PATCH 6/7] updates --- .../src/app/clean-air-forum/partners/page.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/website2/src/app/clean-air-forum/partners/page.tsx b/website2/src/app/clean-air-forum/partners/page.tsx index 579dabcb39..baa8dc15b7 100644 --- a/website2/src/app/clean-air-forum/partners/page.tsx +++ b/website2/src/app/clean-air-forum/partners/page.tsx @@ -29,6 +29,14 @@ const Page = () => { logoUrl: partner.partner_logo_url, })); + // Filter Program Partners + const programPartners = data.partners + ?.filter((partner: any) => partner.category === 'Program Partner') + .map((partner: any) => ({ + id: partner.id, + logoUrl: partner.partner_logo_url, + })); + // Filter Funding Partners (if available) const fundingPartners = data.partners ?.filter((partner: any) => partner.category === 'Funding Partner') @@ -91,6 +99,27 @@ const Page = () => { )} + {/* */} + {programPartners?.length > 0 && ( + <> + +
+
+
+

+ Program Partners and Exhibitors +

+
+ +
+
+ + )} + {/* Funding Partners Section */} {fundingPartners?.length > 0 && ( <> From 13d70bf734af9c9c63ff77004182ad0f67af151f Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Thu, 6 Feb 2025 18:54:59 +0300 Subject: [PATCH 7/7] updates --- website2/package-lock.json | 115 ++++++++++-------- website2/package.json | 3 +- .../src/app/clean-air-forum/glossary/page.tsx | 5 +- .../app/clean-air-forum/logistics/page.tsx | 9 +- .../src/app/clean-air-forum/partners/page.tsx | 5 +- .../program-committee/page.tsx | 5 +- .../src/app/clean-air-forum/schedule/page.tsx | 7 +- .../src/app/clean-air-forum/speakers/page.tsx | 5 +- .../app/clean-air-forum/sponsorships/page.tsx | 6 +- 9 files changed, 100 insertions(+), 60 deletions(-) diff --git a/website2/package-lock.json b/website2/package-lock.json index 4ea714cac0..79b6b61830 100644 --- a/website2/package-lock.json +++ b/website2/package-lock.json @@ -21,10 +21,11 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "date-fns": "^4.1.0", + "dompurify": "^3.2.4", "framer-motion": "^11.11.1", "glob": "^9.3.5", "lucide-react": "^0.447.0", - "next": "14.2.14", + "next": "^14.2.23", "quill-delta-to-html": "^0.12.1", "react": "^18", "react-dom": "^18", @@ -1648,9 +1649,9 @@ } }, "node_modules/@next/env": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.14.tgz", - "integrity": "sha512-/0hWQfiaD5//LvGNgc8PjvyqV50vGK0cADYzaoOOGN8fxzBn3iAiaq3S0tCRnFBldq0LVveLcxCTi41ZoYgAgg==" + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.23.tgz", + "integrity": "sha512-CysUC9IO+2Bh0omJ3qrb47S8DtsTKbFidGm6ow4gXIG6reZybqxbkH2nhdEm1tC8SmgzDdpq3BIML0PWsmyUYA==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.2.14", @@ -1717,9 +1718,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.14.tgz", - "integrity": "sha512-bsxbSAUodM1cjYeA4o6y7sp9wslvwjSkWw57t8DtC8Zig8aG8V6r+Yc05/9mDzLKcybb6EN85k1rJDnMKBd9Gw==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.23.tgz", + "integrity": "sha512-WhtEntt6NcbABA8ypEoFd3uzq5iAnrl9AnZt9dXdO+PZLACE32z3a3qA5OoV20JrbJfSJ6Sd6EqGZTrlRnGxQQ==", "cpu": [ "arm64" ], @@ -1732,9 +1733,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.14.tgz", - "integrity": "sha512-cC9/I+0+SK5L1k9J8CInahduTVWGMXhQoXFeNvF0uNs3Bt1Ub0Azb8JzTU9vNCr0hnaMqiWu/Z0S1hfKc3+dww==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.23.tgz", + "integrity": "sha512-vwLw0HN2gVclT/ikO6EcE+LcIN+0mddJ53yG4eZd0rXkuEr/RnOaMH8wg/sYl5iz5AYYRo/l6XX7FIo6kwbw1Q==", "cpu": [ "x64" ], @@ -1747,9 +1748,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.14.tgz", - "integrity": "sha512-RMLOdA2NU4O7w1PQ3Z9ft3PxD6Htl4uB2TJpocm+4jcllHySPkFaUIFacQ3Jekcg6w+LBaFvjSPthZHiPmiAUg==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.23.tgz", + "integrity": "sha512-uuAYwD3At2fu5CH1wD7FpP87mnjAv4+DNvLaR9kiIi8DLStWSW304kF09p1EQfhcbUI1Py2vZlBO2VaVqMRtpg==", "cpu": [ "arm64" ], @@ -1762,9 +1763,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.14.tgz", - "integrity": "sha512-WgLOA4hT9EIP7jhlkPnvz49iSOMdZgDJVvbpb8WWzJv5wBD07M2wdJXLkDYIpZmCFfo/wPqFsFR4JS4V9KkQ2A==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.23.tgz", + "integrity": "sha512-Mm5KHd7nGgeJ4EETvVgFuqKOyDh+UMXHXxye6wRRFDr4FdVRI6YTxajoV2aHE8jqC14xeAMVZvLqYqS7isHL+g==", "cpu": [ "arm64" ], @@ -1777,9 +1778,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.14.tgz", - "integrity": "sha512-lbn7svjUps1kmCettV/R9oAvEW+eUI0lo0LJNFOXoQM5NGNxloAyFRNByYeZKL3+1bF5YE0h0irIJfzXBq9Y6w==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.23.tgz", + "integrity": "sha512-Ybfqlyzm4sMSEQO6lDksggAIxnvWSG2cDWnG2jgd+MLbHYn2pvFA8DQ4pT2Vjk3Cwrv+HIg7vXJ8lCiLz79qoQ==", "cpu": [ "x64" ], @@ -1792,9 +1793,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.14.tgz", - "integrity": "sha512-7TcQCvLQ/hKfQRgjxMN4TZ2BRB0P7HwrGAYL+p+m3u3XcKTraUFerVbV3jkNZNwDeQDa8zdxkKkw2els/S5onQ==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.23.tgz", + "integrity": "sha512-OSQX94sxd1gOUz3jhhdocnKsy4/peG8zV1HVaW6DLEbEmRRtUCUQZcKxUD9atLYa3RZA+YJx+WZdOnTkDuNDNA==", "cpu": [ "x64" ], @@ -1807,9 +1808,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.14.tgz", - "integrity": "sha512-8i0Ou5XjTLEje0oj0JiI0Xo9L/93ghFtAUYZ24jARSeTMXLUx8yFIdhS55mTExq5Tj4/dC2fJuaT4e3ySvXU1A==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.23.tgz", + "integrity": "sha512-ezmbgZy++XpIMTcTNd0L4k7+cNI4ET5vMv/oqNfTuSXkZtSA9BURElPFyarjjGtRgZ9/zuKDHoMdZwDZIY3ehQ==", "cpu": [ "arm64" ], @@ -1822,9 +1823,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.14.tgz", - "integrity": "sha512-2u2XcSaDEOj+96eXpyjHjtVPLhkAFw2nlaz83EPeuK4obF+HmtDJHqgR1dZB7Gb6V/d55FL26/lYVd0TwMgcOQ==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.23.tgz", + "integrity": "sha512-zfHZOGguFCqAJ7zldTKg4tJHPJyJCOFhpoJcVxKL9BSUHScVDnMdDuOU1zPPGdOzr/GWxbhYTjyiEgLEpAoFPA==", "cpu": [ "ia32" ], @@ -1837,9 +1838,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.14.tgz", - "integrity": "sha512-MZom+OvZ1NZxuRovKt1ApevjiUJTcU2PmdJKL66xUPaJeRywnbGGRWUlaAOwunD6dX+pm83vj979NTC8QXjGWg==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.23.tgz", + "integrity": "sha512-xCtq5BD553SzOgSZ7UH5LH+OATQihydObTrCTvVzOro8QiWYKdBVwcB2Mn2MLMo6DGW9yH1LSPw7jS7HhgJgjw==", "cpu": [ "x64" ], @@ -3205,6 +3206,12 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "optional": true + }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", @@ -4281,9 +4288,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4539,6 +4546,14 @@ "dev": true, "peer": true }, + "node_modules/dompurify": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz", + "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -7886,9 +7901,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -7909,11 +7924,11 @@ "dev": true }, "node_modules/next": { - "version": "14.2.14", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.14.tgz", - "integrity": "sha512-Q1coZG17MW0Ly5x76shJ4dkC23woLAhhnDnw+DfTc7EpZSGuWrlsZ3bZaO8t6u1Yu8FVfhkqJE+U8GC7E0GLPQ==", + "version": "14.2.23", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.23.tgz", + "integrity": "sha512-mjN3fE6u/tynneLiEg56XnthzuYw+kD7mCujgVqioxyPqbmiotUCGJpIZGS/VaPg3ZDT1tvWxiVyRzeqJFm/kw==", "dependencies": { - "@next/env": "14.2.14", + "@next/env": "14.2.23", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -7928,15 +7943,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.14", - "@next/swc-darwin-x64": "14.2.14", - "@next/swc-linux-arm64-gnu": "14.2.14", - "@next/swc-linux-arm64-musl": "14.2.14", - "@next/swc-linux-x64-gnu": "14.2.14", - "@next/swc-linux-x64-musl": "14.2.14", - "@next/swc-win32-arm64-msvc": "14.2.14", - "@next/swc-win32-ia32-msvc": "14.2.14", - "@next/swc-win32-x64-msvc": "14.2.14" + "@next/swc-darwin-arm64": "14.2.23", + "@next/swc-darwin-x64": "14.2.23", + "@next/swc-linux-arm64-gnu": "14.2.23", + "@next/swc-linux-arm64-musl": "14.2.23", + "@next/swc-linux-x64-gnu": "14.2.23", + "@next/swc-linux-x64-musl": "14.2.23", + "@next/swc-win32-arm64-msvc": "14.2.23", + "@next/swc-win32-ia32-msvc": "14.2.23", + "@next/swc-win32-x64-msvc": "14.2.23" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", diff --git a/website2/package.json b/website2/package.json index 12cfe1f569..c39a16fcd3 100644 --- a/website2/package.json +++ b/website2/package.json @@ -27,10 +27,11 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "date-fns": "^4.1.0", + "dompurify": "^3.2.4", "framer-motion": "^11.11.1", "glob": "^9.3.5", "lucide-react": "^0.447.0", - "next": "14.2.14", + "next": "^14.2.23", "quill-delta-to-html": "^0.12.1", "react": "^18", "react-dom": "^18", diff --git a/website2/src/app/clean-air-forum/glossary/page.tsx b/website2/src/app/clean-air-forum/glossary/page.tsx index f812841112..da53599d51 100644 --- a/website2/src/app/clean-air-forum/glossary/page.tsx +++ b/website2/src/app/clean-air-forum/glossary/page.tsx @@ -1,4 +1,5 @@ 'use client'; +import DOMPurify from 'dompurify'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import React from 'react'; @@ -78,7 +79,9 @@ const Page: React.FC = () => {
diff --git a/website2/src/app/clean-air-forum/logistics/page.tsx b/website2/src/app/clean-air-forum/logistics/page.tsx index 4db91a8225..d6e9e8315c 100644 --- a/website2/src/app/clean-air-forum/logistics/page.tsx +++ b/website2/src/app/clean-air-forum/logistics/page.tsx @@ -1,4 +1,5 @@ 'use client'; +import DOMPurify from 'dompurify'; import React from 'react'; import { Divider } from '@/components/ui'; @@ -24,7 +25,9 @@ const Page = () => {
@@ -43,7 +46,9 @@ const Page = () => {
diff --git a/website2/src/app/clean-air-forum/partners/page.tsx b/website2/src/app/clean-air-forum/partners/page.tsx index baa8dc15b7..388ca63130 100644 --- a/website2/src/app/clean-air-forum/partners/page.tsx +++ b/website2/src/app/clean-air-forum/partners/page.tsx @@ -1,4 +1,5 @@ 'use client'; +import DOMPurify from 'dompurify'; import React from 'react'; import { Divider } from '@/components/ui'; @@ -52,7 +53,9 @@ const Page = () => {

Partners

diff --git a/website2/src/app/clean-air-forum/program-committee/page.tsx b/website2/src/app/clean-air-forum/program-committee/page.tsx index 6ae5799636..671213d60c 100644 --- a/website2/src/app/clean-air-forum/program-committee/page.tsx +++ b/website2/src/app/clean-air-forum/program-committee/page.tsx @@ -1,4 +1,5 @@ 'use client'; +import DOMPurify from 'dompurify'; import React, { useMemo, useState } from 'react'; import { Divider, MemberCard, Pagination } from '@/components/ui/'; @@ -52,7 +53,9 @@ const Page: React.FC = () => {

Program Committee

diff --git a/website2/src/app/clean-air-forum/schedule/page.tsx b/website2/src/app/clean-air-forum/schedule/page.tsx index 5dc779aa4a..51ac6f293a 100644 --- a/website2/src/app/clean-air-forum/schedule/page.tsx +++ b/website2/src/app/clean-air-forum/schedule/page.tsx @@ -1,5 +1,6 @@ 'use client'; import { format } from 'date-fns'; +import DOMPurify from 'dompurify'; import React, { useState } from 'react'; import { FaChevronDown, FaChevronUp } from 'react-icons/fa'; @@ -87,7 +88,7 @@ const Page = () => {

Schedule

@@ -115,7 +116,9 @@ const Page = () => {
diff --git a/website2/src/app/clean-air-forum/speakers/page.tsx b/website2/src/app/clean-air-forum/speakers/page.tsx index 6748aba32e..e5346b5e09 100644 --- a/website2/src/app/clean-air-forum/speakers/page.tsx +++ b/website2/src/app/clean-air-forum/speakers/page.tsx @@ -1,4 +1,5 @@ 'use client'; +import DOMPurify from 'dompurify'; import React, { useState } from 'react'; import { Divider, MemberCard, Pagination } from '@/components/ui/'; @@ -61,7 +62,9 @@ const Page = () => {
diff --git a/website2/src/app/clean-air-forum/sponsorships/page.tsx b/website2/src/app/clean-air-forum/sponsorships/page.tsx index c2cc93cbc2..40f67ba49c 100644 --- a/website2/src/app/clean-air-forum/sponsorships/page.tsx +++ b/website2/src/app/clean-air-forum/sponsorships/page.tsx @@ -1,4 +1,5 @@ 'use client'; +import DOMPurify from 'dompurify'; import React from 'react'; import { Divider } from '@/components/ui'; @@ -24,9 +25,12 @@ const Page = () => { {/* Sponsorship Opportunities Text Section */}

Sponsorship opportunities

+