You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.6 KiB
JavaScript

import React, {useState} from "react"
import Head from 'next/head'
import PropTypes from "prop-types"
import axios from 'axios'
import {UserContextProvider} from '~/hooks/useUser'
import {CartContextProvider} from '~/hooks/useCart'
import Header from '~/components/header'
import Footer from '~/components/footer'
import AdminNav from '~/components/admin/nav'
import ErrorBoundary from '~/components/errorBoundary'
import ErrorPage from '~/pages/_error'
import "~/styles/layout.css"
import 'react-infinite-calendar/styles.css'
const errorCodes = {
404: {
name: 'Not Found',
message: `We couldn't find the item you're looking for. Sorry!`
},
500: {
name: 'Error',
message: `Our server encountered an unexpected error. Please try again.`
}
}
Layout.getInitialProps = async ({Component, ctx}) => {
// Configure axios instance
ctx.axios = axios.create({
headers: (ctx.req && ctx.req.headers && ctx.req.headers.cookie)
? {cookie: ctx.req.headers.cookie}
: undefined
})
ctx.axios.interceptors.response.use(res => res,
err => {
if(!err.isAxiosError || !err.response || !err.response.data || !err.response.data.error)
throw err
// Unwrap API error, rethrow that
throw {
...err.response.data.error,
url: err.request.path
}
}
)
const promises = {
user: ctx.axios.get(`/api/auth`),
cart: ctx.axios.get(`/api/cart`)
}
const {data: user} = await promises.user
const {data: cart} = await promises.cart
let pageProps = {};
let error = null;
if(Component.getInitialProps) {
try {
pageProps = await Component.getInitialProps({ctx, user})
} catch (err) {
if(err.status && errorCodes[err.status])
error = errorCodes[err.status]
else
error = errorCodes[500]
console.error(err)
}
}
return {pageProps, error, user, cart}
}
function Layout({ Component, pageProps, error, user, cart }){
const cartState = useState(cart)
const userState = useState(user)
let page = error
? <ErrorPage error={error}/>
: <Component {...pageProps} />
return (
<>
<Head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
</Head>
<CartContextProvider value={cartState}>
<UserContextProvider value={userState}>
<Header/>
<ErrorBoundary>
<AdminNav>
{page}
</AdminNav>
</ErrorBoundary>
<Footer/>
</UserContextProvider>
</CartContextProvider>
</>
)
}
Layout.propTypes = {
pageProps: PropTypes.object
}
export default Layout