Skip to content

Commit

Permalink
Merge pull request #49 from gabrielduete/feat/add-cases-loading-and-e…
Browse files Browse the repository at this point in the history
…rror

feat: add cases loading and error
  • Loading branch information
gabrielduete authored Jul 8, 2024
2 parents 26d0b93 + 7e5e1d2 commit c9cce72
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 49 deletions.
42 changes: 22 additions & 20 deletions pages/[id].page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Head from 'next/head'
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import ErrorCase from '~/src/components/ErrorCase'
import SkeletonText from '~/src/components/SkeletonText'
import { usePagesStoraged } from '~/src/contexts/ContextPages'
import { renderBlock } from '~/src/helpers/notionConverter'
import { Block } from '~/src/helpers/notionConverter/notionConverter.types'
Expand All @@ -12,42 +14,42 @@ const Content = () => {

const { idPage } = usePagesStoraged()

useEffect(() => {
const fetchData = async () => {
setIsLoading(true)
try {
const response = await fetch(`http://localhost:8080/${idPage}`)
const fetchData = useCallback(async () => {
setIsLoading(true)
try {
const response = await fetch(`http://localhost:8080/${idPage}`)

if (!response.ok) {
throw new Error(`COUND NOT GET PAGE ID: ${idPage}`)
}
if (!response.ok) {
throw new Error(`COUND NOT GET PAGE ID: ${idPage}`)
}

const data = await response.json()
const data = await response.json()

setContent(data.results)
} catch (error) {
console.error('Error fetching data:', error)
setHasError(true)
} finally {
setIsLoading(false)
}
setContent(data.results)
} catch (error) {
console.error('Error fetching data:', error)
setHasError(true)
} finally {
setIsLoading(false)
}
}, [idPage])

useEffect(() => {
fetchData()
}, [idPage])
}, [fetchData])

if (isLoading) {
return (
<Layout>
<h1>LOADING</h1>
<SkeletonText />
</Layout>
)
}

if (hasError) {
return (
<Layout>
<h1>ERROR</h1>
<ErrorCase onClick={() => fetchData()} />
</Layout>
)
}
Expand Down
13 changes: 13 additions & 0 deletions src/components/ErrorCase/ErrorCase.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { render, screen } from '@testing-library/react'

import ErrorCase from '.'

describe('<ErrorCase />', () => {
it('should render the ErrorCase component', () => {
render(<ErrorCase onClick={jest.fn()} />)

expect(
screen.getByText('Something went wrong. Please try again.')
).toBeInTheDocument()
})
})
20 changes: 20 additions & 0 deletions src/components/ErrorCase/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ErrorIcon from '@mui/icons-material/Error'

import * as S from './styles'

type ErrorCaseProps = {
hasMargin?: boolean
onClick: () => void
}

const ErrorCase = ({ hasMargin, onClick }: ErrorCaseProps) => {
return (
<S.Container hasMargin={hasMargin}>
<ErrorIcon fontSize='large' />
<S.Text>Something went wrong. Please try again.</S.Text>
<S.RetryButton onClick={onClick}>Retry</S.RetryButton>
</S.Container>
)
}

export default ErrorCase
28 changes: 28 additions & 0 deletions src/components/ErrorCase/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import styled from 'styled-components'

export const Container = styled.div<{ hasMargin?: boolean }>`
display: flex;
gap: var(--spacing-basic);
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: ${({ hasMargin }) => hasMargin && '50%'};
`

export const Text = styled.p`
font-size: var(--font-xmedium);
text-align: center;
`

export const RetryButton = styled.button`
cursor: pointer;
color: var(--green-white);
background: none;
border: none;
font-size: var(--font-xsmall);
transition: 0.5s ease;
&:hover {
color: var(--white);
}
`
15 changes: 15 additions & 0 deletions src/components/SkeletonText/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Skeleton } from '@mui/material'

const SkeletonText = () => {
const skeletons = [160, 120, 70, 50]

return (
<>
{skeletons.map((height, index) => (
<Skeleton key={index} height={height} animation='wave' />
))}
</>
)
}

export default SkeletonText
2 changes: 1 addition & 1 deletion src/contexts/ContextPages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const PagesStoregedProvider = ({
}

fetchData()
}, [idPage])
}, [])

const contextValue: PagesStoraged = {
pages,
Expand Down
5 changes: 3 additions & 2 deletions src/layout/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useRouter } from 'next/router'

import MobileNavBar from '../NavBar/Mobile'
import { NavBarProps } from '../NavBar/Navbar.types'
import { items } from './Header.data'
import * as S from './styles'

const Header = () => {
const Header = ({ pages }: NavBarProps) => {
const router = useRouter()

return (
Expand All @@ -20,7 +21,7 @@ const Header = () => {
)
})}
</S.WrapperLinks>
<MobileNavBar />
<MobileNavBar pages={pages} />
</S.Header>
)
}
Expand Down
15 changes: 7 additions & 8 deletions src/layout/components/NavBar/Desktop/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { useRouter } from 'next/router'
import { useState } from 'react'
import Equalizer from '~/src/components/Equalizer'
import {
PagesStoregedProvider,
usePagesStoraged,
} from '~/src/contexts/ContextPages'
import { usePagesStoraged } from '~/src/contexts/ContextPages'
import { SoundClickButton } from '~/src/utils/sounds'

