SCSS variables + Fixed contact form

dependabot/npm_and_yarn/typescript-eslint/parser-4.33.0
Guusvanmeerveld 3 years ago
parent 8c309699cc
commit 827e3fa21e

@ -1,66 +0,0 @@
import ReCAPTCHA from 'react-google-recaptcha';
import { useTheme } from 'next-themes';
import { FC } from 'react';
import styles from './Contact.module.scss';
const formURL = 'https://forms.guusvanmeerveld.dev/portfolio';
const Contact: FC = () => {
const { theme } = useTheme();
return (
<div className={styles.contact}>
<div className="container">
<div className={styles.header} id="contact">
Contact
</div>
<form
encType="application/x-www-form-urlencoded"
action={formURL}
className="content"
method="POST"
name="contact"
>
<label htmlFor="email">Email</label>
<input
className={styles.input}
name="email"
type="email"
required
placeholder="Your email address"
id="email"
/>
<label htmlFor="type">Message type</label>
<select className={styles.input} name="type[]" id="type">
<option value="bug">Bug</option>
<option value="question">Question</option>
<option value="suggestion">Suggestion</option>
<option value="other">Other</option>
</select>
<label htmlFor="message">Message</label>
<textarea
className={styles.textarea}
required
name="message"
placeholder="Your message"
></textarea>
<ReCAPTCHA
theme={theme as 'light' | 'dark'}
sitekey={process.env.NEXT_PUBLIC_CAPTCHA_KEY}
/>
<button className={styles.submit + ' button'} type="submit">
Send
</button>
</form>
</div>
</div>
);
};
export default Contact;

