Skip to content

Commit cd8becc

Browse files
committed
Add multiple projects display and links
1 parent 328e164 commit cd8becc

File tree

12 files changed

+249
-83
lines changed

12 files changed

+249
-83
lines changed

src/App.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ function App() {
2727
<Routes>
2828
<Route path="/" element={<Home />} />
2929
<Route path="projects" element={<Projects />} />
30-
<Route
31-
path="projects/single-project"
32-
element={<ProjectSingle />}
33-
/>
30+
<Route path="/projects/:title" element={<ProjectSingle />} />
3431

3532
<Route path="about" element={<About />} />
3633
<Route path="contact" element={<Contact />} />

src/components/projects/ProjectGallery.jsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { useContext } from 'react';
2-
import SingleProjectContext from '../../context/SingleProjectContext';
31

4-
const ProjectGallery = () => {
5-
const { singleProjectData } = useContext(SingleProjectContext);
2+
3+
const ProjectGallery = ({ project }) => {
64

75
return (
86
<div className="grid grid-cols-1 sm:grid-cols-3 sm:gap-10 mt-12">
9-
{singleProjectData.ProjectImages.map((project) => {
7+
{project.ProjectImages.map((project) => {
108
return (
119
<div className="mb-10 sm:mb-0" key={project.id}>
1210
<img

src/components/projects/ProjectHeader.jsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1-
import { useContext } from 'react';
2-
import { FiClock, FiTag } from 'react-icons/fi';
3-
import SingleProjectContext from '../../context/SingleProjectContext';
41

5-
const ProjectSingleHeader = () => {
6-
const { singleProjectData } = useContext(SingleProjectContext);
2+
import { FiClock, FiTag } from 'react-icons/fi';
3+
const ProjectSingleHeader = ({ project }) => {
4+
75

86
return (
97
<div>
108
<p className="font-general-medium text-left text-3xl sm:text-4xl font-bold text-primary-dark dark:text-primary-light mt-14 sm:mt-20 mb-7">
11-
{singleProjectData.ProjectHeader.title}
9+
{project.ProjectHeader.title}
1210
</p>
1311
<div className="flex">
1412
<div className="flex items-center mr-10">
1513
<FiClock className="text-lg text-ternary-dark dark:text-ternary-light" />
1614
<span className="font-general-regular ml-2 leading-none text-primary-dark dark:text-primary-light">
17-
{singleProjectData.ProjectHeader.publishDate}
15+
{project.ProjectHeader.publishDate}
1816
</span>
1917
</div>
2018
<div className="flex items-center">
2119
<FiTag className="text-lg text-ternary-dark dark:text-ternary-light" />
2220
<span className="font-general-regular ml-2 leading-none text-primary-dark dark:text-primary-light">
23-
{singleProjectData.ProjectHeader.tags}
21+
{project.ProjectHeader.tags}
2422
</span>
2523
</div>
2624
</div>

src/components/projects/ProjectInfo.jsx

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
import { useContext } from 'react';
2-
import SingleProjectContext from '../../context/SingleProjectContext';
31

4-
const ProjectInfo = () => {
5-
const { singleProjectData } = useContext(SingleProjectContext);
2+
const ProjectInfo = ({project}) => {
63

74
return (
85
<div className="block sm:flex gap-0 sm:gap-10 mt-14">
96
<div className="w-full sm:w-1/3 text-left">
107
{/* Single project client details */}
118
<div className="mb-7">
129
<p className="font-general-regular text-2xl font-semibold text-secondary-dark dark:text-secondary-light mb-2">
13-
{singleProjectData.ProjectInfo.ClientHeading}
10+
{project.ProjectInfo.ClientHeading}
1411
</p>
1512
<ul className="leading-loose">
16-
{singleProjectData.ProjectInfo.CompanyInfo.map(
13+
{project.ProjectInfo.CompanyInfo.map(
1714
(info) => {
1815
return (
1916
<li
@@ -43,20 +40,20 @@ const ProjectInfo = () => {
4340
{/* Single project objectives */}
4441
<div className="mb-7">
4542
<p className="font-general-regular text-2xl font-semibold text-ternary-dark dark:text-ternary-light mb-2">
46-
{singleProjectData.ProjectInfo.ObjectivesHeading}
43+
{project.ProjectInfo.ObjectivesHeading}
4744
</p>
4845
<p className="font-general-regular text-primary-dark dark:text-ternary-light">
49-
{singleProjectData.ProjectInfo.ObjectivesDetails}
46+
{project.ProjectInfo.ObjectivesDetails}
5047
</p>
5148
</div>
5249

5350
{/* Single project technologies */}
5451
<div className="mb-7">
5552
<p className="font-general-regular text-2xl font-semibold text-ternary-dark dark:text-ternary-light mb-2">
56-
{singleProjectData.ProjectInfo.Technologies[0].title}
53+
{project.ProjectInfo.Technologies[0].title}
5754
</p>
5855
<p className="font-general-regular text-primary-dark dark:text-ternary-light">
59-
{singleProjectData.ProjectInfo.Technologies[0].techs.join(
56+
{project.ProjectInfo.Technologies[0].techs.join(
6057
', '
6158
)}
6259
</p>
@@ -65,10 +62,10 @@ const ProjectInfo = () => {
6562
{/* Single project social sharing */}
6663
<div>
6764
<p className="font-general-regular text-2xl font-semibold text-ternary-dark dark:text-ternary-light mb-2">
68-
{singleProjectData.ProjectInfo.SocialSharingHeading}
65+
{project.ProjectInfo.SocialSharingHeading}
6966
</p>
7067
<div className="flex items-center gap-3 mt-5">
71-
{singleProjectData.ProjectInfo.SocialSharing.map(
68+
{project.ProjectInfo.SocialSharing.map(
7269
(social) => {
7370
return (
7471
<a
@@ -92,9 +89,9 @@ const ProjectInfo = () => {
9289
{/* Single project right section */}
9390
<div className="w-full sm:w-2/3 text-left mt-10 sm:mt-0">
9491
<p className="font-general-regular text-primary-dark dark:text-primary-light text-2xl font-bold mb-7">
95-
{singleProjectData.ProjectInfo.ProjectDetailsHeading}
92+
{project.ProjectInfo.ProjectDetailsHeading}
9693
</p>
97-
{singleProjectData.ProjectInfo.ProjectDetails.map((details) => {
94+
{project.ProjectInfo.ProjectDetails.map((details) => {
9895
return (
9996
<p
10097
key={details.id}

src/components/projects/ProjectRelatedProjects.jsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import { useContext } from 'react';
2-
import SingleProjectContext from '../../context/SingleProjectContext';
31

4-
const ProjectRelatedProjects = () => {
5-
const { singleProjectData } = useContext(SingleProjectContext);
2+
3+
const ProjectRelatedProjects = ({project}) => {
64

75
return (
86
<div className="mt-10 pt-10 sm:pt-14 sm:mt-20 border-t-2 border-primary-light dark:border-secondary-dark">
97
<p className="font-general-regular text-primary-dark dark:text-primary-light text-3xl font-bold mb-10 sm:mb-14 text-left">
10-
{singleProjectData.RelatedProject.title}
8+
{project.RelatedProject.title}
119
</p>
1210

1311
<div className="grid grid-cols-1 sm:grid-cols-4 gap-10">
14-
{singleProjectData.RelatedProject.Projects.map((project) => {
12+
{project.RelatedProject.Projects.map((project) => {
1513
return (
1614
<img
1715
src={project.img}

src/components/projects/ProjectSingle.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { motion } from 'framer-motion';
22
import { Link } from 'react-router-dom';
33

4-
const ProjectSingle = ({ title, category, image }) => {
4+
const ProjectSingle = ({ title, category, image, id }) => {
5+
const projectTitleUrl = title.replace(/\s+/g, '-').toLowerCase(); // Replace spaces with hyphens and convert to lowercase
56
return (
67
<motion.div
78
initial={{ opacity: 0 }}
@@ -12,7 +13,7 @@ const ProjectSingle = ({ title, category, image }) => {
1213
delay: 0.15,
1314
}}
1415
>
15-
<Link to="/projects/single-project" aria-label="Single Project">
16+
<Link key={id} to={`/projects/${projectTitleUrl}`} aria-label={`Project ${title}`}>
1617
<div className="rounded-xl shadow-lg hover:shadow-xl cursor-pointer mb-10 sm:mb-0 bg-secondary-light dark:bg-ternary-dark">
1718
<div>
1819
<img

src/components/projects/ProjectsGrid.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const ProjectsGrid = () => {
102102
category={project.category}
103103
image={project.img}
104104
key={project.id}
105+
id={project.id}
105106
/>
106107
))
107108
: searchProject
@@ -111,6 +112,7 @@ const ProjectsGrid = () => {
111112
category={project.category}
112113
image={project.img}
113114
key={project.id}
115+
id={project.id}
114116
/>
115117
))
116118
: projects.map((project) => (
@@ -119,6 +121,7 @@ const ProjectsGrid = () => {
119121
category={project.category}
120122
image={project.img}
121123
key={project.id}
124+
id={project.id}
122125
/>
123126
))}
124127
</div>

src/context/ProjectsContext.jsx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,13 @@ export const ProjectsProvider = (props) => {
1212

1313
// Search projects by project title
1414
const searchProjectsByTitle = projects.filter((item) => {
15-
const result = item.title
16-
.toLowerCase()
17-
.includes(searchProject.toLowerCase())
18-
? item
19-
: searchProject === ''
20-
? item
21-
: '';
22-
return result;
15+
return item.title.toLowerCase().includes(searchProject.toLowerCase()) || searchProject === '';
2316
});
2417

2518
// Select projects by project category
26-
const selectProjectsByCategory = projects.filter((item) => {
27-
let category =
28-
item.category.charAt(0).toUpperCase() + item.category.slice(1);
29-
return category.includes(selectProject);
19+
const selectProjectsByCategory = searchProjectsByTitle.filter((item) => {
20+
let category = item.category.charAt(0).toUpperCase() + item.category.slice(1);
21+
return category.includes(selectProject) || selectProject === '';
3022
});
3123

3224
return (

src/context/SingleProjectContext.jsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
import { useState, createContext } from 'react';
1+
// src/context/SingleProjectContext.js
2+
import { createContext, useState } from 'react';
23
import { singleProjectData as singleProjectDataJson } from '../data/singleProjectData';
34

45
const SingleProjectContext = createContext();
56

6-
export const SingleProjectProvider = ({ children }) => {
7-
const [singleProjectData, setSingleProjectData] = useState(
8-
singleProjectDataJson
9-
);
7+
export const SingleProjectProvider = ({ children, project }) => {
8+
const [projects] = useState(singleProjectDataJson); // Assuming this is where you're defining your projects
109

1110
return (
12-
<SingleProjectContext.Provider
13-
value={{ singleProjectData, setSingleProjectData }}
14-
>
11+
<SingleProjectContext.Provider value={{ projects, project }}>
1512
{children}
1613
</SingleProjectContext.Provider>
1714
);

src/data/projects.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,71 @@ import UIImage1 from '../images/ui-project-1.jpg';
77
import UIImage2 from '../images/ui-project-2.jpg';
88

99
export const projectsData = [
10+
1011
{
1112
id: 1,
12-
title: 'Google Health Platform',
13+
title: 'Laboratory Research Management',
1314
category: 'Web Application',
14-
img: WebImage2,
15+
img: MobileImage2,
1516
ProjectHeader: {
16-
title: 'Project Management UI - From Context',
17-
publishDate: 'Jul 26, 2021',
18-
tags: 'UI / Frontend',
17+
title: 'Laboratory Research Management Web Application - Managing a research laboratory',
18+
publishDate: 'Jan 27, 2024',
19+
tags: 'Angular / SpringBoot',
1920
},
2021
},
2122
{
2223
id: 2,
23-
title: 'Phoenix Digital Agency',
24-
category: 'Mobile Application',
25-
img: MobileImage2,
24+
title: 'BrightSkies Academy Platform',
25+
category: 'Web Application',
26+
img: WebImage2,
27+
ProjectHeader: {
28+
title: 'BrightSkies Academy Platform - Developed a web-based platform for online training tailored to High Performance Computing (HPC) courses.',
29+
publishDate: 'Nov 6, 2023',
30+
tags: 'Angular, Django, MySQL, AWS',
31+
},
2632
},
2733
{
2834
id: 3,
29-
title: 'Project Management UI',
30-
category: 'UI/UX Design',
35+
title: 'Olive Oil supply chain',
36+
category: 'Web application',
3137
img: UIImage1,
38+
ProjectHeader: {
39+
title: 'Olive Oil supply chain - A React and Blockchain-Based Solution for Ensuring Product Authenticity ',
40+
publishDate: 'May 31, 2023',
41+
tags: 'React / NodeJS / Blockchain / MongoDB ',
42+
},
3243
},
3344
{
3445
id: 4,
35-
title: 'Cloud Storage Platform',
36-
category: 'UI/UX Design',
46+
title: 'Blog space',
47+
category: 'Web application',
3748
img: UIImage2,
49+
ProjectHeader: {
50+
title: 'Blog space - Academic project',
51+
publishDate: 'May 28, 2023',
52+
tags: 'PHP / AJAX / JAVASCRIPT / HTML / CSS',
53+
},
3854
},
3955
{
4056
id: 5,
41-
title: 'React Social App',
57+
title: 'Patient tracker',
4258
category: 'Mobile Application',
4359
img: MobileImage1,
60+
ProjectHeader: {
61+
title: 'Patient tracker - Developed a mobile application for patient monitoring',
62+
publishDate: 'Apr 20, 2023',
63+
tags: 'Dart / Flutter',
64+
},
4465
},
4566
{
4667
id: 6,
47-
title: 'Apple Design System',
68+
title: 'DoubleCo Agency',
4869
category: 'Web Application',
4970
img: WebImage1,
71+
ProjectHeader: {
72+
title: 'Project Management UI - From Context',
73+
publishDate: 'Oct 11, 2022',
74+
tags: 'HTML / Bootstrap / CSS / Frontend',
75+
},
5076
},
5177
];

0 commit comments

Comments
 (0)