Skip to content

Commit bd542b9

Browse files
committed
add recent project section
1 parent 0831e87 commit bd542b9

File tree

8 files changed

+358
-2
lines changed

8 files changed

+358
-2
lines changed

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
66
<link rel="icon" type="image/png" href="/favicon.png" />
77
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8-
<title>&hearts; FrontendFixer</title>
8+
<title>FrontendFixer [&hearts;]</title>
99
</head>
1010
<body>
1111
<div id="root"></div>

public/demo.webp

4.83 KB
Binary file not shown.

src/components/ImageModal.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { faGithub } from '@fortawesome/free-brands-svg-icons';
2+
import { faClose, faEye } from '@fortawesome/free-solid-svg-icons';
3+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4+
5+
type PropsType = {
6+
imgAlt: string;
7+
onClick: () => void;
8+
imgURL: string;
9+
liveURL: string;
10+
repoURL: string;
11+
};
12+
13+
const ImageModal = (props: PropsType) => {
14+
const { onClick, imgAlt, imgURL, liveURL, repoURL } = props;
15+
16+
return (
17+
<>
18+
<div className="fixed inset-0 h-screen w-screen bg-black/50 backdrop-blur-[2px]" />
19+
<div className="fixed left-1/2 top-1/2 z-10 w-2/5 -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 dark:bg-dark-500">
20+
<div className="relative grid grid-cols-1 gap-4">
21+
<FontAwesomeIcon
22+
icon={faClose}
23+
className="absolute -right-9 -top-9 h-6 w-6 cursor-pointer rounded-full bg-dark-900 p-1 text-white dark:bg-white dark:text-dark-900"
24+
onClick={onClick}
25+
/>
26+
<img
27+
src={imgURL}
28+
alt={imgAlt}
29+
className="h-full max-w-full rounded-lg object-cover"
30+
/>
31+
<div className="grid grid-cols-2 gap-5">
32+
<a
33+
href={liveURL}
34+
target="_blank"
35+
rel="noopener noreferrer"
36+
className="flex items-center justify-center gap-2 rounded-md bg-blue-600 py-2 text-sm font-medium text-white transition-colors duration-300 ease-in-out hover:bg-blue-400"
37+
>
38+
<FontAwesomeIcon icon={faEye} />
39+
<span>See Live</span>
40+
</a>
41+
<a
42+
href={repoURL}
43+
target="_blank"
44+
rel="noopener noreferrer"
45+
className="flex items-center justify-center gap-2 rounded-md bg-dark-900 py-2 text-sm font-medium text-white transition-colors duration-300 ease-in-out hover:bg-dark-700"
46+
>
47+
<FontAwesomeIcon icon={faGithub} />
48+
<span>Source Code</span>
49+
</a>
50+
</div>
51+
</div>
52+
</div>
53+
</>
54+
);
55+
};
56+
57+
export default ImageModal;

