1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2025-05-29 22:37:44 +02:00

feat: add light mode + rewrite in Tailwind CSS (#15)

This commit is contained in:
Divlo
2021-05-08 19:52:04 +02:00
committed by GitHub
parent 26f24329c7
commit c62e66a86a
83 changed files with 5803 additions and 7623 deletions

View File

@ -10,7 +10,6 @@ const Error404: React.FC = () => {
return (
<>
<Head title='Divlo - 404' />
<ErrorPage statusCode={404} message={t('errors:notFound')} />
</>
)

View File

@ -10,7 +10,6 @@ const Error500: React.FC = () => {
return (
<>
<Head title='Divlo - 500' />
<ErrorPage statusCode={500} message={t('errors:serverError')} />
</>
)

View File

@ -1,32 +1,23 @@
import { useEffect } from 'react'
import { AppProps } from 'next/app'
import Router from 'next/router'
import NProgress from 'nprogress'
import { ThemeProvider } from 'next-themes'
import useTranslation from 'next-translate/useTranslation'
import UniversalCookie from 'universal-cookie'
import 'normalize.css/normalize.css'
import 'tailwindcss/tailwind.css'
import '@fontsource/montserrat/400.css'
import '@fontsource/montserrat/500.css'
import '@fontsource/montserrat/600.css'
import '@fontsource/montserrat/700.css'
import 'styles/grid.scss'
import 'styles/general.scss'
import 'styles/nprogress.scss'
import { Header } from 'components/Header'
import { Footer } from 'components/Footer'
import { useEffect } from 'react'
const universalCookie = new UniversalCookie()
/** how long in seconds, until the cookie expires (10 years) */
const COOKIE_MAX_AGE = 10 * 365.25 * 24 * 60 * 60
Router.events.on('routeChangeStart', () => NProgress.start())
Router.events.on('routeChangeComplete', () => NProgress.done())
Router.events.on('routeChangeError', () => NProgress.done())
const MyApp = ({ Component, pageProps }: AppProps): JSX.Element => {
const { lang } = useTranslation()
@ -38,13 +29,13 @@ const MyApp = ({ Component, pageProps }: AppProps): JSX.Element => {
}, [lang])
return (
<>
<ThemeProvider attribute='class' defaultTheme='dark'>
<Header />
<main className='content container'>
<main className='flex flex-col md:mx-auto md:max-w-4xl lg:max-w-7xl'>
<Component {...pageProps} />
</main>
<Footer />
</>
</ThemeProvider>
)
}

31
pages/_document.tsx Normal file
View File

@ -0,0 +1,31 @@
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps
} from 'next/document'
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render(): JSX.Element {
return (
<Html>
<Head />
<body className='bg-white dark:bg-black text-black dark:text-white font-headline'>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument

View File

@ -1,61 +0,0 @@
import { NextApiRequest, NextApiResponse } from 'next'
import nodemailer from 'nodemailer'
import validator from 'validator'
const EMAIL_PORT = parseInt(process.env.EMAIL_PORT ?? '465', 10)
const emailTransporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST,
port: EMAIL_PORT,
secure: EMAIL_PORT === 465,
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASSWORD
},
tls: {
rejectUnauthorized: false
}
})
const handler = async (
request: NextApiRequest,
response: NextApiResponse
): Promise<any> => {
if (request.method !== 'POST') {
return response.redirect('/404')
}
const { name, email, subject, message } = request.body as {
name: string
email: string
subject: string
message: string
}
if (
validator.isEmpty(name) ||
validator.isEmpty(email) ||
validator.isEmpty(subject) ||
validator.isEmpty(message)
) {
return response.status(400).json({ type: 'requiredFields' })
}
if (!validator.isEmail(email)) {
return response.status(400).json({ type: 'invalidEmail' })
}
try {
await emailTransporter.sendMail({
from: '"Divlo" <contact@divlo.fr>',
to: email,
subject: `Contact - ${validator.escape(subject)}`,
html: `
<b>Name:</b> ${validator.escape(name)} <br/>
<b>Email:</b> ${validator.escape(email)} <br/>
<b>Message:</b> ${validator.escape(message)}
`
})
return response.status(201).json({ type: 'success' })
} catch {
return response.status(500).json({ type: 'serverError' })
}
}
export default handler

View File

@ -1,7 +1,6 @@
import { GetStaticProps } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { Contact } from 'components/Contact'
import { RevealFade } from 'components/design/RevealFade'
import { Section } from 'components/design/Section'
import { Head } from 'components/Head'
@ -30,7 +29,11 @@ const Home: React.FC = () => {
</RevealFade>
<RevealFade>
<Section id='skills' heading={t('home:skills.title')} withoutShadowContainer>
<Section
id='skills'
heading={t('home:skills.title')}
withoutShadowContainer
>
<Skills />
</Section>
</RevealFade>
@ -44,12 +47,6 @@ const Home: React.FC = () => {
<Portfolio />
</Section>
</RevealFade>
<RevealFade>
<Section id='contact' heading={t('home:contact.title')}>
<Contact />
</Section>
</RevealFade>
</>
)
}