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>
<div className='intro'>
<h2>Hi, I am Hazem</h2>
<h2>I Like Building Things</h2>
<h2 className='blue'>Software Developer</h2>
<h2>I Like Building Software</h2>
<h2 className='blue'>Full Stack TypeScript Developer</h2>
<h2 className='blue'>Life Long Learner</h2>
</div>
<div className='photo'>
+2 -2
View File
@@ -49,8 +49,8 @@ const MobileNav = ({ open, close }: Props) => {
</Button>
</div>
<div className='mobile-button-wrapper'>
<Button href='/portfolio' onClick={() => close()}>
Portfolio
<Button href='/projects' onClick={() => close()}>
Projects
</Button>
</div>
<div className='mobile-button-wrapper'>
+1 -1
View File
@@ -29,7 +29,7 @@ const Nav = () => {
icon={mode === 'dark' ? '/icons/sun.svg' : '/icons/moon.svg'}
onClick={toggle}
/>
<Button href='/portfolio'>Portfolio</Button>
<Button href='/projects'>Projects</Button>
<Button href='/blog'>Blog</Button>
<Button href='/contact'>Contact</Button>
<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='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: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
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>
</Head>
+9 -3
View File
@@ -39,7 +39,10 @@ const BlogPost = ({ source, frontMatter, text }: Props) => {
content={
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' />
@@ -49,7 +52,10 @@ const BlogPost = ({ source, frontMatter, text }: Props) => {
content={
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`} />
@@ -58,7 +64,7 @@ const BlogPost = ({ source, frontMatter, text }: Props) => {
content={
frontMatter?.tags
? 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>
+10 -4
View File
@@ -35,18 +35,24 @@ const About = () => {
<meta name='author' content='Hazem Krimi' />
<meta
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: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
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>
</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 { GetStaticProps } from 'next';
import { Wrapper } from '../styles/home';
@@ -16,7 +16,7 @@ interface Props {
date: string;
tags?: string[];
}[];
portfolioProjects: {
projects: {
title: string;
description: string;
slug: string;
@@ -25,7 +25,7 @@ interface Props {
}[];
}
const Index = ({ blogPosts, portfolioProjects }: Props) => {
const Index = ({ blogPosts, projects }: Props) => {
return (
<>
<Head>
@@ -33,18 +33,24 @@ const Index = ({ blogPosts, portfolioProjects }: Props) => {
<meta name='author' content='Hazem Krimi' />
<meta
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' />
<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'
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, 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>
</Head>
@@ -54,22 +60,19 @@ const Index = ({ blogPosts, portfolioProjects }: Props) => {
<h1>About</h1>
<div className='about'>
<p>
I am a software developer. I have experience as a full stack developer but I lean more
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.
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.
</p>
</div>
{portfolioProjects.length !== 0 && (
{projects.length !== 0 && (
<>
<h1>Portfolio</h1>
<Button href='/portfolio' className='blue'>
<h1>Projects</h1>
<Button href='/projects' className='blue'>
See More
</Button>
<div className='portfolio'>
<div className='projects'>
<div className='projects-wrapper'>
{portfolioProjects.slice(0, 3).map(({ slug, ...rest }) => (
<Card {...rest} key={slug} href={`/portfolio/${slug}`} />
{projects.slice(0, 3).map(({ slug, ...rest }) => (
<Card {...rest} key={slug} href={`/projects/${slug}`} />
))}
</div>
</div>
@@ -100,11 +103,11 @@ export default Index;
export const getStaticProps: GetStaticProps = async () => {
const blogPosts = getBlogPosts();
const portfolioProjects = getPortfolioProjects();
const projects = getProjects();
return {
props: {
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 { getPortfolioPorjectsSlugs, getPortfolioProjectdata } from '../../utils/portfolio';
import { getPorjectsSlugs, getProjectdata } from '../../utils/projects';
import { useRouter } from 'next/router';
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
import { MDXProvider } from '@mdx-js/react';
import { GetStaticPaths, GetStaticProps } from 'next';
import { serialize } from 'next-mdx-remote/serialize';
import matter from 'gray-matter';
import { Wrapper } from '../../styles/portfolio/slug';
import { Wrapper } from '../../styles/projects/slug';
import Head from 'next/head';
import IconButton from '../../components/IconButton';
import CodeBlock from '../../components/CodeBlock';
@@ -18,7 +18,7 @@ interface Props {
frontMatter: any;
}
const PortfolioProject = ({ source, frontMatter }: Props) => {
const Project = ({ source, frontMatter }: Props) => {
const router = useRouter();
const htmlOverrides = { code: CodeBlock };
const mdxComponents = { Button: MDXButton };
@@ -37,7 +37,10 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
content={
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' />
@@ -47,7 +50,10 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
content={
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`} />
@@ -56,7 +62,7 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
content={
frontMatter?.tags
? 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>
@@ -102,19 +108,19 @@ const PortfolioProject = ({ source, frontMatter }: Props) => {
);
};
export default PortfolioProject;
export default Project;
export const getStaticPaths: GetStaticPaths = async () => {
const paths = getPortfolioPorjectsSlugs();
const paths = getPorjectsSlugs();
return {
paths,
fallback: false
};
};
export const getStaticProps: GetStaticProps = async ({ params }: any) => {
const portfolioProjectContent = await getPortfolioProjectdata(params.slug);
const projectContent = await getProjectdata(params.slug);
if (!portfolioProjectContent)
if (!projectContent)
return {
props: {
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, {
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,
.portfolio,
.projects,
.blog {
margin: 1rem 0rem;
}
.portfolio {
.projects {
margin-bottom: 3rem;
}
+8 -8
View File
@@ -2,18 +2,18 @@ import fs from 'fs';
import path from 'path';
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 {
const fileNames = fs.readdirSync(portfolioProjects);
const fileNames = fs.readdirSync(projects);
if (!fileNames) return [];
const allPortfolioProjectsData = fileNames.map(filename => {
const slug = filename.replace('.mdx', '');
const fullPath = path.join(portfolioProjects, filename);
const fullPath = path.join(projects, filename);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const { data } = matter(fileContents);
@@ -43,9 +43,9 @@ export const getPortfolioProjects = () => {
}
};
export const getPortfolioPorjectsSlugs = () => {
export const getPorjectsSlugs = () => {
try {
const fileNames = fs.readdirSync(portfolioProjects);
const fileNames = fs.readdirSync(projects);
if (!fileNames) return [];
@@ -61,9 +61,9 @@ export const getPortfolioPorjectsSlugs = () => {
}
};
export const getPortfolioProjectdata = async (slug: string) => {
export const getProjectdata = async (slug: string) => {
try {
const fullPath = path.join(portfolioProjects, `${slug}.mdx`);
const fullPath = path.join(projects, `${slug}.mdx`);
const postContent = fs.readFileSync(fullPath, 'utf8');
if (!postContent) return undefined;