src/components/ProjectCard.tsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { faGithub } from '@fortawesome/free-brands-svg-icons';
2+
import { faEye } from '@fortawesome/free-solid-svg-icons';
3+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4+
import { useState } from 'react';
5+
import { twJoin } from 'tailwind-merge';
6+
7+
import { ProjectType } from '../data/Projects';
8+
import ImageModal from './ImageModal';
9+
10+
const ProjectCard = ({ project }: { project: ProjectType }) => {
11+
const [openModal, setOpenModal] = useState(false);
12+
13+
const handelImageClick = () => {
14+
setOpenModal(!openModal);
15+
};
16+
const handelClose = () => {
17+
setOpenModal(!openModal);
18+
};
19+
20+
return (
21+
<div className="overflow-hidden rounded-xl bg-white shadow-md dark:bg-dark-700">
22+
<>
23+
<a
24+
onClick={handelImageClick}
25+
className="cursor-pointer transition-all duration-500"
26+
aria-label="open image with live link and repo url"
27+
>
28+
<img
29+
src={project.image}
30+
alt={project.title}
31+
className="h-full max-w-full object-cover"
32+
/>
33+
{openModal && (
34+
<ImageModal
35+
onClick={handelClose}
36+
imgAlt={project.title}
37+
imgURL={project.image}
38+
liveURL={project.url}
39+
repoURL={project.repo}
40+
/>
41+
)}
42+
</a>
43+
</>
44+
45+
<div className="flex flex-col justify-between p-4">
46+
<h3 className="text-center font-serif text-xl font-bold text-dark-900 dark:text-white">
47+
{project.title}
48+
</h3>
49+
<div className="mx-auto my-2 w-full rounded-md bg-slate-400/20 pb-3 pt-2">
50+
<h4 className="text-center text-sm font-medium capitalize dark:text-white">
51+
Coding done with
52+
</h4>
53+
<div className="mx-3 flex flex-wrap gap-2">
54+
{project.development.language
55+
?.filter(el => el !== 'HTML' && el !== 'CSS')
56+
.map((el, i) => (
57+
<span
58+
key={i}
59+
className={twJoin(
60+
'inline-block rounded',
61+
el == 'react' && 'bg-[hsl(224,96%,80%)]/80',
62+
el == 'nextjs' && 'bg-[hsl(220,6%,18%)]/80 text-white',
63+
el == 'typescript' && 'bg-[hsl(186,96%,80%)]/80',
64+
el == 'redux' && 'bg-[hsl(263,96%,80%)]/80',
65+
el == 'MUI' && 'bg-[hsl(203,96%,80%)]/80',
66+
el == 'prisma' && 'bg-[hsl(225,22%,30%)]/80 text-white',
67+
el == 'postgreSQL' && 'bg-[hsl(350,96%,80%)]/80',
68+
'px-3 py-1 text-[12px] capitalize',
69+
)}
70+
>
71+
{el}
72+
</span>
73+
))}
74+
</div>
75+
</div>
76+
<div className="grid grid-cols-2 gap-5">
77+
<a
78+
href={project.url}
79+
target="_blank"
80+
rel="noopener noreferrer"
81+
className="flex items-center justify-center gap-2 rounded-md bg-blue-600 py-2 text-sm font-medium text-white transition-colors duration-300 ease-in-out hover:bg-blue-400"
82+
>
83+
<FontAwesomeIcon icon={faEye} />
84+
<span>See Live</span>
85+
</a>
86+
<a
87+
href={project.repo}
88+
target="_blank"
89+
rel="noopener noreferrer"
90+
className="flex items-center justify-center gap-2 rounded-md bg-dark-900 py-2 text-sm font-medium text-white transition-colors duration-300 ease-in-out hover:bg-dark-700"
91+
>
92+
<FontAwesomeIcon icon={faGithub} />
93+
<span>Source Code</span>
94+
</a>
95+
</div>
96+
</div>
97+
</div>
98+
);
99+
};
100+
101+
export default ProjectCard;

src/components/RecentWork.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Projects from '../data/Projects';
2+
import ProjectCard from './ProjectCard';
3+
4+
const featuredProject = Projects.filter(project => project.featured);
5+
6+
const RecentWork = () => {
7+
return (
8+
<div id="project-grid">
9+
{featuredProject.map(project => {
10+
return <ProjectCard project={project} key={project.id} />;
11+
})}
12+
</div>
13+
);
14+
};
15+
16+
export default RecentWork;

src/data/Projects.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import demoImg from '/demo.webp';
2+
3+
export type ProjectType = {
4+
id: number;
5+
title: string;
6+
description: string;
7+
image: string;
8+
repo: string;
9+
url: string;
10+
development: {
11+
language?: string[];
12+
tools?: string[];
13+
};
14+
featured: boolean;
15+
};
16+
17+
const Projects: ProjectType[] = [
18+
{
19+
id: 1,
20+
title: 'Crwn Clothing Online Store',
21+
description: 'This is a project 1',
22+
image: demoImg,
23+
repo: 'https://github.com',
24+
url: 'https://www.google.com',
25+
development: {
26+
language: ['react', 'typescript', 'HTML', 'CSS', 'redux'],
27+
tools: ['react', 'typescript'],
28+
},
29+
featured: true,
30+
},
31+
{
32+
id: 2,
33+
title: 'Open Table | Book a Table at Any Restaurant',
34+
description: 'This is a project 2',
35+
image: demoImg,
36+
repo: 'https://github.com',
37+
url: 'https://www.google.com',
38+
development: {
39+
language: [
40+
'nextjs',
41+
'react',
42+
'typescript',
43+
'redux',
44+
'MUI',
45+
'prisma',
46+
'postgreSQL',
47+
'HTML',
48+
'CSS',
49+
],
50+
tools: ['react', 'typescript'],
51+
},
52+
featured: true,
53+
},
54+
{
55+
id: 3,
56+
title: 'Open Table | Book a Table at Any Restaurant',
57+
description: 'This is a project 2',
58+
image: demoImg,
59+
repo: 'https://github.com',
60+
url: 'https://www.google.com',
61+
development: {
62+
language: [
63+
'nextjs',
64+
'react',
65+
'typescript',
66+
'redux',
67+
'MUI',
68+
'prisma',
69+
'postgreSQL',
70+
'HTML',
71+
'CSS',
72+
],
73+
tools: ['react', 'typescript'],
74+
},
75+
featured: true,
76+
},
77+
{
78+
id: 4,
79+
title: 'Project 4',
80+
description: 'This is a project 4',
81+
image: demoImg,
82+
repo: 'https://github.com',
83+
url: 'https://www.google.com',
84+
development: {
85+
language: ['react', 'typescript', 'HTML', 'CSS', 'redux'],
86+
tools: ['react', 'typescript'],
87+
},
88+
featured: true,
89+
},
90+
{
91+
id: 5,
92+
title: 'Project 5',
93+
description: 'This is a project 5',
94+
image: demoImg,
95+
repo: 'https://github.com',
96+
url: 'https://www.google.com',
97+
development: {
98+
language: ['react', 'typescript', 'HTML', 'CSS', 'redux'],
99+
tools: ['react', 'typescript'],
100+
},
101+
featured: true,
102+
},
103+
{
104+
id: 6,
105+
title: 'Project 6',
106+
description: 'This is a project 6',
107+
image: demoImg,
108+
repo: 'https://github.com',
109+
url: 'https://www.google.com',
110+
development: {
111+
language: ['react', 'typescript', 'HTML', 'CSS', 'redux'],
112+
tools: ['react', 'typescript'],
113+
},
114+
featured: false,
115+
},
116+
];
117+
118+
export default Projects;

