diff --git a/components/projects/projectExplore.jsx b/components/projects/projectExplore.jsx
deleted file mode 100644
index 8f1a6a9..0000000
--- a/components/projects/projectExplore.jsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from 'react';
-import Section from '../section';
-import { Container, Row } from 'reactstrap';
-import ActionButton from '../actionButton';
-
-const ProjectExplore = () => (
-
-
-
-
-
Explore
-
-
-
-
-
-
- For more information on making a lasting impact through a project team or working with
- us to solve a core need for your organization, click below!
-
-
-
-
-
-
-
- Students
-
-
Nonprofits
-
-
-
-
-);
-export default ProjectExplore;
diff --git a/package.json b/package.json
index a1f0def..7f72e91 100644
--- a/package.json
+++ b/package.json
@@ -12,28 +12,33 @@
"lint:fix": "eslint --fix \"./**/*.{js,jsx}\""
},
"dependencies": {
+ "@notionhq/client": "^4.0.1",
"lucide-react": "^0.501.0",
"mongodb": "^4.17.2",
- "next": "^12.0.0",
+ "next": "^13.5.0",
"next-page-transitions": "^1.0.0-alpha.4",
- "react": "^17.0.0",
- "react-dom": "^17.0.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
"react-ga": "^3.1.2",
+ "react-icons": "^4.3.1",
"react-spring": "^8.0.27",
"react-toastify": "^6.0.8",
"react-vertical-timeline-component": "^3.0.2",
"reactstrap": "^8.5.1",
- "yarn": "^1.16.0"
+ "sass": "^1.77.8"
},
"devDependencies": {
"@contentful/rich-text-html-renderer": "^14.1.2",
"@hack4impact-uiuc/eslint-plugin": "2.0.3",
+ "@typescript-eslint/eslint-plugin": "3.10.1",
+ "@typescript-eslint/parser": "3.10.1",
"babel-plugin-inline-react-svg": "^1.0.1",
- "eslint": "^7.6.0",
- "eslint-config-prettier": "^6.12.0",
- "eslint-plugin-prettier": "^3.3.1",
- "prettier": "^2.1.2",
- "sass": "^1.86.0",
- "styled-jsx-plugin-sass": "^1.0.0"
+ "eslint": "^7.32.0",
+ "eslint-config-prettier": "^8.10.0",
+ "eslint-plugin-prettier": "^4.2.1",
+ "jest": "^29.6.2",
+ "prettier": "^3.0.0",
+ "styled-jsx-plugin-sass": "^1.0.0",
+ "typescript": "^4.9.5"
}
}
diff --git a/pages/about.jsx b/pages/about.jsx
index 1f67e45..b6d3e7c 100644
--- a/pages/about.jsx
+++ b/pages/about.jsx
@@ -4,7 +4,8 @@ import MissionSection from '../components/about/missionSection';
import OurValues from '../components/about/ourValues';
import Head from '../components/head';
import Team from '../components/about/team';
-import fetchContent from '../utils/fetchContent';
+import { fetchContent } from '../utils/fetchContent';
+import fetchNotionContent from '../utils/fetchContent';
function AboutPage({ members, alumni, values, execBoard }) {
return (
@@ -12,7 +13,7 @@ function AboutPage({ members, alumni, values, execBoard }) {
@@ -25,63 +26,53 @@ function AboutPage({ members, alumni, values, execBoard }) {
export default AboutPage;
export async function getStaticProps() {
- const {
- pennWebsiteLayout: {
- chapterValuesCollection,
- execBoardCollection,
- membersCollection,
- alumniCollection,
- },
- } = await fetchContent(`
- fragment profile on PennMemberProfile{
- name
- title
- image {
- url
- }
- linkedIn
- classOf
- urlSlug
- }
-
- {
- pennWebsiteLayout(id: "${process.env.LAYOUT_ENTRY_ID}") {
- chapterValuesCollection {
- items {
- header
- body {
- json
+ try {
+ // Fetch values from Contentful and all members from Notion
+ const [contentfulData, allMembers] = await Promise.all([
+ fetchContent(`
+ {
+ pennWebsiteLayout(id: "${process.env.LAYOUT_ENTRY_ID}") {
+ chapterValuesCollection {
+ items {
+ header
+ body {
+ json
+ }
+ image {
+ url
+ description
+ }
+ }
}
- image {
- url
- description
- }
- }
- }
- execBoardCollection {
- items {
- ...profile
- }
- }
- membersCollection {
- items {
- ...profile
}
}
- alumniCollection {
- items {
- ...profile
- }
- }
- }
+ `),
+ fetchNotionContent('members')
+ ]);
+
+ const membersList = allMembers.memberCollection.items;
+ const activeMembers = membersList.filter(member => member.status === 'Active');
+ const alumni = membersList.filter(member => member.status === 'Alumni');
+ const execBoard = membersList.filter(member => member.title === 'Co-Director' || /chair/i.test(member.title));
+
+
+ return {
+ props: {
+ values: contentfulData.pennWebsiteLayout.chapterValuesCollection.items,
+ members: activeMembers,
+ alumni: alumni,
+ execBoard: execBoard
+ },
+ };
+ } catch (error) {
+ console.error('Error fetching about page data:', error);
+ return {
+ props: {
+ members: [],
+ alumni: [],
+ values: [],
+ execBoard: []
+ },
+ };
}
- `);
- return {
- props: {
- values: chapterValuesCollection.items,
- members: membersCollection.items,
- alumni: alumniCollection.items,
- execBoard: execBoardCollection.items,
- },
- };
}
diff --git a/pages/api/saveQuizData.js b/pages/api/saveQuizData.js
index 2ac0d97..0de3ea4 100644
--- a/pages/api/saveQuizData.js
+++ b/pages/api/saveQuizData.js
@@ -2,7 +2,7 @@ import { MongoClient } from 'mongodb';
// MongoDB connection string - replace with your actual connection string
// You should use environment variables for this in production
-const MONGODB_URI = process.env.MONGODB_URI;
+// const MONGODB_URI = process.env.MONGODB_URI;
const MONGODB_DB = process.env.MONGODB_DB || 'Hack4ImpactUPenn';
export default async function handler(req, res) {
@@ -14,7 +14,7 @@ export default async function handler(req, res) {
try {
// Connect to MongoDB
- const client = await MongoClient.connect(MONGODB_URI, {
+ const client = await MongoClient.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
diff --git a/pages/apply/nonprofits.jsx b/pages/apply/nonprofits.jsx
index 9dfb8db..4aac562 100644
--- a/pages/apply/nonprofits.jsx
+++ b/pages/apply/nonprofits.jsx
@@ -6,7 +6,7 @@ import Quote from '../../components/quote';
import ApplicationProcess from '../../components/apply/applicationProcess';
import Head from '../../components/head';
import ActionButton from '../../components/actionButton';
-import fetchContent from '../../utils/fetchContent';
+import { fetchContent } from '../../utils/fetchContent';
function NonProfits({
applicationLink,
diff --git a/pages/apply/students.jsx b/pages/apply/students.jsx
index 445be47..da9bf0b 100644
--- a/pages/apply/students.jsx
+++ b/pages/apply/students.jsx
@@ -6,7 +6,7 @@ import Quote from '../../components/quote';
import ApplicationProcess from '../../components/apply/applicationProcess';
import Head from '../../components/head';
import ActionButton from '../../components/actionButton';
-import fetchContent from '../../utils/fetchContent';
+import { fetchContent } from '../../utils/fetchContent';
function Students({
applicationLink,
diff --git a/pages/clients/quizpage.jsx b/pages/clients/quizpage.jsx
index e1e3bfa..d96b26d 100644
--- a/pages/clients/quizpage.jsx
+++ b/pages/clients/quizpage.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import Head from '../../components/head';
import { Container, Row, Col } from 'reactstrap';
import Quiz from '../../components/clients/ProjectQuiz';
-import fetchContent from '../../utils/fetchContent';
+import {fetchContent} from '../../utils/fetchContent';
export async function getStaticProps() {
const {
diff --git a/pages/index.jsx b/pages/index.jsx
index 5c1f9a0..5c65d4d 100644
--- a/pages/index.jsx
+++ b/pages/index.jsx
@@ -6,7 +6,7 @@ import PartnerSection from '../components/homepage/partnerSection';
import OtherChapters from '../components/homepage/otherChapters';
import { ToastContainer } from 'react-toastify';
import Head from '../components/head';
-import fetchContent from '../utils/fetchContent';
+import fetchNotionContent from '../utils/fetchContent';
import Section from '../components/section';
import { Container } from 'reactstrap';
@@ -24,7 +24,7 @@ function Home({ chapterLogos, previewProjects }) {
-
+ {/*
*/}
>
);
}
@@ -35,36 +35,8 @@ export async function getStaticProps() {
const {
chapterCollection,
pennWebsiteLayout: { projectsCollection },
- } = await fetchContent(`
- {
- chapterCollection {
- items {
- name
- websiteLink
- socialMediaLink
- codeRepoLink
- universityLogo {
- url
- }
- }
- }
- pennWebsiteLayout(id: "${process.env.LAYOUT_ENTRY_ID}") {
- projectsCollection(limit: 3) {
- items {
- title
- description {
- json
- }
- thumbnail {
- url
- description
- }
- urlSlug
- }
- }
- }
- }
- `);
+ } = await fetchNotionContent('homepage');
+
return {
props: {
chapterLogos: chapterCollection.items.map(
diff --git a/pages/projects/[projectSlug].jsx b/pages/projects/[projectSlug].jsx
index 1241ede..959fe77 100644
--- a/pages/projects/[projectSlug].jsx
+++ b/pages/projects/[projectSlug].jsx
@@ -1,10 +1,10 @@
import React from 'react';
import Head from '../../components/head';
-import fetchContent from '../../utils/fetchContent';
+import { fetchNotionContent, fetchProjectDetail } from '../../utils/fetchContent';
import Team from '../../components/projects/Team';
import FeatureSlider from '../../components/projects/featureSlider';
import ProjectQuote from '../../components/quote';
-import ContentBlock from '../../components/ContentBlock';
+import TextBlock from '../../components/TextBlock';
import ActionButton from '../../components/actionButton';
import { Row, Col, Container } from 'reactstrap';
import GradientBanner from '../../components/gradientBanner';
@@ -23,6 +23,7 @@ function ProjectPage({
testimonialsCollection,
technologiesUsed,
teamMembersCollection,
+ pmtlCollection,
}) {
return (
<>
@@ -53,40 +54,40 @@ function ProjectPage({
About the Project
-
+
About the Client
-
+
-
+ {featuresCollection.items.length > 0 &&
}
-
t.trim())} />
- {testimonialsCollection.items.map(({ author, quote }) => {
+ {technologiesUsed && t.trim())} />}
+ {testimonialsCollection.items.map(({ author, quote }, index) => {
const [authorName, authorTitle] = author.split(',');
return (
);
})}
- {teamMembersCollection.items.size > 0 && }
-
+ {pmtlCollection.items.length > 0 && }
+ {teamMembersCollection.items.length > 0 && }
See more of our projects
@@ -117,24 +118,14 @@ function ProjectPage({
export default ProjectPage;
-// necessary to statically render all paths
export async function getStaticPaths() {
+ try {
const {
pennWebsiteLayout: { projectsCollection },
- } = await fetchContent(`
- {
- pennWebsiteLayout(id: "${process.env.LAYOUT_ENTRY_ID}") {
- projectsCollection {
- items {
- urlSlug
- }
- }
- }
- }
- `);
+ } = await fetchNotionContent('projects');
const paths = projectsCollection.items
- .filter((x) => !!x)
+ .filter((x) => !!x && !!x.urlSlug)
.map(({ urlSlug }) => ({
params: {
projectSlug: urlSlug,
@@ -145,78 +136,30 @@ export async function getStaticPaths() {
paths,
fallback: false,
};
+ } catch (error) {
+ console.error('Error in getStaticPaths:', error);
+ return {
+ paths: [],
+ fallback: false,
+ };
+ }
}
-// necessary to statically render all paths
-
export async function getStaticProps({ params: { projectSlug } }) {
- const { pennProjectPageCollection } = await fetchContent(`
- {
- pennProjectPageCollection(where: {urlSlug: "${projectSlug}"}, limit: 1) {
- items {
- title
- description {
- json
- }
- thumbnail {
- url
- }
- finalProductLink
- codeRepoLink
- technologiesUsed
- project {
- json
- }
- client {
- json
- }
- impact {
- json
- }
- featuresCollection {
- items {
- header
- body {
- json
- }
- image {
- url
- description
- }
- }
- }
- testimonialsCollection {
- items {
- author
- quote {
- json
- }
- }
- }
- teamMembersCollection {
- items {
- name
- title
- image {
- url
- }
- linkedIn
- }
- }
- }
- }
- }
- `);
-
- if (!pennProjectPageCollection?.items?.length) {
- throw `The slug ${projectSlug} doesn't have an associated Contentful entry.
- Make sure your getStaticPaths method is pulling the right slugs!`;
+ try {
+ const formattedProject = await fetchProjectDetail(projectSlug);
+
+ if (!formattedProject) {
+ throw new Error(`No project found with slug: ${projectSlug}`);
}
- const projectContent = pennProjectPageCollection.items[0];
return {
- props: {
- ...projectContent,
- },
+ props: formattedProject,
+ };
+ } catch (error) {
+ console.error('Error fetching project detail:', error);
+ return {
+ notFound: true,
};
+ }
}
diff --git a/pages/projects/index.jsx b/pages/projects/index.jsx
index 2531ec8..c689281 100644
--- a/pages/projects/index.jsx
+++ b/pages/projects/index.jsx
@@ -3,11 +3,11 @@ import React from 'react';
import Head from '../../components/head';
import GradientBanner from '../../components/gradientBanner';
import ProjectList from '../../components/projects/projectList';
-import ProjectExplore from '../../components/projects/projectExplore';
-import fetchContent from '../../utils/fetchContent';
+import fetchNotionContent from '../../utils/fetchContent';
import ActionButton from '../../components/actionButton';
function Projects({ projects }) {
+ console.log(projects);
return (
@@ -34,7 +34,6 @@ function Projects({ projects }) {