Rename portfolio to projects

This commit is contained in:
Hazem Krimi
2023-06-04 16:07:59 +01:00
parent 3a51b7fdb2
commit 69afc742a0
14 changed files with 161 additions and 128 deletions
+2 -2
View File
@@ -5,8 +5,8 @@ const Hero = () => (
<Wrapper> <Wrapper>
<div className='intro'> <div className='intro'>
<h2>Hi, I am Hazem</h2> <h2>Hi, I am Hazem</h2>
<h2>I Like Building Things</h2> <h2>I Like Building Software</h2>
<h2 className='blue'>Software Developer</h2> <h2 className='blue'>Full Stack TypeScript Developer</h2>
<h2 className='blue'>Life Long Learner</h2> <h2 className='blue'>Life Long Learner</h2>
</div> </div>
<div className='photo'> <div className='photo'>
+2 -2
View File
@@ -49,8 +49,8 @@ const MobileNav = ({ open, close }: Props) => {
</Button> </Button>
</div> </div>
<div className='mobile-button-wrapper'> <div className='mobile-button-wrapper'>
<Button href='/portfolio' onClick={() => close()}> <Button href='/projects' onClick={() => close()}>
Portfolio Projects
</Button> </Button>
</div> </div>
<div className='mobile-button-wrapper'> <div className='mobile-button-wrapper'>
+1 -1
View File
@@ -29,7 +29,7 @@ const Nav = () => {
icon={mode === 'dark' ? '/icons/sun.svg' : '/icons/moon.svg'} icon={mode === 'dark' ? '/icons/sun.svg' : '/icons/moon.svg'}
onClick={toggle} onClick={toggle}
/> />
<Button href='/portfolio'>Portfolio</Button> <Button href='/projects'>Projects</Button>
<Button href='/blog'>Blog</Button> <Button href='/blog'>Blog</Button>
<Button href='/contact'>Contact</Button> <Button href='/contact'>Contact</Button>
<Button href='/resume.pdf' target='_blank' variant='outline'> <Button href='/resume.pdf' target='_blank' variant='outline'>
+10 -4
View File
@@ -13,18 +13,24 @@ const NotFound = () => {
<meta name='author' content='Hazem Krimi' /> <meta name='author' content='Hazem Krimi' />
<meta <meta
name='description' name='description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/> />
<link rel='canonical' href='https://hazemkrimi.tech/*' /> <link rel='canonical' href='https://hazemkrimi.tech' />
<meta property='og:image' content='/logo.png' /> <meta property='og:image' content='/logo.png' />
<meta <meta
property='og:description' property='og:description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/> />
<meta property='og:title' content='Hazem Krimi' /> <meta property='og:title' content='Hazem Krimi' />
<meta <meta
name='keywords' name='keywords'
content='Hazem, Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News' content='Hazem, Krimi, Hazem Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, TypeScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News, Software Developer, Software Engineer, Full Stack TypeScript Developer, Next.js'
/> />
<title>404 Not Found | Hazem Krimi</title> <title>404 Not Found | Hazem Krimi</title>
</Head> </Head>
+9 -3
View File
@@ -39,7 +39,10 @@ const BlogPost = ({ source, frontMatter, text }: Props) => {
content={ content={
frontMatter?.description frontMatter?.description
? frontMatter.description ? frontMatter.description
: 'Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' : `Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.`
} }
/> />
<link rel='canonical' href='https://hazemkrimi.tech' /> <link rel='canonical' href='https://hazemkrimi.tech' />
@@ -49,7 +52,10 @@ const BlogPost = ({ source, frontMatter, text }: Props) => {
content={ content={
frontMatter?.description frontMatter?.description
? frontMatter.description ? frontMatter.description
: 'Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' : `Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.`
} }
/> />
<meta property='og:title' content={`${frontMatter?.title} | Hazem Krimi`} /> <meta property='og:title' content={`${frontMatter?.title} | Hazem Krimi`} />
@@ -58,7 +64,7 @@ const BlogPost = ({ source, frontMatter, text }: Props) => {
content={ content={
frontMatter?.tags frontMatter?.tags
? frontMatter.tags.join(' ') ? frontMatter.tags.join(' ')
: 'Hazem, Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News' : `Hazem, Krimi, Hazem Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, TypeScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News, Software Developer, Software Engineer, Full Stack TypeScript Developer, Next.js`
} }
/> />
<title>{`${frontMatter?.title} | Hazem Krimi`}</title> <title>{`${frontMatter?.title} | Hazem Krimi`}</title>
+10 -4
View File
@@ -35,18 +35,24 @@ const About = () => {
<meta name='author' content='Hazem Krimi' /> <meta name='author' content='Hazem Krimi' />
<meta <meta
name='description' name='description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/> />
<link rel='canonical' href='https://hazemkrimi.tech/about' /> <link rel='canonical' href='https://hazemkrimi.tech' />
<meta property='og:image' content='/logo.png' /> <meta property='og:image' content='/logo.png' />
<meta <meta
property='og:description' property='og:description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/> />
<meta property='og:title' content='Hazem Krimi' /> <meta property='og:title' content='Hazem Krimi' />
<meta <meta
name='keywords' name='keywords'
content='Hazem, Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News' content='Hazem, Krimi, Hazem Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, TypeScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News, Software Developer, Software Engineer, Full Stack TypeScript Developer, Next.js'
/> />
<title>Contact | Hazem Krimi</title> <title>Contact | Hazem Krimi</title>
</Head> </Head>
+21 -18
View File
@@ -1,4 +1,4 @@
import { getPortfolioProjects } from '../utils/portfolio'; import { getProjects } from '../utils/projects';
import { getBlogPosts } from '../utils/blog'; import { getBlogPosts } from '../utils/blog';
import { GetStaticProps } from 'next'; import { GetStaticProps } from 'next';
import { Wrapper } from '../styles/home'; import { Wrapper } from '../styles/home';
@@ -16,7 +16,7 @@ interface Props {
date: string; date: string;
tags?: string[]; tags?: string[];
}[]; }[];
portfolioProjects: { projects: {
title: string; title: string;
description: string; description: string;
slug: string; slug: string;
@@ -25,7 +25,7 @@ interface Props {
}[]; }[];
} }
const Index = ({ blogPosts, portfolioProjects }: Props) => { const Index = ({ blogPosts, projects }: Props) => {
return ( return (
<> <>
<Head> <Head>
@@ -33,18 +33,24 @@ const Index = ({ blogPosts, portfolioProjects }: Props) => {
<meta name='author' content='Hazem Krimi' /> <meta name='author' content='Hazem Krimi' />
<meta <meta
name='description' name='description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/> />
<link rel='canonical' href='https://hazemkrimi.tech' /> <link rel='canonical' href='https://hazemkrimi.tech' />
<meta property='og:image' content='/logo.png' /> <meta property='og:image' content='/logo.png' />
<meta <meta
property='og:description' property='og:description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/> />
<meta property='og:title' content='Hazem Krimi' /> <meta property='og:title' content='Hazem Krimi' />
<meta <meta
name='keywords' name='keywords'
content='Hazem, Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News' content='Hazem, Krimi, Hazem Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, TypeScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News, Software Developer, Software Engineer, Full Stack TypeScript Developer, Next.js'
/> />
<title>Hazem Krimi</title> <title>Hazem Krimi</title>
</Head> </Head>
@@ -54,22 +60,19 @@ const Index = ({ blogPosts, portfolioProjects }: Props) => {
<h1>About</h1> <h1>About</h1>
<div className='about'> <div className='about'>
<p> <p>
I am a software developer. I have experience as a full stack developer but I lean more Experienced Full Stack developer with a focus on building user-friendly web and cross-platform mobile applications using cutting-edge technologies. Passionate about ongoing learning and staying up-to-date with the latest trends in software engineering.
to the front end and I have built a lot of web apps and some mobile apps. Also, I am
always learning and experimenting with new technologies (currently learning about the
ethereum blockchain) and other topics other than software engineering.
</p> </p>
</div> </div>
{portfolioProjects.length !== 0 && ( {projects.length !== 0 && (
<> <>
<h1>Portfolio</h1> <h1>Projects</h1>
<Button href='/portfolio' className='blue'> <Button href='/projects' className='blue'>
See More See More
</Button> </Button>
<div className='portfolio'> <div className='projects'>
<div className='projects-wrapper'> <div className='projects-wrapper'>
{portfolioProjects.slice(0, 3).map(({ slug, ...rest }) => ( {projects.slice(0, 3).map(({ slug, ...rest }) => (
<Card {...rest} key={slug} href={`/portfolio/${slug}`} /> <Card {...rest} key={slug} href={`/projects/${slug}`} />
))} ))}
</div> </div>
</div> </div>
@@ -100,11 +103,11 @@ export default Index;
export const getStaticProps: GetStaticProps = async () => { export const getStaticProps: GetStaticProps = async () => {
const blogPosts = getBlogPosts(); const blogPosts = getBlogPosts();
const portfolioProjects = getPortfolioProjects(); const projects = getProjects();
return { return {
props: { props: {
blogPosts, blogPosts,
portfolioProjects projects
} }
}; };
}; };
-73
View File
@@ -1,73 +0,0 @@
import { getPortfolioProjects } from '../../utils/portfolio';
import { useRouter } from 'next/router';
import { Wrapper } from '../../styles/portfolio';
import Card from '../../components/Card';
import IconButton from '../../components/IconButton';
import Head from 'next/head';
interface Props {
portfolioProjects: {
title: string;
description: string;
image?: string;
slug: string;
date: string;
tags?: string[];
}[];
}
const Index = ({ portfolioProjects }: Props) => {
const router = useRouter();
return (
<>
<Head>
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
<meta name='author' content='Hazem Krimi' />
<meta
name='description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast'
/>
<link rel='canonical' href='https://hazemkrimi.tech/portfolio' />
<meta property='og:image' content='/logo.png' />
<meta
property='og:description'
content='Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast'
/>
<meta property='og:title' content='Hazem Krimi' />
<meta
name='keywords'
content='Hazem, Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News'
/>
<title>Portfolio | Hazem Krimi</title>
</Head>
<Wrapper>
<div className='back' onClick={() => router.back()}>
<IconButton alt='Back' icon='/icons/arrow-left.svg' />
<span>Back</span>
</div>
<h1>Portfolio</h1>
<div className='projects-wrapper'>
{portfolioProjects.length !== 0 ? (
portfolioProjects.map(({ slug, ...rest }) => (
<Card {...rest} key={slug} href={`/portfolio/${slug}`} />
))
) : (
<h4>Nothing for now</h4>
)}
</div>
</Wrapper>
</>
);
};
export default Index;
export const getStaticProps = async () => {
const portfolioProjects = getPortfolioProjects();
return {
props: {
portfolioProjects
}
};
};
@@ -1,12 +1,12 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { getPortfolioPorjectsSlugs, getPortfolioProjectdata } from '../../utils/portfolio'; import { getPorjectsSlugs, getProjectdata } from '../../utils/projects';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'; import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
import { MDXProvider } from '@mdx-js/react'; import { MDXProvider } from '@mdx-js/react';
import { GetStaticPaths, GetStaticProps } from 'next'; import { GetStaticPaths, GetStaticProps } from 'next';
import { serialize } from 'next-mdx-remote/serialize'; import { serialize } from 'next-mdx-remote/serialize';
import matter from 'gray-matter'; import matter from 'gray-matter';
import { Wrapper } from '../../styles/portfolio/slug'; import { Wrapper } from '../../styles/projects/slug';
import Head from 'next/head'; import Head from 'next/head';
import IconButton from '../../components/IconButton'; import IconButton from '../../components/IconButton';
import CodeBlock from '../../components/CodeBlock'; import CodeBlock from '../../components/CodeBlock';
@@ -18,7 +18,7 @@ interface Props {
frontMatter: any; frontMatter: any;
} }
const PortfolioProject = ({ source, frontMatter }: Props) => { const Project = ({ source, frontMatter }: Props) => {
const router = useRouter(); const router = useRouter();
const htmlOverrides = { code: CodeBlock }; const htmlOverrides = { code: CodeBlock };
const mdxComponents = { Button: MDXButton }; const mdxComponents = { Button: MDXButton };
@@ -37,7 +37,10 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
content={ content={
frontMatter?.description frontMatter?.description
? frontMatter.description ? frontMatter.description
: 'Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' : `Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.`
} }
/> />
<link rel='canonical' href='https://hazemkrimi.tech' /> <link rel='canonical' href='https://hazemkrimi.tech' />
@@ -47,7 +50,10 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
content={ content={
frontMatter?.description frontMatter?.description
? frontMatter.description ? frontMatter.description
: 'Hazem Krimi is a Full Stack JavaScript Developer and a Software Engineering Enthusiast' : `Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.`
} }
/> />
<meta property='og:title' content={`${frontMatter?.title} | Hazem Krimi`} /> <meta property='og:title' content={`${frontMatter?.title} | Hazem Krimi`} />
@@ -56,7 +62,7 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
content={ content={
frontMatter?.tags frontMatter?.tags
? frontMatter.tags.join(' ') ? frontMatter.tags.join(' ')
: 'Hazem, Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News' : `Hazem, Krimi, Hazem Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, TypeScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News, Software Developer, Software Engineer, Full Stack TypeScript Developer, Next.js`
} }
/> />
<title>{`${frontMatter?.title} | Hazem Krimi`}</title> <title>{`${frontMatter?.title} | Hazem Krimi`}</title>
@@ -102,19 +108,19 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
); );
}; };
export default PortfolioProject; export default Project;
export const getStaticPaths: GetStaticPaths = async () => { export const getStaticPaths: GetStaticPaths = async () => {
const paths = getPortfolioPorjectsSlugs(); const paths = getPorjectsSlugs();
return { return {
paths, paths,
fallback: false fallback: false
}; };
}; };
export const getStaticProps: GetStaticProps = async ({ params }: any) => { export const getStaticProps: GetStaticProps = async ({ params }: any) => {
const portfolioProjectContent = await getPortfolioProjectdata(params.slug); const projectContent = await getProjectdata(params.slug);
if (!portfolioProjectContent) if (!projectContent)
return { return {
props: { props: {
source: undefined, source: undefined,
@@ -122,7 +128,7 @@ export const getStaticProps: GetStaticProps = async ({ params }: any) => {
} }
}; };
const { data, content } = matter(portfolioProjectContent); const { data, content } = matter(projectContent);
const mdxSource = await serialize(content, { const mdxSource = await serialize(content, {
scope: data scope: data
}); });
+79
View File
@@ -0,0 +1,79 @@
import { getProjects } from '../../utils/projects';
import { useRouter } from 'next/router';
import { Wrapper } from '../../styles/projects';
import Card from '../../components/Card';
import IconButton from '../../components/IconButton';
import Head from 'next/head';
interface Props {
projects: {
title: string;
description: string;
image?: string;
slug: string;
date: string;
tags?: string[];
}[];
}
const Index = ({ projects }: Props) => {
const router = useRouter();
return (
<>
<Head>
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
<meta name='author' content='Hazem Krimi' />
<meta
name='description'
content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/>
<link rel='canonical' href='https://hazemkrimi.tech' />
<meta property='og:image' content='/logo.png' />
<meta
property='og:description'
content='Hazem Krimi is an experienced Full Stack developer with a focus on building user-friendly
web and cross-platform mobile applications using cutting-edge
technologies. Passionate about ongoing learning and staying up-to-date
with the latest trends in software engineering.'
/>
<meta property='og:title' content='Hazem Krimi' />
<meta
name='keywords'
content='Hazem, Krimi, Hazem Krimi, Developer, Software, Engineer, Web, Mobile, Frontend, Backend, Fullstack, JavaScript, TypeScript, React.js, React Native, Node.js, Portfolio, Blog, Tutorials, Tech News, Software Developer, Software Engineer, Full Stack TypeScript Developer, Next.js'
/>
<title>Projects | Hazem Krimi</title>
</Head>
<Wrapper>
<div className='back' onClick={() => router.back()}>
<IconButton alt='Back' icon='/icons/arrow-left.svg' />
<span>Back</span>
</div>
<h1>Projects</h1>
<div className='projects-wrapper'>
{projects.length !== 0 ? (
projects.map(({ slug, ...rest }) => (
<Card {...rest} key={slug} href={`/projects/${slug}`} />
))
) : (
<h4>Nothing for now</h4>
)}
</div>
</Wrapper>
</>
);
};
export default Index;
export const getStaticProps = async () => {
const projects = getProjects();
return {
props: {
projects
}
};
};
+2 -2
View File
@@ -28,12 +28,12 @@ export const Wrapper = styled.div`
} }
.about, .about,
.portfolio, .projects,
.blog { .blog {
margin: 1rem 0rem; margin: 1rem 0rem;
} }
.portfolio { .projects {
margin-bottom: 3rem; margin-bottom: 3rem;
} }
+8 -8
View File
@@ -2,18 +2,18 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import matter from 'gray-matter'; import matter from 'gray-matter';
const portfolioProjects = path.join(process.cwd(), '_portfolio'); const projects = path.join(process.cwd(), '_portfolio');
export const getPortfolioProjects = () => { export const getProjects = () => {
try { try {
const fileNames = fs.readdirSync(portfolioProjects); const fileNames = fs.readdirSync(projects);
if (!fileNames) return []; if (!fileNames) return [];
const allPortfolioProjectsData = fileNames.map(filename => { const allPortfolioProjectsData = fileNames.map(filename => {
const slug = filename.replace('.mdx', ''); const slug = filename.replace('.mdx', '');
const fullPath = path.join(portfolioProjects, filename); const fullPath = path.join(projects, filename);
const fileContents = fs.readFileSync(fullPath, 'utf8'); const fileContents = fs.readFileSync(fullPath, 'utf8');
const { data } = matter(fileContents); const { data } = matter(fileContents);
@@ -43,9 +43,9 @@ export const getPortfolioProjects = () => {
} }
}; };
export const getPortfolioPorjectsSlugs = () => { export const getPorjectsSlugs = () => {
try { try {
const fileNames = fs.readdirSync(portfolioProjects); const fileNames = fs.readdirSync(projects);
if (!fileNames) return []; if (!fileNames) return [];
@@ -61,9 +61,9 @@ export const getPortfolioPorjectsSlugs = () => {
} }
}; };
export const getPortfolioProjectdata = async (slug: string) => { export const getProjectdata = async (slug: string) => {
try { try {
const fullPath = path.join(portfolioProjects, `${slug}.mdx`); const fullPath = path.join(projects, `${slug}.mdx`);
const postContent = fs.readFileSync(fullPath, 'utf8'); const postContent = fs.readFileSync(fullPath, 'utf8');
if (!postContent) return undefined; if (!postContent) return undefined;