src/index.css

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,58 @@
33
@tailwind base;
44
@tailwind components;
55
@tailwind utilities;
6+
7+
#project-grid {
8+
display: grid;
9+
grid-template-columns: minmax(0, 1fr);
10+
gap: 24px;
11+
}
12+
13+
#project-grid > div {
14+
display: grid;
15+
}
16+
17+
@media (min-width: 640px) {
18+
#project-grid {
19+
grid-template-columns: repeat(2, minmax(0, 1fr));
20+
}
21+
#project-grid > div {
22+
grid-template-columns: minmax(0, 1fr);
23+
}
24+
#project-grid > div:nth-child(1) {
25+
grid-template-columns: repeat(2, minmax(0, 1fr));
26+
grid-column: 1/-1;
27+
}
28+
}
29+
30+
@media (min-width: 1024px) {
31+
#project-grid {
32+
grid-template-columns: repeat(6, minmax(0, 1fr));
33+
}
34+
#project-grid > div:nth-child(1),
35+
#project-grid > div:nth-child(2) {
36+
grid-template-columns: repeat(2, minmax(0, 1fr));
37+
}
38+
#project-grid > div:nth-child(1) {
39+
grid-column: 1/4;
40+
}
41+
#project-grid > div:nth-child(2) {
42+
grid-column: 4/-1;
43+
}
44+
45+
#project-grid > div:nth-child(3),
46+
#project-grid > div:nth-child(4),
47+
#project-grid > div:nth-child(5) {
48+
grid-template-columns: minmax(0, 1fr);
49+
grid-template-rows: auto minmax(0, 1fr);
50+
}
51+
#project-grid > div:nth-child(3) {
52+
grid-column: 1/3;
53+
}
54+
#project-grid > div:nth-child(4) {
55+
grid-column: 3/5;
56+
}
57+
#project-grid > div:nth-child(5) {
58+
grid-column: 5/-1;
59+
}
60+
}

src/routes/Home.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Container from '../components/Container';
22
import HeroSection from '../components/HeroSection';
33
import LanguageAndTool from '../components/LanguageAndTool';
4+
import RecentWork from '../components/RecentWork';
45

56
const Home = () => {
67
return (
@@ -15,14 +16,22 @@ const Home = () => {
1516
</section>
1617
<section id="skills" className="pb-16">
1718
<div className="bg-blue-400 pb-40 pt-24">
18-
<h2 className="text-center font-serif text-4xl font-bold text-white drop-shadow-md lg:text-7xl">
19+
<h2 className="text-center font-serif text-3xl font-bold text-white drop-shadow-md lg:text-5xl">
1920
Skills
2021
</h2>
2122
</div>
2223
<Container>
2324
<LanguageAndTool />
2425
</Container>
2526
</section>
27+
<section className="pb-16 pt-24">
28+
<Container>
29+
<h2 className="mb-16 text-center font-serif text-3xl font-bold capitalize text-dark-900 drop-shadow-md dark:text-gray-50 lg:text-5xl">
30+
My recent projects
31+
</h2>
32+
<RecentWork />
33+
</Container>
34+
</section>
2635
</main>
2736
);
2837
};

0 commit comments

Comments
 (0)