@ -1,6 +1,8 @@
@import '../styles/colors.scss';
.body { .body {
background-color: var(--secondary); background-color: $bg-secondary;
border-top: 0.1rem solid var(--borders); border-top: 0.1rem solid $borders;
padding: 3rem; padding: 3rem;
} }
@ -20,9 +22,6 @@
} }
.socialLink { .socialLink {
// color: var(--primary);
// cursor: pointer;
height: 3rem; height: 3rem;
width: 3rem; width: 3rem;
margin-right: 2rem; margin-right: 2rem;

@ -1,7 +1,9 @@
@import '../styles/colors.scss';
.bar { .bar {
z-index: 1; z-index: 1;
background-color: var(--secondary); background-color: $bg-secondary;
border-bottom: 0.1rem solid var(--borders); border-bottom: 0.1rem solid $borders;
position: fixed; position: fixed;
top: 0; top: 0;
@ -10,25 +12,32 @@
width: 100%; width: 100%;
} }
.select { .content {
border-color: var(--borders); display: flex;
color: var(--foreground);
background-color: var(--secondary);
width: 7.5rem; align-items: center;
margin-bottom: 0;
} }
.header { .header {
font-size: 1.75rem; flex: 1;
// height: max-content;
font-size: 2rem;
}
.select {
width: 7.5rem;
margin-bottom: 0;
} }
.items { .items {
float: right;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
a { a {
font-size: 1.75rem;
margin-left: 1rem; margin-left: 1rem;
} }
} }
@ -36,8 +45,7 @@
.moon, .moon,
.sun { .sun {
font-size: 2rem; font-size: 2rem;
margin-left: 1rem; margin: 0.25rem 1.5rem;
margin-top: 0.25rem;
cursor: pointer; cursor: pointer;
} }

@ -19,13 +19,9 @@ const Navbar: FC = () => {
return ( return (
<nav className={styles.bar}> <nav className={styles.bar}>
<div className="container"> <div className="container">
<span className={styles.header}>Portfolio</span> <div className={styles.content}>
<div className={styles.header}>Portfolio</div>
<div className={styles.items}> <div className={styles.items}>
<select id="" className={styles.select}>
<option value="nl">NL</option>
<option value="en">EN</option>
</select>
<Link href="/#projects"> <Link href="/#projects">
<a>{t('nav.projects')}</a> <a>{t('nav.projects')}</a>
</Link> </Link>
@ -38,6 +34,12 @@ const Navbar: FC = () => {
<BiMoon onClick={switchTheme} className={styles.moon} /> <BiMoon onClick={switchTheme} className={styles.moon} />
<ImSun onClick={switchTheme} className={styles.sun} /> <ImSun onClick={switchTheme} className={styles.sun} />
<select className={styles.select}>
<option value="nl">NL</option>
<option value="en">EN</option>
</select>
</div>
</div> </div>
</div> </div>
</nav> </nav>
@ -47,8 +49,6 @@ const Navbar: FC = () => {
export const getStaticProps: GetStaticProps = async ({ locale }) => { export const getStaticProps: GetStaticProps = async ({ locale }) => {
const { default: lngDict = {} } = await import(`../locales/${locale}.json`); const { default: lngDict = {} } = await import(`../locales/${locale}.json`);
console.log(lngDict);
return { return {
props: { lngDict }, props: { lngDict },
}; };

@ -35,7 +35,8 @@
@media only screen and (max-width: 600px) { @media only screen and (max-width: 600px) {
.cover, .cover,
.info { .info,
.right {
width: 100%; width: 100%;
margin: 2rem 0; margin: 2rem 0;
text-align: center; text-align: center;

@ -27,7 +27,7 @@ const Project: FC<ProjectComponent> = ({ name, description, buttons, cover, righ
</div> </div>
{cover ? ( {cover ? (
<div className={styles.cover}> <div className={styles.cover}>
<Image src={`/assets/images/${cover}`} width={200} height={200} alt="" /> <Image src={`/assets/images/${cover}`} width={200} height={200} alt={name} />
</div> </div>
) : null} ) : null}
</div> </div>

@ -11,10 +11,10 @@
width: 64px; width: 64px;
height: 64px; height: 64px;
margin: 8px; margin: 8px;
border: 8px solid var(--foreground); border: 8px solid $text;
border-radius: 50%; border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: var(--foreground) transparent transparent transparent; border-color: $text transparent transparent transparent;
&:nth-child(1) { &:nth-child(1) {
animation-delay: -0.45s; animation-delay: -0.45s;

@ -6,12 +6,13 @@ import { useRouter } from 'next/router';
import type { AppProps } from 'next/app'; import type { AppProps } from 'next/app';
import 'milligram'; import 'milligram';
import '@styles/raleway.css'; import '@styles/raleway.css';
import '@styles/roboto.css'; import '@styles/roboto.css';
import '@styles/globals.scss'; import '@styles/globals.scss';
function App({ Component, pageProps }: AppProps): JSX.Element { const App = ({ Component, pageProps }: AppProps): JSX.Element => {
const router = useRouter(); const router = useRouter();
const { lngDict, ...rest } = pageProps; const { lngDict, ...rest } = pageProps;
@ -22,6 +23,6 @@ function App({ Component, pageProps }: AppProps): JSX.Element {
</ThemeProvider> </ThemeProvider>
</I18nProvider> </I18nProvider>
); );
} };
export default App; export default App;

@ -1,14 +1,70 @@
import { NextPage } from 'next'; import { NextPage } from 'next';
import { useTheme } from 'next-themes';
import ReCAPTCHA from 'react-google-recaptcha';
import Page from '@components/Page'; import Page from '@components/Page';
import Layout from '@components/Layout'; import Layout from '@components/Layout';
import ContactForm from '@components/Contact';
import styles from './contact.module.scss';
const formURL = 'https://forms.guusvanmeerveld.dev/portfolio';
const Contact: NextPage = () => { const Contact: NextPage = () => {
const { theme } = useTheme();
return ( return (
<Page description="Contact me" title="Contact"> <Page description="Contact me" title="Contact">
<Layout> <Layout>
<ContactForm /> <div className={styles.contact}>
<div className="container">
<div className={styles.header} id="contact">
Contact
</div>
<form
encType="application/x-www-form-urlencoded"
action={formURL}
className="content"
method="POST"
name="contact"
>
<label htmlFor="email">Email</label>
<input
className={styles.input}
name="email"
type="email"
required
placeholder="Your email address"
id="email"
/>
<label htmlFor="type">Message type</label>
<select className={styles.input} name="type[]" id="type">
<option value="bug">Bug</option>
<option value="question">Question</option>
<option value="suggestion">Suggestion</option>
<option value="other">Other</option>
</select>
<label htmlFor="message">Message</label>
<textarea
className={styles.textarea}
required
name="message"
placeholder="Your message"
></textarea>
<ReCAPTCHA
theme={theme as 'light' | 'dark'}
sitekey={process.env.NEXT_PUBLIC_CAPTCHA_KEY}
/>
<button className={styles.submit + ' button'} type="submit">
Send
</button>
</form>
</div>
</div>
</Layout> </Layout>
</Page> </Page>
); );

@ -0,0 +1,5 @@
$primary: var(--primary);
$bg-primary: var(--background);
$bg-secondary: var(--secondary);
$borders: var(--borders);
$text: var(--text);

@ -1,7 +1,7 @@
body { body {
margin: 0; margin: 0;
background-color: var(--background); background-color: $bg-primary;
color: var(--foreground); color: $text;
font-family: 'Raleway'; font-family: 'Raleway';
} }

@ -2,6 +2,18 @@ input,
textarea, textarea,
select { select {
&:focus { &:focus {
border-color: var(--primary); border-color: $primary !important;
}
color: $text;
border-color: $borders !important;
font-family: 'Roboto';
font-size: 1.5rem;
}
select {
&:focus {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 8" width="30"><path fill="%23388e3c" d="M0,0l6,8l6-8"/></svg>');
} }
} }

@ -1,9 +1,9 @@
:root { :root {
--primary: #9ccc65; --primary: #9ccc65;
--background: white;
--secondary: #f4f5f6; --secondary: #f4f5f6;
--background: white;
--borders: #e4e4e4; --borders: #e4e4e4;
--foreground: #606c76; --text: #606c76;
} }
[data-theme='dark'] { [data-theme='dark'] {
@ -12,12 +12,14 @@
} }
--primary: #388e3c; --primary: #388e3c;
--background: #212123;
--secondary: #1c1c1c; --secondary: #1c1c1c;
--background: #212123;
--borders: #3c3838; --borders: #3c3838;
--foreground: rgb(236, 235, 235); --text: rgb(236, 235, 235);
} }
@import './colors.scss';
@import './global/body.scss'; @import './global/body.scss';
@import './global/link.scss'; @import './global/link.scss';
@import './global/input.scss'; @import './global/input.scss';

Loading…
Cancel
Save