mirror of
https://github.com/hazemKrimi/personal-website.git
synced 2026-05-01 18:00:26 +00:00
Refactoring components
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
NEXT_PUBLIC_FORMSPREE_KEY=FORMSPREE_KEY
|
||||||
|
NEXT_PUBLIC_GOOGLE_ANALYTICS_KEY=GOOGLE_ANALYTICS_KEY
|
||||||
@@ -1,18 +1,8 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { StyledCard } from './styles';
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
import { StyledCard } from './styles';
|
||||||
|
import { Props } from './types';
|
||||||
|
|
||||||
interface Props {
|
const Card = ({ title, description, image, tags, href, target, onClick }: Props) => {
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
image?: string;
|
|
||||||
tags?: string[];
|
|
||||||
href: string;
|
|
||||||
target?: HTMLAnchorElement['target'];
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Card: FC<Props> = ({ title, description, image, tags, href, target, onClick }) => {
|
|
||||||
return (
|
return (
|
||||||
<StyledCard href={href} onClick={onClick} image={image ? Boolean(image) : undefined} target={target}>
|
<StyledCard href={href} onClick={onClick} image={image ? Boolean(image) : undefined} target={target}>
|
||||||
<div className='card-content'>
|
<div className='card-content'>
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export interface Props {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
image?: string;
|
||||||
|
tags?: string[];
|
||||||
|
href: string;
|
||||||
|
target?: HTMLAnchorElement['target'];
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import Highlight, { defaultProps, Language } from 'prism-react-renderer';
|
import Highlight, { defaultProps, Language } from 'prism-react-renderer';
|
||||||
import theme from 'prism-react-renderer/themes/vsDark';
|
import theme from 'prism-react-renderer/themes/vsDark';
|
||||||
|
import { Props } from './types';
|
||||||
import { Line, LineContent, LineNo, Pre } from './styles';
|
import { Line, LineContent, LineNo, Pre } from './styles';
|
||||||
|
|
||||||
const CodeBlock: FC<{ className: string, children: React.ReactNode }> = ({ children, className }) => {
|
const CodeBlock = ({ children, className }: Props) => {
|
||||||
const language = className.replace(/language-/, '') as Language;
|
const language = className.replace(/language-/, '') as Language;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface Props {
|
||||||
|
className: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { FC, useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { ThemeContext } from '../../styles/theme';
|
import { ThemeContext } from '../../styles/theme';
|
||||||
import { StyledFooter } from './styles';
|
import { StyledFooter } from './styles';
|
||||||
import IconButton from '../../components/IconButton';
|
import IconButton from '../IconButton';
|
||||||
|
|
||||||
const Footer: FC = () => {
|
const Footer = () => {
|
||||||
const { mode } = useContext(ThemeContext);
|
const { mode } = useContext(ThemeContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { Wrapper } from './styles';
|
import { Wrapper } from './styles';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
const Hero: FC = () => (
|
const Hero = () => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<div className='intro'>
|
<div className='intro'>
|
||||||
<h2>Hi, I am Hazem</h2>
|
<h2>Hi, I am Hazem</h2>
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import Image from 'next/image';
|
|
||||||
import Link from 'next/link';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
alt: string;
|
|
||||||
icon: string;
|
|
||||||
width?: number;
|
|
||||||
height?: number;
|
|
||||||
href?: string;
|
|
||||||
target?: HTMLAnchorElement['target'];
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Btn = styled(Link)`
|
|
||||||
cursor: pointer;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const IconButton: FC<Props & { className?: string }> = ({
|
|
||||||
alt,
|
|
||||||
icon,
|
|
||||||
href,
|
|
||||||
target,
|
|
||||||
onClick,
|
|
||||||
className,
|
|
||||||
width = 24,
|
|
||||||
height = 24
|
|
||||||
}) => {
|
|
||||||
return !href ? (
|
|
||||||
<Btn href='#' onClick={onClick} className={className}>
|
|
||||||
<Image alt={alt} src={icon} width={width} height={height} />
|
|
||||||
</Btn>
|
|
||||||
) : (
|
|
||||||
<Btn href={href} target={target} onClick={onClick} className={className}>
|
|
||||||
<Image alt={alt} src={icon} width={width} height={height} />
|
|
||||||
</Btn>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default IconButton;
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import Image from 'next/image';
|
||||||
|
import { Props } from './types';
|
||||||
|
import { StyledButton, StyledLink } from './styles';
|
||||||
|
|
||||||
|
const IconButton = ({
|
||||||
|
alt,
|
||||||
|
icon,
|
||||||
|
href,
|
||||||
|
target,
|
||||||
|
onClick,
|
||||||
|
className,
|
||||||
|
width = 24,
|
||||||
|
height = 24
|
||||||
|
}: Props) => href ? (
|
||||||
|
<StyledLink href={href} target={target} onClick={onClick} className={className}>
|
||||||
|
<Image alt={alt} src={icon} width={width} height={height} />
|
||||||
|
</StyledLink>
|
||||||
|
) : (
|
||||||
|
<StyledButton onClick={onClick} className={className}>
|
||||||
|
<Image alt={alt} src={icon} width={width} height={height} />
|
||||||
|
</StyledButton>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default IconButton;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import styled, { css } from 'styled-components';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
const sharedStyles = css`
|
||||||
|
cursor: pointer;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const StyledLink = styled(Link)`
|
||||||
|
${sharedStyles}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const StyledButton = styled.button`
|
||||||
|
${sharedStyles}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export interface Props {
|
||||||
|
alt: string;
|
||||||
|
icon: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
href?: string;
|
||||||
|
target?: HTMLAnchorElement['target'];
|
||||||
|
onClick?: () => void;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
import React, { FC } from 'react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
placeholder?: string;
|
|
||||||
type: 'text' | 'email';
|
|
||||||
variant: 'small' | 'big';
|
|
||||||
name: string;
|
|
||||||
value: string;
|
|
||||||
required?: boolean;
|
|
||||||
onChange?: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SmallField = styled.input`
|
|
||||||
border: none;
|
|
||||||
padding: 1rem;
|
|
||||||
background: var(--secondary-background);
|
|
||||||
color: var(--text);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const BigField = styled.textarea`
|
|
||||||
resize: none;
|
|
||||||
border: none;
|
|
||||||
padding: 1rem;
|
|
||||||
background: var(--secondary-background);
|
|
||||||
color: var(--text);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Input: FC<Props & { className?: string }> = ({
|
|
||||||
type = 'text',
|
|
||||||
variant = 'small',
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
required,
|
|
||||||
placeholder,
|
|
||||||
className,
|
|
||||||
onChange
|
|
||||||
}) => {
|
|
||||||
return variant === 'small' ? (
|
|
||||||
<SmallField
|
|
||||||
type={type}
|
|
||||||
name={name}
|
|
||||||
value={value}
|
|
||||||
required={required}
|
|
||||||
placeholder={placeholder}
|
|
||||||
className={className}
|
|
||||||
onChange={onChange}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<BigField
|
|
||||||
name={name}
|
|
||||||
value={value}
|
|
||||||
required={required}
|
|
||||||
placeholder={placeholder}
|
|
||||||
className={className}
|
|
||||||
onChange={onChange}
|
|
||||||
rows={3}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Input;
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { BigField, SmallField } from "./styles";
|
||||||
|
import { Props } from "./types";
|
||||||
|
|
||||||
|
const Input = ({
|
||||||
|
type = 'text',
|
||||||
|
variant = 'small',
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
required,
|
||||||
|
placeholder,
|
||||||
|
className,
|
||||||
|
onChange
|
||||||
|
}: Props) => {
|
||||||
|
return variant === 'small' ? (
|
||||||
|
<SmallField
|
||||||
|
type={type}
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
|
required={required}
|
||||||
|
placeholder={placeholder}
|
||||||
|
className={className}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<BigField
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
|
required={required}
|
||||||
|
placeholder={placeholder}
|
||||||
|
className={className}
|
||||||
|
onChange={onChange}
|
||||||
|
rows={3}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Input;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export const SmallField = styled.input`
|
||||||
|
border: none;
|
||||||
|
padding: 1rem;
|
||||||
|
background: var(--secondary-background);
|
||||||
|
color: var(--text);
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const BigField = styled.textarea`
|
||||||
|
resize: none;
|
||||||
|
border: none;
|
||||||
|
padding: 1rem;
|
||||||
|
background: var(--secondary-background);
|
||||||
|
color: var(--text);
|
||||||
|
`;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export interface Props {
|
||||||
|
placeholder?: string;
|
||||||
|
type: 'text' | 'email';
|
||||||
|
variant: 'small' | 'big';
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
required?: boolean;
|
||||||
|
onChange?: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { ThemeContext } from '../../styles/theme';
|
import { ThemeContext } from '../../styles/theme';
|
||||||
import { Props } from './types';
|
import { Props } from './types';
|
||||||
import { Btn } from './styles';
|
import { StyledLink, StyledButton } from './styles';
|
||||||
|
|
||||||
const MDXButton = ({
|
const MDXButton = ({
|
||||||
variant = 'text',
|
variant = 'text',
|
||||||
@@ -15,7 +15,7 @@ const MDXButton = ({
|
|||||||
const { mode } = useContext(ThemeContext);
|
const { mode } = useContext(ThemeContext);
|
||||||
|
|
||||||
return link ? (
|
return link ? (
|
||||||
<Btn
|
<StyledLink
|
||||||
href={link}
|
href={link}
|
||||||
target={target}
|
target={target}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
@@ -25,11 +25,11 @@ const MDXButton = ({
|
|||||||
className={className}
|
className={className}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Btn>
|
</StyledLink>
|
||||||
) : (
|
) : (
|
||||||
<Btn href="#" variant={variant} type={type} mode={mode} disabled={disabled} className={className}>
|
<StyledButton variant={variant} type={type} mode={mode} disabled={disabled} className={className}>
|
||||||
{children}
|
{children}
|
||||||
</Btn>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import styled from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import { Props } from './types';
|
import { Props } from './types';
|
||||||
|
|
||||||
export const Btn = styled(Link)<Props>`
|
export const sharedStyles = css<Props>`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: ${({ variant }) =>
|
display: ${({ variant }) =>
|
||||||
['action', 'outline'].includes(variant as string) ? 'block' : 'inline'};
|
['action', 'outline'].includes(variant as string) ? 'block' : 'inline'};
|
||||||
width: ${({ variant }) => (['action', 'outline'].includes(variant as string) ? '100%' : 'auto')};
|
width: ${({ variant }) => (['action', 'outline'].includes(variant as string) ? '100%' : 'auto')};
|
||||||
/* TODO: fix theme blue color problem */
|
|
||||||
background: ${({ variant }) => (variant === 'action' ? '#1573CA' : 'none')};
|
background: ${({ variant }) => (variant === 'action' ? '#1573CA' : 'none')};
|
||||||
color: ${({ variant, mode }) =>
|
color: ${({ variant, mode }) =>
|
||||||
variant === 'action' ? 'white' : mode === 'dark' ? 'white' : 'black'};
|
variant === 'action' ? 'white' : mode === 'dark' ? 'white' : 'black'};
|
||||||
@@ -25,9 +24,7 @@ export const Btn = styled(Link)<Props>`
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 250ms ease-in-out;
|
transition: color 250ms ease-in-out;
|
||||||
|
|
||||||
${({ disabled }) =>
|
${({ disabled }) => disabled && `
|
||||||
disabled &&
|
|
||||||
`
|
|
||||||
background: gray;
|
background: gray;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
`}
|
`}
|
||||||
@@ -37,3 +34,11 @@ export const Btn = styled(Link)<Props>`
|
|||||||
['action', 'outline'].includes(variant as string) ? '.5rem .75rem' : '0rem'};
|
['action', 'outline'].includes(variant as string) ? '.5rem .75rem' : '0rem'};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const StyledLink = styled(Link)<Props>`
|
||||||
|
${sharedStyles}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const StyledButton = styled.button<Omit<Props, 'href'>>`
|
||||||
|
${sharedStyles}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { FC, useContext, useRef, useEffect } from 'react';
|
import { useContext, useRef, useEffect } from 'react';
|
||||||
import { ThemeContext } from '../../styles/theme';
|
import { ThemeContext } from '../../styles/theme';
|
||||||
import { Props } from './types';
|
import { Props } from './types';
|
||||||
import { Bar } from './styles';
|
import { Bar } from './styles';
|
||||||
import IconButton from '../IconButton';
|
import IconButton from '../IconButton';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
|
|
||||||
const MobileNav: FC<Props> = ({ open, close }) => {
|
const MobileNav = ({ open, close }: Props) => {
|
||||||
const { mode, toggle } = useContext(ThemeContext);
|
const { mode, toggle } = useContext(ThemeContext);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ const MobileNav: FC<Props> = ({ open, close }) => {
|
|||||||
close();
|
close();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{mode === 'dark' ? 'Light Mode' : 'Dark Mode'}
|
{mode === 'dark' ? 'Switch to Light Mode' : 'Switch to Dark Mode'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className='mobile-button-wrapper'>
|
<div className='mobile-button-wrapper'>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useContext, useState } from 'react';
|
import { useContext, useState } from 'react';
|
||||||
import { ThemeContext } from '../../styles/theme';
|
import { ThemeContext } from '../../styles/theme';
|
||||||
import { Bar } from './styles';
|
import { Bar } from './styles';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
@@ -7,7 +7,7 @@ import Button from '../Button';
|
|||||||
import IconButton from '../IconButton';
|
import IconButton from '../IconButton';
|
||||||
import MobileNav from '../MobileNav';
|
import MobileNav from '../MobileNav';
|
||||||
|
|
||||||
const Nav: FC = () => {
|
const Nav = () => {
|
||||||
const [mobileNavOpen, setMobileNavOpen] = useState<boolean>(false);
|
const [mobileNavOpen, setMobileNavOpen] = useState<boolean>(false);
|
||||||
const { mode, toggle } = useContext(ThemeContext);
|
const { mode, toggle } = useContext(ThemeContext);
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ const Nav: FC = () => {
|
|||||||
Resume
|
Resume
|
||||||
</Button>
|
</Button>
|
||||||
<IconButton
|
<IconButton
|
||||||
alt='Theme toggler'
|
alt='Hamburger menu'
|
||||||
icon={mode === 'dark' ? '/icons/light-menu.svg' : '/icons/dark-menu.svg'}
|
icon={mode === 'dark' ? '/icons/light-menu.svg' : '/icons/dark-menu.svg'}
|
||||||
onClick={() => setMobileNavOpen(true)}
|
onClick={() => setMobileNavOpen(true)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+1
-2
@@ -1,10 +1,9 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import IconButton from '../components/IconButton';
|
import IconButton from '../components/IconButton';
|
||||||
import { Wrapper } from '../styles/404';
|
import { Wrapper } from '../styles/404';
|
||||||
|
|
||||||
const NotFound: FC = () => {
|
const NotFound = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { getBlogPostsSlugs, getBlogPostdata } from '../../utils/blog';
|
import { getBlogPostsSlugs, getBlogPostdata } from '../../utils/blog';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
|
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
|
||||||
@@ -19,7 +19,7 @@ interface Props {
|
|||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BlogPost: FC<Props> = ({ source, frontMatter, text }) => {
|
const BlogPost = ({ source, frontMatter, text }: Props) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const stats = readingTime(text);
|
const stats = readingTime(text);
|
||||||
const htmlOverrides = { code: CodeBlock };
|
const htmlOverrides = { code: CodeBlock };
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import React, { FC } from 'react';
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { getBlogPosts } from '../../utils/blog';
|
import { getBlogPosts } from '../../utils/blog';
|
||||||
import { Wrapper } from '../../styles/blog';
|
import { Wrapper } from '../../styles/blog';
|
||||||
@@ -18,7 +17,7 @@ interface Props {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Index: FC<Props> = ({ blogPosts }) => {
|
const Index = ({ blogPosts }: Props) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
import React, { FC, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useForm, ValidationError } from '@formspree/react';
|
import { useForm, ValidationError } from '@formspree/react';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { Wrapper } from '../styles/contact';
|
import { Wrapper } from '../styles/contact';
|
||||||
import Input from '../components/Input';
|
import Input from '../components/Input';
|
||||||
import MDXButton from '../components/MDXButton';
|
import MDXButton from '../components/MDXButton';
|
||||||
|
|
||||||
const About: FC = () => {
|
const About = () => {
|
||||||
const [form, setForm] = useState<{ name: string; email: string; message: string }>({
|
const [form, setForm] = useState<{ name: string; email: string; message: string }>({
|
||||||
name: '',
|
name: '',
|
||||||
email: '',
|
email: '',
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { getPortfolioProjects } from '../utils/portfolio';
|
import { getPortfolioProjects } from '../utils/portfolio';
|
||||||
import { getBlogPosts } from '../utils/blog';
|
import { getBlogPosts } from '../utils/blog';
|
||||||
import { GetStaticProps } from 'next';
|
import { GetStaticProps } from 'next';
|
||||||
@@ -26,7 +25,7 @@ interface Props {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Index: FC<Props> = ({ blogPosts, portfolioProjects }) => {
|
const Index = ({ blogPosts, portfolioProjects }: Props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { getPortfolioPorjectsSlugs, getPortfolioProjectdata } from '../../utils/portfolio';
|
import { getPortfolioPorjectsSlugs, getPortfolioProjectdata } from '../../utils/portfolio';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
|
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
|
||||||
@@ -18,7 +18,7 @@ interface Props {
|
|||||||
frontMatter: any;
|
frontMatter: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PortfolioProject: FC<Props> = ({ source, frontMatter }) => {
|
const PortfolioProject = ({ 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 };
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import React, { FC } from 'react';
|
|
||||||
import { getPortfolioProjects } from '../../utils/portfolio';
|
import { getPortfolioProjects } from '../../utils/portfolio';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { Wrapper } from '../../styles/portfolio';
|
import { Wrapper } from '../../styles/portfolio';
|
||||||
@@ -17,7 +16,7 @@ interface Props {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Index: FC<Props> = ({ portfolioProjects }) => {
|
const Index = ({ portfolioProjects }: Props) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user