diff --git a/.editorconfig b/.editorconfig index 88a8ef0..4be2ba3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,5 @@ [*.{ts,js,json,tsx,md,mdx,html}] charset = utf-8 -indent_style = tab +indent_style = space indent_size = 2 quote_type= single \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..22c8bbc --- /dev/null +++ b/.prettierignore @@ -0,0 +1,32 @@ +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7adfe41 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "printWidth": 80, + "singleQuote": true, + "jsxSingleQuote": true, + "tabWidth": 2, + "semi": true, + "quoteProps": "as-needed" +} diff --git a/components/Button/index.tsx b/components/Button/index.tsx index c2dfc8b..7c0ff53 100644 --- a/components/Button/index.tsx +++ b/components/Button/index.tsx @@ -2,16 +2,22 @@ import { Props } from './types'; import { StyledButton } from './styles'; const Button = ({ - variant = 'text', - href, - target, - onClick, - children, - className + variant = 'text', + href, + target, + onClick, + children, + className, }: Props) => ( - - {children} - + + {children} + ); export default Button; diff --git a/components/Button/styles.tsx b/components/Button/styles.tsx index 3c80f14..640f9da 100644 --- a/components/Button/styles.tsx +++ b/components/Button/styles.tsx @@ -3,45 +3,49 @@ import Link from 'next/link'; import { Props } from './types'; export const StyledButton = styled(Link)` - position: relative; - display: inline; - cursor: pointer; - background: none; - color: var(--text); - border: ${({ variant }) => - variant === 'outline' ? '2px solid var(--text)' : '2px solid transparent'}; - font-weight: bold; - text-transform: ${({ variant }) => (variant === 'outline' ? 'uppercase' : 'inherit')}; - padding: ${({ variant }) => (variant === 'outline' ? '.5rem 1rem' : '0rem')}; - text-align: left; - text-decoration: none; - transition: color 250ms ease-in-out, border 250ms ease-in-out; - z-index: 1; + position: relative; + display: inline; + cursor: pointer; + background: none; + color: var(--text); + border: ${({ variant }) => + variant === 'outline' ? '2px solid var(--text)' : '2px solid transparent'}; + font-weight: bold; + text-transform: ${({ variant }) => + variant === 'outline' ? 'uppercase' : 'inherit'}; + padding: ${({ variant }) => (variant === 'outline' ? '.5rem 1rem' : '0rem')}; + text-align: left; + text-decoration: none; + transition: color 250ms ease-in-out, border 250ms ease-in-out; + z-index: 1; - @media (max-width: 768px) { - padding: ${({ variant }) => (variant === 'outline' ? '.5rem .75rem' : '0rem')}; - } + @media (max-width: 768px) { + padding: ${({ variant }) => + variant === 'outline' ? '.5rem .75rem' : '0rem'}; + } - &::before { - content: ''; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - z-index: -1; - background-color: ${({ variant }) => (variant === 'outline' ? 'var(--text)' : 'inherit')}; - transition: transform 250ms ease-in-out; - transform: scaleX(0); - transform-origin: left; - } + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: -1; + background-color: ${({ variant }) => + variant === 'outline' ? 'var(--text)' : 'inherit'}; + transition: transform 250ms ease-in-out; + transform: scaleX(0); + transform-origin: left; + } - &:hover { - color: ${({ variant }) => (variant === 'outline' ? 'var(--background)' : 'inherit')}; - border: 2px solid transparent; - } + &:hover { + color: ${({ variant }) => + variant === 'outline' ? 'var(--background)' : 'inherit'}; + border: 2px solid transparent; + } - &:hover::before { - transform: scaleX(1); - } + &:hover::before { + transform: scaleX(1); + } `; diff --git a/components/Button/types.ts b/components/Button/types.ts index f95cc77..30dc416 100644 --- a/components/Button/types.ts +++ b/components/Button/types.ts @@ -1,8 +1,8 @@ export type Props = { - variant?: 'outline' | 'text'; - href: string; - target?: HTMLAnchorElement['target']; - onClick?: () => void; - children: React.ReactNode; - className?: string; + variant?: 'outline' | 'text'; + href: string; + target?: HTMLAnchorElement['target']; + onClick?: () => void; + children: React.ReactNode; + className?: string; }; diff --git a/components/Card/index.tsx b/components/Card/index.tsx index cf48e17..bfeed71 100644 --- a/components/Card/index.tsx +++ b/components/Card/index.tsx @@ -2,27 +2,40 @@ import Image from 'next/image'; import { StyledCard } from './styles'; import { Props } from './types'; -const Card = ({ title, description, image, tags, href, target, onClick }: Props) => { - return ( - -
-

{title}

-

{description}

- {tags && ( -
- {tags.map((tag, index) => ( - #{tag}  - ))} -
- )} -
- {image && ( -
- {title} -
- )} -
- ); +const Card = ({ + title, + description, + image, + tags, + href, + target, + onClick, +}: Props) => { + return ( + +
+

{title}

+

{description}

+ {tags && ( +
+ {tags.map((tag, index) => ( + #{tag}  + ))} +
+ )} +
+ {image && ( +
+ {title} +
+ )} +
+ ); }; export default Card; diff --git a/components/Card/styles.tsx b/components/Card/styles.tsx index 120d645..bed96bc 100644 --- a/components/Card/styles.tsx +++ b/components/Card/styles.tsx @@ -2,75 +2,76 @@ import styled from 'styled-components'; import Link from 'next/link'; export const StyledCard = styled(Link)<{ image?: boolean }>` - cursor: pointer; - width: 100%; - display: grid; - grid-template-columns: ${({ image }) => (image ? 'auto 9.375rem' : 'auto')}; - align-items: stretch; - transition: color 0ms ease-in-out; - text-decoration: none; - color: var(--text); + cursor: pointer; + width: 100%; + display: grid; + grid-template-columns: ${({ image }) => (image ? 'auto 9.375rem' : 'auto')}; + align-items: stretch; + transition: color 0ms ease-in-out; + text-decoration: none; + color: var(--text); - @media (max-width: 320px) { - grid-template-columns: ${({ image }) => (image ? 'auto 7.813rem' : 'auto')}; - } + @media (max-width: 320px) { + grid-template-columns: ${({ image }) => (image ? 'auto 7.813rem' : 'auto')}; + } - @media (min-width: 1440px) { - grid-template-columns: ${({ image }) => (image ? 'auto 15.625rem' : 'auto')}; - } + @media (min-width: 1440px) { + grid-template-columns: ${({ image }) => + image ? 'auto 15.625rem' : 'auto'}; + } - &:hover { - & > div { - background: ${({ theme }) => theme.colors.blue}; + &:hover { + & > div { + background: ${({ theme }) => theme.colors.blue}; - * { - color: ${({ theme }) => theme.colors.dark.text} !important; - } - } + * { + color: ${({ theme }) => theme.colors.dark.text} !important; + } + } - img { - filter: ${({ image }) => (image ? 'grayscale(80%)' : 'none')}; - } - } + img { + filter: ${({ image }) => (image ? 'grayscale(80%)' : 'none')}; + } + } - .card-content { - padding: 1rem 0rem; - background: var(--secondary-background); - display: grid; - row-gap: 0.5rem; + .card-content { + padding: 1rem 0rem; + background: var(--secondary-background); + display: grid; + row-gap: 0.5rem; - @media (max-width: 768px) { - padding: 0.75rem 0rem; - } - } + @media (max-width: 768px) { + padding: 0.75rem 0rem; + } + } - .card-image { - position: relative; - width: 100%; - } + .card-image { + position: relative; + width: 100%; + } - h3, - p, - .tags-wrapper { - padding: 0rem 1rem; + h3, + p, + .tags-wrapper { + padding: 0rem 1rem; - @media (max-width: 768px) { - padding: 0rem 0.5rem; - } - } + @media (max-width: 768px) { + padding: 0rem 0.5rem; + } + } - h3 { - font-size: 1.3rem; - } + h3 { + font-size: 1.3rem; + } - .tags-wrapper { - display: flex; - flex-direction: row; - align-content: center; - flex-wrap: wrap; - } + .tags-wrapper { + display: flex; + flex-direction: row; + align-content: center; + flex-wrap: wrap; + } - span { - font-size: 0.7rem; - } + span { + font-size: 0.7rem; + } `; diff --git a/components/Card/types.ts b/components/Card/types.ts index 6661255..2b8e27e 100644 --- a/components/Card/types.ts +++ b/components/Card/types.ts @@ -1,9 +1,9 @@ export interface Props { - title: string; - description: string; - image?: string; - tags?: string[]; - href: string; - target?: HTMLAnchorElement['target']; - onClick?: () => void; -} \ No newline at end of file + title: string; + description: string; + image?: string; + tags?: string[]; + href: string; + target?: HTMLAnchorElement['target']; + onClick?: () => void; +} diff --git a/components/CodeBlock/index.tsx b/components/CodeBlock/index.tsx index c811cfb..be5d7ed 100644 --- a/components/CodeBlock/index.tsx +++ b/components/CodeBlock/index.tsx @@ -4,31 +4,31 @@ import { Props } from './types'; import { Line, LineContent, LineNo, Pre } from './styles'; const CodeBlock = ({ children, className }: Props) => { - const language = className.replace(/language-/, '') as Language; + const language = className.replace(/language-/, '') as Language; - return ( - - {({ className, style, tokens, getLineProps, getTokenProps }) => ( -
-					{tokens.map((line, i) => (
-						
-							{i + 1}
-							
-								{line.map((token, key) => (
-									
-								))}
-							
-						
-					))}
-				
- )} -
- ); + return ( + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+          {tokens.map((line, i) => (
+            
+              {i + 1}
+              
+                {line.map((token, key) => (
+                  
+                ))}
+              
+            
+          ))}
+        
+ )} +
+ ); }; export default CodeBlock; diff --git a/components/CodeBlock/styles.tsx b/components/CodeBlock/styles.tsx index 710b89d..502a527 100644 --- a/components/CodeBlock/styles.tsx +++ b/components/CodeBlock/styles.tsx @@ -1,24 +1,24 @@ import styled from 'styled-components'; export const Pre = styled.pre` - text-align: left; - margin: 1em 0; - padding: 0.5em; - overflow: scroll; + text-align: left; + margin: 1em 0; + padding: 0.5em; + overflow: scroll; `; export const Line = styled.div` - display: table-row; + display: table-row; `; export const LineNo = styled.span` - display: table-cell; - text-align: right; - padding-right: 1em; - user-select: none; - opacity: 0.5; + display: table-cell; + text-align: right; + padding-right: 1em; + user-select: none; + opacity: 0.5; `; export const LineContent = styled.span` - display: table-cell; + display: table-cell; `; diff --git a/components/CodeBlock/types.ts b/components/CodeBlock/types.ts index 6e46e87..eff76be 100644 --- a/components/CodeBlock/types.ts +++ b/components/CodeBlock/types.ts @@ -1,4 +1,4 @@ export interface Props { - className: string; - children: React.ReactNode; -} \ No newline at end of file + className: string; + children: React.ReactNode; +} diff --git a/components/Container.tsx b/components/Container.tsx index 7d73ddb..058450c 100644 --- a/components/Container.tsx +++ b/components/Container.tsx @@ -1,12 +1,12 @@ import styled from 'styled-components'; const Container = styled.div` - width: 85%; - margin: auto; + width: 85%; + margin: auto; - @media (max-width: 768px) { - width: 95%; - } + @media (max-width: 768px) { + width: 95%; + } `; export default Container; diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index daa74b3..4462214 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -4,39 +4,51 @@ import { StyledFooter } from './styles'; import IconButton from '../IconButton'; const Footer = () => { - const { mode } = useContext(ThemeContext); + const { mode } = useContext(ThemeContext); - return ( - -
- - - -
-

Hazem Krimi © {new Date().getFullYear()}

-
- ); + return ( + +
+ + + +
+

Hazem Krimi © {new Date().getFullYear()}

+
+ ); }; export default Footer; diff --git a/components/Footer/styles.tsx b/components/Footer/styles.tsx index 9415778..735753c 100644 --- a/components/Footer/styles.tsx +++ b/components/Footer/styles.tsx @@ -1,41 +1,41 @@ import styled from 'styled-components'; export const StyledFooter = styled.footer` - position: absolute; - bottom: 0; - min-height: 100px; - width: 85%; - margin: auto; - display: grid; - grid-template-columns: repeat(2, 1fr); - column-gap: 2rem; - justify-content: flex-end; - align-content: center; - padding: 1rem 0rem; + position: absolute; + bottom: 0; + min-height: 100px; + width: 85%; + margin: auto; + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 2rem; + justify-content: flex-end; + align-content: center; + padding: 1rem 0rem; - @media (max-width: 768px) { - width: 95%; - } + @media (max-width: 768px) { + width: 95%; + } - .contact { - display: grid; - grid-template-columns: repeat(auto-fill, 16px); - column-gap: 1rem; - align-items: center; - justify-content: flex-start; + .contact { + display: grid; + grid-template-columns: repeat(auto-fill, 16px); + column-gap: 1rem; + align-items: center; + justify-content: flex-start; - * { - user-select: none; - } + * { + user-select: none; + } - @media (max-width: 768px) { - column-gap: 0.5rem; - } - } + @media (max-width: 768px) { + column-gap: 0.5rem; + } + } - p { - display: inline; - text-align: right; - font-weight: bold; - } + p { + display: inline; + text-align: right; + font-weight: bold; + } `; diff --git a/components/Hero/index.tsx b/components/Hero/index.tsx index f25aed6..ce2853f 100644 --- a/components/Hero/index.tsx +++ b/components/Hero/index.tsx @@ -2,17 +2,17 @@ import { Wrapper } from './styles'; import Image from 'next/image'; const Hero = () => ( - -
-

Hi, I am Hazem

-

I Like Building Software

-

Full Stack TypeScript Developer

-

Life Long Learner

-
-
- Hazem Krimi -
-
+ +
+

Hi, I am Hazem

+

I Like Building Software

+

Full Stack TypeScript Developer

+

Life Long Learner

+
+
+ Hazem Krimi +
+
); export default Hero; diff --git a/components/Hero/styles.tsx b/components/Hero/styles.tsx index 6065721..a4183ff 100644 --- a/components/Hero/styles.tsx +++ b/components/Hero/styles.tsx @@ -1,35 +1,35 @@ import styled from 'styled-components'; export const Wrapper = styled.div` - min-height: 45vh; - display: grid; - grid-template-columns: 1fr 32.188rem; - align-items: center; - height: auto; - text-align: left; + min-height: 45vh; + display: grid; + grid-template-columns: 1fr 32.188rem; + align-items: center; + height: auto; + text-align: left; - @media (max-width: 1024px) { - min-height: 35vh; - grid-template-columns: 1fr; + @media (max-width: 1024px) { + min-height: 35vh; + grid-template-columns: 1fr; - .photo { - display: none; - } - } + .photo { + display: none; + } + } - h2 { - font-size: 1.5rem; + h2 { + font-size: 1.5rem; - @media (min-width: 1440px) { - font-size: 2rem; - } + @media (min-width: 1440px) { + font-size: 2rem; + } - @media (min-width: 2560px) { - font-size: 3.5rem; - } - } + @media (min-width: 2560px) { + font-size: 3.5rem; + } + } - .blue { - color: ${({ theme }) => theme.colors.blue}; - } + .blue { + color: ${({ theme }) => theme.colors.blue}; + } `; diff --git a/components/IconButton/index.tsx b/components/IconButton/index.tsx index 96792c0..390d037 100644 --- a/components/IconButton/index.tsx +++ b/components/IconButton/index.tsx @@ -3,22 +3,28 @@ import { Props } from './types'; import { StyledButton, StyledLink } from './styles'; const IconButton = ({ - alt, - icon, - href, - target, - onClick, - className, - width = 24, - height = 24 -}: Props) => href ? ( - - {alt} - - ) : ( - - {alt} - - ); + alt, + icon, + href, + target, + onClick, + className, + width = 24, + height = 24, +}: Props) => + href ? ( + + {alt} + + ) : ( + + {alt} + + ); export default IconButton; diff --git a/components/IconButton/styles.tsx b/components/IconButton/styles.tsx index de75887..f75a111 100644 --- a/components/IconButton/styles.tsx +++ b/components/IconButton/styles.tsx @@ -2,17 +2,17 @@ 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; + cursor: pointer; + background: none; + border: none; + display: inline-flex; + align-items: center; `; export const StyledLink = styled(Link)` - ${sharedStyles} + ${sharedStyles} `; export const StyledButton = styled.button` - ${sharedStyles} -`; \ No newline at end of file + ${sharedStyles} +`; diff --git a/components/IconButton/types.ts b/components/IconButton/types.ts index 3530902..9dc87cd 100644 --- a/components/IconButton/types.ts +++ b/components/IconButton/types.ts @@ -1,10 +1,10 @@ export interface Props { - alt: string; - icon: string; - width?: number; - height?: number; - href?: string; - target?: HTMLAnchorElement['target']; - onClick?: () => void; - className?: string; -} \ No newline at end of file + alt: string; + icon: string; + width?: number; + height?: number; + href?: string; + target?: HTMLAnchorElement['target']; + onClick?: () => void; + className?: string; +} diff --git a/components/Input/index.tsx b/components/Input/index.tsx index b5adaca..c1b2287 100644 --- a/components/Input/index.tsx +++ b/components/Input/index.tsx @@ -1,37 +1,37 @@ -import { BigField, SmallField } from "./styles"; -import { Props } from "./types"; +import { BigField, SmallField } from './styles'; +import { Props } from './types'; const Input = ({ - type = 'text', - variant = 'small', - name, - value, - required, - placeholder, - className, - onChange + type = 'text', + variant = 'small', + name, + value, + required, + placeholder, + className, + onChange, }: Props) => { - return variant === 'small' ? ( - - ) : ( - - ); + return variant === 'small' ? ( + + ) : ( + + ); }; export default Input; diff --git a/components/Input/styles.tsx b/components/Input/styles.tsx index a18cf96..08ec3e8 100644 --- a/components/Input/styles.tsx +++ b/components/Input/styles.tsx @@ -1,16 +1,16 @@ -import styled from "styled-components"; +import styled from 'styled-components'; export const SmallField = styled.input` - border: none; - padding: 1rem; - background: var(--secondary-background); - color: var(--text); + 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); -`; \ No newline at end of file + resize: none; + border: none; + padding: 1rem; + background: var(--secondary-background); + color: var(--text); +`; diff --git a/components/Input/types.ts b/components/Input/types.ts index 3709223..51fab22 100644 --- a/components/Input/types.ts +++ b/components/Input/types.ts @@ -1,10 +1,12 @@ export interface Props { - placeholder?: string; - type: 'text' | 'email'; - variant: 'small' | 'big'; - name: string; - value: string; - required?: boolean; - onChange?: (event: React.ChangeEvent) => void; - className?: string; + placeholder?: string; + type: 'text' | 'email'; + variant: 'small' | 'big'; + name: string; + value: string; + required?: boolean; + onChange?: ( + event: React.ChangeEvent + ) => void; + className?: string; } diff --git a/components/MDXButton/index.tsx b/components/MDXButton/index.tsx index 7825577..afaaffb 100644 --- a/components/MDXButton/index.tsx +++ b/components/MDXButton/index.tsx @@ -4,33 +4,39 @@ import { Props } from './types'; import { StyledLink, StyledButton } from './styles'; const MDXButton = ({ - variant = 'text', - type = 'button', - link, - target, - children, - disabled, - className + variant = 'text', + type = 'button', + link, + target, + children, + disabled, + className, }: Props) => { - const { mode } = useContext(ThemeContext); + const { mode } = useContext(ThemeContext); - return link ? ( - - {children} - - ) : ( - - {children} - - ); + return link ? ( + + {children} + + ) : ( + + {children} + + ); }; export default MDXButton; diff --git a/components/MDXButton/styles.tsx b/components/MDXButton/styles.tsx index 2984e5e..6be80bf 100644 --- a/components/MDXButton/styles.tsx +++ b/components/MDXButton/styles.tsx @@ -3,42 +3,51 @@ import styled, { css } from 'styled-components'; import { Props } from './types'; export const sharedStyles = css` - cursor: pointer; - display: ${({ variant }) => - ['action', 'outline'].includes(variant as string) ? 'block' : 'inline'}; - width: ${({ variant }) => (['action', 'outline'].includes(variant as string) ? '100%' : 'auto')}; - background: ${({ variant }) => (variant === 'action' ? '#1573CA' : 'none')}; - color: ${({ variant, mode }) => - variant === 'action' ? 'white' : mode === 'dark' ? 'white' : 'black'}; - border: ${({ variant, mode }) => - variant === 'outline' ? `2px solid ${mode === 'dark' ? 'white' : 'black'}` : 'none'}; - font-weight: bold; - font-size: ${({ variant }) => - ['action', 'outline'].includes(variant as string) ? '1.05rem' : 'inherit'}; - text-transform: ${({ variant }) => - ['action', 'outline'].includes(variant as string) ? 'uppercase' : 'inherit'}; - padding: ${({ variant }) => - ['action', 'outline'].includes(variant as string) ? '.5rem 1rem' : '0rem'}; - text-align: ${({ variant }) => - ['action', 'outline'].includes(variant as string) ? 'center' : 'left'}; - text-decoration: none; - transition: color 250ms ease-in-out; + cursor: pointer; + display: ${({ variant }) => + ['action', 'outline'].includes(variant as string) ? 'block' : 'inline'}; + width: ${({ variant }) => + ['action', 'outline'].includes(variant as string) ? '100%' : 'auto'}; + background: ${({ variant }) => (variant === 'action' ? '#1573CA' : 'none')}; + color: ${({ variant, mode }) => + variant === 'action' ? 'white' : mode === 'dark' ? 'white' : 'black'}; + border: ${({ variant, mode }) => + variant === 'outline' + ? `2px solid ${mode === 'dark' ? 'white' : 'black'}` + : 'none'}; + font-weight: bold; + font-size: ${({ variant }) => + ['action', 'outline'].includes(variant as string) ? '1.05rem' : 'inherit'}; + text-transform: ${({ variant }) => + ['action', 'outline'].includes(variant as string) + ? 'uppercase' + : 'inherit'}; + padding: ${({ variant }) => + ['action', 'outline'].includes(variant as string) ? '.5rem 1rem' : '0rem'}; + text-align: ${({ variant }) => + ['action', 'outline'].includes(variant as string) ? 'center' : 'left'}; + text-decoration: none; + transition: color 250ms ease-in-out; - ${({ disabled }) => disabled && ` + ${({ disabled }) => + disabled && + ` background: gray; cursor: default; `} - @media (max-width: 768px) { - padding: ${({ variant }) => - ['action', 'outline'].includes(variant as string) ? '.5rem .75rem' : '0rem'}; - } + @media (max-width: 768px) { + padding: ${({ variant }) => + ['action', 'outline'].includes(variant as string) + ? '.5rem .75rem' + : '0rem'}; + } `; export const StyledLink = styled(Link)` - ${sharedStyles} + ${sharedStyles} `; export const StyledButton = styled.button>` - ${sharedStyles} + ${sharedStyles} `; diff --git a/components/MDXButton/types.ts b/components/MDXButton/types.ts index 07f9c0e..5bc3947 100644 --- a/components/MDXButton/types.ts +++ b/components/MDXButton/types.ts @@ -1,10 +1,10 @@ export type Props = { - variant?: 'outline' | 'text' | 'action'; - type?: 'button' | 'submit'; - link?: string; - target?: HTMLAnchorElement['target']; - mode?: string; - disabled?: boolean; - className?: string; - children: React.ReactNode; + variant?: 'outline' | 'text' | 'action'; + type?: 'button' | 'submit'; + link?: string; + target?: HTMLAnchorElement['target']; + mode?: string; + disabled?: boolean; + className?: string; + children: React.ReactNode; }; diff --git a/components/MobileNav/index.tsx b/components/MobileNav/index.tsx index a9dda7c..6b7df81 100644 --- a/components/MobileNav/index.tsx +++ b/components/MobileNav/index.tsx @@ -6,65 +6,69 @@ import IconButton from '../IconButton'; import Button from '../Button'; const MobileNav = ({ open, close }: Props) => { - const { mode, toggle } = useContext(ThemeContext); - const ref = useRef(null); + const { mode, toggle } = useContext(ThemeContext); + const ref = useRef(null); - useEffect(() => { - document.addEventListener('mousedown', (event: MouseEvent) => { - if (ref.current && ref.current.contains(event.target as Node)) { - document.addEventListener('mouseup', event => { - if (ref.current && !ref.current.contains(event.target as Node)) return; - }); - } else { - document.addEventListener('mouseup', event => { - if (ref.current && !ref.current.contains(event.target as Node)) close(); - }); - } - }); + useEffect(() => { + document.addEventListener('mousedown', (event: MouseEvent) => { + if (ref.current && ref.current.contains(event.target as Node)) { + document.addEventListener('mouseup', (event) => { + if (ref.current && !ref.current.contains(event.target as Node)) + return; + }); + } else { + document.addEventListener('mouseup', (event) => { + if (ref.current && !ref.current.contains(event.target as Node)) + close(); + }); + } + }); - return () => { - document.removeEventListener('mousedown', () => {}); - document.removeEventListener('mouseup', () => {}); - }; - }); + return () => { + document.removeEventListener('mousedown', () => {}); + document.removeEventListener('mouseup', () => {}); + }; + }); - return ( - -
- -
-
- -
-
- -
-
- -
-
- -
-
- ); + return ( + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ ); }; export default MobileNav; diff --git a/components/MobileNav/styles.tsx b/components/MobileNav/styles.tsx index 256bf39..380ca0f 100644 --- a/components/MobileNav/styles.tsx +++ b/components/MobileNav/styles.tsx @@ -2,36 +2,36 @@ import styled from 'styled-components'; import { StyledProps } from './types'; export const Bar = styled.nav` - position: fixed; - z-index: 2; - top: 0; - right: 0; - transform-origin: right; - transform: ${({ open }) => (open ? 'translateX(0%)' : 'translateX(100%)')}; - width: 80%; - height: 100vh; - background: var(--text); - transition: transform 250ms ease-in-out; - display: grid; - grid-template-rows: 30% repeat(4, 50px); - padding: 1rem 1rem 5rem 1rem; + position: fixed; + z-index: 2; + top: 0; + right: 0; + transform-origin: right; + transform: ${({ open }) => (open ? 'translateX(0%)' : 'translateX(100%)')}; + width: 80%; + height: 100vh; + background: var(--text); + transition: transform 250ms ease-in-out; + display: grid; + grid-template-rows: 30% repeat(4, 50px); + padding: 1rem 1rem 5rem 1rem; - @media (orientation: landscape) { - grid-template-rows: auto; - } + @media (orientation: landscape) { + grid-template-rows: auto; + } - .close { - justify-self: flex-end; - align-self: flex-start; - margin-top: 0.5rem; - } + .close { + justify-self: flex-end; + align-self: flex-start; + margin-top: 0.5rem; + } - .mobile-button-wrapper { - display: flex; - margin: 0rem 1rem; + .mobile-button-wrapper { + display: flex; + margin: 0rem 1rem; - a { - color: var(--text-inverted) !important; - } - } + a { + color: var(--text-inverted) !important; + } + } `; diff --git a/components/MobileNav/types.ts b/components/MobileNav/types.ts index 5d15207..d677fb7 100644 --- a/components/MobileNav/types.ts +++ b/components/MobileNav/types.ts @@ -1,8 +1,8 @@ export type Props = { - open: boolean; - close: () => void; + open: boolean; + close: () => void; }; export type StyledProps = { - open: boolean; + open: boolean; }; diff --git a/components/Nav/index.tsx b/components/Nav/index.tsx index f996e25..d20dfd2 100644 --- a/components/Nav/index.tsx +++ b/components/Nav/index.tsx @@ -8,47 +8,49 @@ import IconButton from '../IconButton'; import MobileNav from '../MobileNav'; const Nav = () => { - const [mobileNavOpen, setMobileNavOpen] = useState(false); - const { mode, toggle } = useContext(ThemeContext); + const [mobileNavOpen, setMobileNavOpen] = useState(false); + const { mode, toggle } = useContext(ThemeContext); - return ( - - - Logo Image -

Hazem Krimi

- -
- - - - - -
-
- - setMobileNavOpen(true)} - /> -
- setMobileNavOpen(false)} /> -
- ); + return ( + + + Logo Image +

Hazem Krimi

+ +
+ + + + + +
+
+ + setMobileNavOpen(true)} + /> +
+ setMobileNavOpen(false)} /> +
+ ); }; export default Nav; diff --git a/components/Nav/styles.tsx b/components/Nav/styles.tsx index d0ae7c2..16efd84 100644 --- a/components/Nav/styles.tsx +++ b/components/Nav/styles.tsx @@ -1,59 +1,59 @@ import styled from 'styled-components'; export const Bar = styled.nav` - width: 100%; - display: grid; - grid-template-columns: auto 1fr; - align-items: center; - padding: 1rem 0rem; + width: 100%; + display: grid; + grid-template-columns: auto 1fr; + align-items: center; + padding: 1rem 0rem; - * { - user-select: none; - } + * { + user-select: none; + } - h1 { - font-size: 1.7rem; + h1 { + font-size: 1.7rem; - @media (max-width: 768px) { - font-size: 1rem; - } - } + @media (max-width: 768px) { + font-size: 1rem; + } + } - div, - a.logo { - display: grid; - align-items: center; - column-gap: 1rem; + div, + a.logo { + display: grid; + align-items: center; + column-gap: 1rem; - @media (max-width: 768px) { - column-gap: 0.5rem; - } - } + @media (max-width: 768px) { + column-gap: 0.5rem; + } + } - a.logo { - text-decoration: none; - color: var(--text); - cursor: pointer; - grid-template-columns: repeat(2, auto); - justify-content: flex-start; - } + a.logo { + text-decoration: none; + color: var(--text); + cursor: pointer; + grid-template-columns: repeat(2, auto); + justify-content: flex-start; + } - .buttons { - grid-template-columns: repeat(5, auto); - justify-content: flex-end; + .buttons { + grid-template-columns: repeat(5, auto); + justify-content: flex-end; - @media (max-width: 768px) { - display: none; - } - } + @media (max-width: 768px) { + display: none; + } + } - .mobile-buttons { - display: none; + .mobile-buttons { + display: none; - @media (max-width: 768px) { - display: grid; - grid-template-columns: repeat(2, auto); - justify-content: flex-end; - } - } + @media (max-width: 768px) { + display: grid; + grid-template-columns: repeat(2, auto); + justify-content: flex-end; + } + } `; diff --git a/mdx.d.ts b/mdx.d.ts index fc1392c..aeb22ac 100644 --- a/mdx.d.ts +++ b/mdx.d.ts @@ -1,14 +1,14 @@ declare module '@mdx-js/react' { - import * as React from 'react'; + import * as React from 'react'; - export type Components = { - [key]?: React.ComponentType; - }; + export type Components = { + [key]?: React.ComponentType; + }; - export interface MDXProviderProps { - children: React.ReactNode; - components?: Components; - } - - export class MDXProvider extends React.Component {} + export interface MDXProviderProps { + children: React.ReactNode; + components?: Components; + } + + export class MDXProvider extends React.Component {} } diff --git a/next.config.js b/next.config.js index ddf88be..911d3af 100644 --- a/next.config.js +++ b/next.config.js @@ -1,13 +1,13 @@ const withMDX = require('@next/mdx')({ - extension: /\.mdx?$/, - options: { - providerImportSource: '@mdx-js/react' - } + extension: /\.mdx?$/, + options: { + providerImportSource: '@mdx-js/react', + }, }); module.exports = withMDX({ - pageExtensions: ['ts', 'tsx', 'md', 'mdx'], - images: { - domains: ['res.cloudinary.com'] - } + pageExtensions: ['ts', 'tsx', 'md', 'mdx'], + images: { + domains: ['res.cloudinary.com'], + }, }); diff --git a/package.json b/package.json index 791b4b1..6cd83f9 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "dev": "next dev", "build": "next build", - "start": "next start" + "start": "next start", + "format": "prettier --write ./**/*.{js,jsx,ts,tsx}" }, "dependencies": { "@formspree/react": "^2.4.1", @@ -28,6 +29,7 @@ "@types/styled-components": "^5.1.26", "babel-plugin-styled-components": "^2.0.7", "babel-runtime": "^6.26.0", + "prettier": "^2.8.8", "typescript": "^5.0.2" }, "engines": { diff --git a/pages/404.tsx b/pages/404.tsx index d14a340..226905b 100644 --- a/pages/404.tsx +++ b/pages/404.tsx @@ -4,45 +4,45 @@ import IconButton from '../components/IconButton'; import { Wrapper } from '../styles/404'; const NotFound = () => { - const router = useRouter(); + const router = useRouter(); - return ( - <> - - - - + + - - - + + - - - 404 Not Found | Hazem Krimi - - -

404: This page could not be found

-
router.push('/')}> - - Go Home -
-
- - ); + /> + + + 404 Not Found | Hazem Krimi + + +

404: This page could not be found

+
router.push('/')}> + + Go Home +
+
+ + ); }; export default NotFound; diff --git a/pages/_app.tsx b/pages/_app.tsx index 7e54954..aed57d0 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -20,50 +20,50 @@ import { initStyles } from '../utils/styles'; NProgress.configure({ showSpinner: false }); const App = ({ Component, pageProps }: AppProps) => { - const router = useRouter(); + const router = useRouter(); - useEffect(() => { - router.events.on('routeChangeStart', () => { - NProgress.start(); - }); + useEffect(() => { + router.events.on('routeChangeStart', () => { + NProgress.start(); + }); - router.events.on('routeChangeComplete', url => { - NProgress.done(); - pageview(url); - }); + router.events.on('routeChangeComplete', (url) => { + NProgress.done(); + pageview(url); + }); - router.events.on('routeChangeError', () => { - NProgress.done(); - }); + router.events.on('routeChangeError', () => { + NProgress.done(); + }); - return () => { - router.events.off('routeChangeComplete', url => { - pageview(url); - }); - }; - }, [router.events]); + return () => { + router.events.off('routeChangeComplete', (url) => { + pageview(url); + }); + }; + }, [router.events]); - return ( - <> -