-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Website: Include site manifest files and fix on clean air forum sessions #2539
Changes from 8 commits
4021068
6d2b5a3
7d82e0a
981015a
a3d476a
35d78fc
c163d19
ac280dd
53b9560
9ebacc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon1.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon2.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon3.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon4.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon5.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon6.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon6.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// components/icons/Icon6.tsx | ||
|
||
import React from 'react'; | ||
|
||
interface IconProps { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "AirQo Website", | ||
"short_name": "AirQo", | ||
"icons": [ | ||
{ | ||
"src": "/web-app-manifest-192x192.png", | ||
"sizes": "192x192", | ||
"type": "image/png", | ||
"purpose": "maskable" | ||
}, | ||
{ | ||
"src": "/web-app-manifest-512x512.png", | ||
"sizes": "512x512", | ||
"type": "image/png", | ||
"purpose": "maskable" | ||
} | ||
], | ||
"theme_color": "#ffffff", | ||
"background_color": "#ffffff", | ||
"display": "standalone" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,19 @@ | ||
import React from 'react'; | ||
import { Metadata } from 'next'; | ||
|
||
import AboutPage from '@/views/Forum/AboutPage'; | ||
import AboutPage from '@/views/cleanAirForum/about/AboutPage'; | ||
|
||
const page = () => { | ||
export const metadata: Metadata = { | ||
title: 'About Clean Air Forum | AirQo', | ||
description: | ||
'Discover the Clean Air Forum – learn about our mission, vision, and how we foster collaboration to advance clean air solutions and improve air quality.', | ||
}; | ||
|
||
const Page = () => { | ||
return ( | ||
<div> | ||
<AboutPage /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default page; | ||
export default Page; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,115 +1,15 @@ | ||
'use client'; | ||
import { Metadata } from 'next'; | ||
|
||
import DOMPurify from 'dompurify'; | ||
import Link from 'next/link'; | ||
import React from 'react'; | ||
import GlossaryPage from '@/views/cleanAirForum/glossary/GlossaryPage'; | ||
|
||
import Loading from '@/components/loading'; | ||
import { Divider } from '@/components/ui'; | ||
import { NoData } from '@/components/ui'; | ||
import { useForumData } from '@/context/ForumDataContext'; | ||
import { ForumEvent } from '@/types/forum'; | ||
import { isValidGlossaryContent } from '@/utils/glossaryValidator'; | ||
import { renderContent } from '@/utils/quillUtils'; | ||
import SectionDisplay from '@/views/Forum/SectionDisplay'; | ||
|
||
const GlossaryPage: React.FC = () => { | ||
// Access data from the context. | ||
const { selectedEvent, eventTitles } = useForumData(); | ||
|
||
// If either is not available, show a loading state. | ||
if (!selectedEvent || !eventTitles) { | ||
return <Loading />; | ||
} | ||
|
||
// Extract the events list from eventTitles. | ||
// If eventTitles is an array, use it directly; otherwise, assume it's a ForumTitlesResponse. | ||
const eventsList: ForumEvent[] = Array.isArray(eventTitles) | ||
? eventTitles | ||
: eventTitles.forum_events; | ||
|
||
if (eventsList.length === 0) { | ||
return <NoData message="No events found" />; | ||
} | ||
|
||
// Render the main glossary content using the selected event. | ||
const glossaryHTML = renderContent(selectedEvent.glossary_details); | ||
const showGlossaryMain = isValidGlossaryContent(glossaryHTML); | ||
|
||
const glossarySections = selectedEvent.sections?.filter((section: any) => { | ||
if (!section.pages.includes('glossary')) return false; | ||
const html = renderContent(section.content); | ||
return html.trim().length > 0; | ||
}); | ||
|
||
return ( | ||
<div className="px-4 lg:px-0 prose max-w-none flex flex-col gap-6"> | ||
<Divider className="bg-black p-0 m-0 h-[1px] w-full" /> | ||
|
||
{/* Clean Air Forum Events Section (Sidebar) */} | ||
<div className="flex flex-col md:flex-row py-6 md:space-x-8"> | ||
{/* Left column: Heading */} | ||
<div className="md:w-1/3 mb-4 md:mb-0"> | ||
<h1 className="text-2xl mt-4 font-semibold"> | ||
Clean Air Forum Events | ||
</h1> | ||
</div> | ||
{/* Right column: List of event links */} | ||
<div className="md:w-2/3"> | ||
<ul className="space-y-2"> | ||
{eventsList.map((event) => { | ||
// Use the unique_title directly in the link. | ||
const href = `/clean-air-forum/about?slug=${encodeURIComponent( | ||
event.unique_title, | ||
)}`; | ||
return ( | ||
<li key={event.id}> | ||
<Link | ||
href={href} | ||
target="_blank" | ||
className="text-blue-600 hover:underline" | ||
> | ||
{event.title} | ||
</Link> | ||
</li> | ||
); | ||
})} | ||
</ul> | ||
</div> | ||
</div> | ||
|
||
{/* Clean Air Glossary Section */} | ||
{showGlossaryMain && ( | ||
<> | ||
<Divider className="bg-black p-0 m-0 h-[1px] w-full" /> | ||
<div className="flex flex-col py-6 md:flex-row md:space-x-8"> | ||
{/* Left column: Heading */} | ||
<div className="md:w-1/3 mb-4 md:mb-0"> | ||
<h1 className="text-2xl mt-4 font-bold text-gray-900"> | ||
Clean Air Glossary | ||
</h1> | ||
</div> | ||
{/* Right column: Glossary content */} | ||
<div | ||
className="md:w-2/3" | ||
dangerouslySetInnerHTML={{ | ||
__html: DOMPurify.sanitize(glossaryHTML), | ||
}} | ||
></div> | ||
</div> | ||
</> | ||
)} | ||
export const metadata: Metadata = { | ||
title: 'Glossary | Clean Air Forum', | ||
description: | ||
'Explore our glossary of key terms and pollutant types used at Clean Air Forum, providing clear definitions to help you better understand air quality management.', | ||
}; | ||
|
||
{/* Additional Glossary Sections (if any) */} | ||
{glossarySections && glossarySections.length > 0 && ( | ||
<> | ||
{glossarySections.map((section: any) => ( | ||
<SectionDisplay key={section.id} section={section} /> | ||
))} | ||
</> | ||
)} | ||
</div> | ||
); | ||
const Page = () => { | ||
return <GlossaryPage />; | ||
}; | ||
|
||
export default GlossaryPage; | ||
export default Page; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,96 +1,15 @@ | ||||||
'use client'; | ||||||
import { Metadata } from 'next'; | ||||||
|
||||||
import DOMPurify from 'dompurify'; | ||||||
import React from 'react'; | ||||||
import LogisticsPage from '@/views/cleanAirForum/logistics/LogisticsPage'; | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the import path for LogisticsPage component. The build pipeline is failing because it cannot find the LogisticsPage component. There appears to be a case sensitivity issue in the import path. -import LogisticsPage from '@/views/cleanAirForum/logistics/LogisticsPage';
+import LogisticsPage from '@/views/cleanairforum/logistics/LogisticsPage'; Note: Ensure that the component actually exists at this path. If it doesn't, you'll need to create it first. 📝 Committable suggestion
Suggested change
|
||||||
import Loading from '@/components/loading'; | ||||||
import { Divider } from '@/components/ui'; | ||||||
import { useForumData } from '@/context/ForumDataContext'; | ||||||
import { isValidHTMLContent } from '@/utils/htmlValidator'; | ||||||
import { renderContent } from '@/utils/quillUtils'; | ||||||
import SectionDisplay from '@/views/Forum/SectionDisplay'; | ||||||
|
||||||
const LogisticsPage: React.FC = () => { | ||||||
// Destructure the selected event from the context. | ||||||
const { selectedEvent } = useForumData(); | ||||||
|
||||||
// If selectedEvent is not available, show a loading state. | ||||||
if (!selectedEvent) { | ||||||
return <Loading />; | ||||||
} | ||||||
|
||||||
// Render static content from the event model. | ||||||
const vaccinationHTML = renderContent( | ||||||
selectedEvent.travel_logistics_vaccination_details, | ||||||
); | ||||||
const visaHTML = renderContent(selectedEvent.travel_logistics_visa_details); | ||||||
|
||||||
const showVaccination = isValidHTMLContent(vaccinationHTML); | ||||||
const showVisa = isValidHTMLContent(visaHTML); | ||||||
|
||||||
// Filter extra sections assigned to the "logistics" page. | ||||||
const logisticsSections = selectedEvent.sections?.filter( | ||||||
(section: any) => | ||||||
section.pages.includes('logistics') && | ||||||
isValidHTMLContent(renderContent(section.content)), | ||||||
); | ||||||
|
||||||
return ( | ||||||
<div className="px-4 prose max-w-none lg:px-0"> | ||||||
{/* Render Vaccination Section if content exists */} | ||||||
{showVaccination && ( | ||||||
<> | ||||||
<Divider className="bg-black p-0 m-0 h-[1px] w-full" /> | ||||||
<div className="py-6"> | ||||||
<div className="flex flex-col md:flex-row md:space-x-8"> | ||||||
<div className="md:w-1/3 mb-4 md:mb-0"> | ||||||
<h1 className="text-2xl mt-4 font-bold text-gray-900"> | ||||||
Vaccination | ||||||
</h1> | ||||||
</div> | ||||||
<div | ||||||
className="md:w-2/3 space-y-4" | ||||||
dangerouslySetInnerHTML={{ | ||||||
__html: DOMPurify.sanitize(vaccinationHTML), | ||||||
}} | ||||||
/> | ||||||
</div> | ||||||
</div> | ||||||
</> | ||||||
)} | ||||||
|
||||||
{/* Render Visa Invitation Letter Section if content exists */} | ||||||
{showVisa && ( | ||||||
<> | ||||||
<Divider className="bg-black p-0 m-0 h-[1px] w-full" /> | ||||||
<div className="py-6"> | ||||||
<div className="flex flex-col md:flex-row md:space-x-8"> | ||||||
<div className="md:w-1/3 mb-4 md:mb-0"> | ||||||
<h1 className="text-2xl mt-4 font-bold text-gray-900"> | ||||||
Visa invitation letter | ||||||
</h1> | ||||||
</div> | ||||||
<div | ||||||
className="md:w-2/3 space-y-4" | ||||||
dangerouslySetInnerHTML={{ | ||||||
__html: DOMPurify.sanitize(visaHTML), | ||||||
}} | ||||||
/> | ||||||
</div> | ||||||
</div> | ||||||
</> | ||||||
)} | ||||||
export const metadata: Metadata = { | ||||||
title: 'Logistics | Clean Air Forum', | ||||||
description: | ||||||
'Get all the essential logistics information for attending the Clean Air Forum, including travel, accommodation, event schedules, and practical tips for participants.', | ||||||
}; | ||||||
|
||||||
{/* Render additional Logistics Sections, if any */} | ||||||
{logisticsSections && logisticsSections.length > 0 && ( | ||||||
<> | ||||||
{logisticsSections.map((section: any) => ( | ||||||
<SectionDisplay key={section.id} section={section} /> | ||||||
))} | ||||||
</> | ||||||
)} | ||||||
</div> | ||||||
); | ||||||
const Page = () => { | ||||||
return <LogisticsPage />; | ||||||
}; | ||||||
|
||||||
export default LogisticsPage; | ||||||
export default Page; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix import path case sensitivity.
The import path is causing a build failure due to case sensitivity issues.
The pipeline failure indicates that the module cannot be resolved. The actual directory path uses lowercase 'cleanairforum' rather than the camelCase 'cleanAirForum' in your import.
📝 Committable suggestion