import { NavBarProps } from '../Navbar.types'
import { titleWithHyphens } from '../helpers/formateTitle'
import { getPaths } from '../helpers/getPaths'
import * as S from './styles'

const DesktopNavBar = () => {
const DesktopNavBar = ({ pages }: NavBarProps) => {
const router = useRouter()
const [isOpen, setIsOpen] = useState(true)
const { setIdPage, pages } = usePagesStoraged()

const { setIdPage } = usePagesStoraged()

const closeNavBar = () => {
SoundClickButton()
Expand All @@ -29,7 +28,7 @@ const DesktopNavBar = () => {
const paths = getPaths({ pages })

return (
<PagesStoregedProvider>
<>
<S.Wrapper showNavBar={isOpen}>
<S.NavBar>
{paths?.map(({ title, id }) => (
Expand All @@ -47,7 +46,7 @@ const DesktopNavBar = () => {
<S.WrapperColapsed showNavBar={!isOpen}>
<S.GoIcon onClick={closeNavBar} />
</S.WrapperColapsed>
</PagesStoregedProvider>
</>
)
}

Expand Down
7 changes: 4 additions & 3 deletions src/layout/components/NavBar/Mobile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { useRouter } from 'next/router'
import React, { useState } from 'react'
import { usePagesStoraged } from '~/src/contexts/ContextPages'

import { NavBarProps } from '../Navbar.types'
import { titleWithHyphens } from '../helpers/formateTitle'
import { getPaths } from '../helpers/getPaths'
import * as S from './styles'

const MobileNavBar = () => {
const MobileNavBar = ({ pages }: NavBarProps) => {
const router = useRouter()
const [isOpen, setIsOpen] = useState(false)
const { setIdPage, pages } = usePagesStoraged()
const { setIdPage } = usePagesStoraged()

const goToContent = (id: string, title: string) => {
setIdPage(id)
Expand All @@ -24,7 +25,7 @@ const MobileNavBar = () => {
<S.WrapperContent isOpen={isOpen}>
<S.IconClose onClick={() => setIsOpen(false)} />
<S.WrapperLinks>
{paths.map(({ title, id }) => {
{paths?.map(({ title, id }) => {
return (
<S.Link key={id} onClick={() => goToContent(id, title)}>
{title}
Expand Down
5 changes: 5 additions & 0 deletions src/layout/components/NavBar/Navbar.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Block } from '~/src/helpers/notionConverter/notionConverter.types'

export type NavBarProps = {
pages: Block[]
}
54 changes: 42 additions & 12 deletions src/layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ReactNode } from 'react'

import ErrorCase from '../components/ErrorCase'
import { usePagesStoraged } from '../contexts/ContextPages'
import Breadcrumb from './components/Breadcrumb'
import Footer from './components/Footer'
import Header from './components/Header'
Expand All @@ -10,18 +12,46 @@ type LayoutProps = {
children: ReactNode | ReactNode[]
}

const Layout = ({ children }: LayoutProps) => (
<S.Container>
<Header />
<S.WrapperContent>
<DesktopNavbar />
<S.Content>
<Breadcrumb />
const Layout = ({ children }: LayoutProps) => {
const { pages, isLoading, hasError } = usePagesStoraged()

const LayoutBase = ({ children }: LayoutProps) => {
return (
<S.Container>
<Header pages={pages} />
{children}
</S.Content>
</S.WrapperContent>
<Footer />
</S.Container>
)
<Footer />
</S.Container>
)
}

if (isLoading) return <S.Loading color='inherit' />

if (hasError)
return (
<LayoutBase>
<S.Content>
<ErrorCase
onClick={() =>
typeof window !== 'undefined' && window.location.reload()
}
hasMargin={true}
/>
</S.Content>
</LayoutBase>
)

return (
<LayoutBase>
<S.WrapperContent>
<DesktopNavbar pages={pages} />
<S.Content>
<Breadcrumb />
{children}
</S.Content>
</S.WrapperContent>
</LayoutBase>
)
}

export default Layout
9 changes: 8 additions & 1 deletion src/layout/styles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { CircularProgress } from '@mui/material'
import styled from 'styled-components'

import { breakpoints } from '../enums/breakpoints'

export const Container = styled.main`
color: var(--white);
background-color: var(--green-dark);
`

export const WrapperContent = styled.section`
Expand All @@ -26,3 +26,10 @@ export const Content = styled.div`
padding: 0 var(--spacing-basic);
}
`

export const Loading = styled(CircularProgress)`
color: var(--white);
position: absolute;
top: 45%;
left: 50%;
`
4 changes: 2 additions & 2 deletions src/styles/GlobalStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ const GlobalStyle = createGlobalStyle`
:root{
// Colors
--black: #21272E;
--green-dark: #122226;
--green: #1A3038;
--green-dark: #122226;
--green-white: #3C5768;
--green-white-regular: #1D333D;
--green-white-bold: #223943;
--green-white: #3C5768;
--white: #FFFFFF;
// Spacings
Expand Down
1 change: 1 addition & 0 deletions src/styles/TextsStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const TextsStyle = createGlobalStyle`
a{
color: var(--green-white);
cursor: pointer;
text-decoration: none;
transition: 0.3s;
}
Expand Down

0 comments on commit c9cce72

Please sign in to comment.