🎉 Initial Commit!

This commit is contained in:
Jack Merrill 2021-03-31 00:27:36 -05:00
commit 0eee4e6a07
18 changed files with 3118 additions and 0 deletions

15
.editorconfig Normal file
View File

@ -0,0 +1,15 @@
# https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
[*{.ts,.js}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

25
.eslintrc.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:react/recommended",
"airbnb"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
"indent": ["error", 2]
}
};

34
.gitignore vendored Normal file
View File

@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# 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

41
README.md Normal file
View File

@ -0,0 +1,41 @@
# TypeScript Next.js example
This is a really simple project that shows the usage of Next.js with TypeScript.
## Deploy your own
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-typescript&project-name=with-typescript&repository-name=with-typescript)
## How to use it?
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
npx create-next-app --example with-typescript with-typescript-app
# or
yarn create next-app --example with-typescript with-typescript-app
```
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
## Notes
This example shows how to integrate the TypeScript type system into Next.js. Since TypeScript is supported out of the box with Next.js, all we have to do is to install TypeScript.
```
npm install --save-dev typescript
```
To enable TypeScript's features, we install the type declarations for React and Node.
```
npm install --save-dev @types/react @types/react-dom @types/node
```
When we run `next dev` the next time, Next.js will start looking for any `.ts` or `.tsx` files in our project and builds it. It even automatically creates a `tsconfig.json` file for our project with the recommended settings.
Next.js has built-in TypeScript declarations, so we'll get autocompletion for Next.js' modules straight away.
A `type-check` script is also added to `package.json`, which runs TypeScript's `tsc` CLI in `noEmit` mode to run type-checking separately. You can then include this, for example, in your `test` scripts.

View File

@ -0,0 +1,30 @@
const Logo = () => (
<svg
width="100%"
height="100%"
viewBox="0 0 1080 1080"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
xmlSpace="preserve"
fillRule='evenodd'
clipRule='evenodd'
strokeLinejoin='round'
strokeMiterlimit='2'
>
<g transform="matrix(1.87667,0,0,1.87667,-211.69,-370.379)">
<path d="M330.006,585.343L506.715,408.388C513.207,401.887 513.2,391.339 506.699,384.847C500.198,378.355 489.65,378.363 483.158,384.863L306.448,561.819C299.956,568.32 299.964,578.868 306.465,585.36C312.965,591.852 323.514,591.844 330.006,585.343Z" fill="white" />
</g>
<g transform="matrix(1.87667,0,0,1.87667,-45.877,-370.379)">
<path d="M330.006,585.343L506.715,408.388C513.207,401.887 513.2,391.339 506.699,384.847C500.198,378.355 489.65,378.363 483.158,384.863L306.448,561.819C299.956,568.32 299.964,578.868 306.465,585.36C312.965,591.852 323.514,591.844 330.006,585.343Z" fill="white" />
</g>
<g transform="matrix(1.87667,0,0,1.87667,119.936,-370.379)">
<path d="M330.006,585.343L506.715,408.388C513.207,401.887 513.2,391.339 506.699,384.847C500.198,378.355 489.65,378.363 483.158,384.863L306.448,561.819C299.956,568.32 299.964,578.868 306.465,585.36C312.965,591.852 323.514,591.844 330.006,585.343Z" fill="white" />
</g>
<g transform="matrix(1.87667,0,0,1.87667,-473.399,-473.402)">
<path d="M362.424,611.832L534.257,439.76C540.749,433.259 551.297,433.252 557.798,439.744C564.299,446.235 564.306,456.784 557.815,463.285L381.105,640.24C379.514,641.833 377.679,643.037 375.72,643.85L375.686,643.864C373.726,644.676 371.578,645.124 369.326,645.124L268.899,645.124C259.712,645.124 252.253,637.665 252.253,628.478C252.253,619.29 259.712,611.832 268.899,611.832L362.424,611.832Z" fill="white" />
</g>
</svg>
)
export default Logo;

70
components/Navbar.tsx Normal file
View File

@ -0,0 +1,70 @@
import Link from "next/link";
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import Logo from './Images/Logo';
const Navbar = ({ links }: {
links: {
label: string;
href: string;
}[]
}) => {
const [collapsed, setCollapsed] = useState(false);
const [atTop, setAtTop] = useState<boolean>()
useEffect(() => {
if (window.scrollY === 0) {
setAtTop(true)
} else {
setAtTop(false)
}
window.addEventListener("scroll", () => {
if (window.scrollY === 0) {
setAtTop(true)
} else {
setAtTop(false)
}
})
})
return (
<nav className={`fixed w-full flex flex-wrap items-center justify-between px-2 py-6 navbar-expand-lg bg-gray-800 ${atTop ? '' : 'shadow-md'}`}>
<div className="container px-4 mx-auto flex flex-wrap items-center justify-between">
<div className="w-full relative flex justify-between md:w-auto px-4 md:static md:block md:justify-start items-center">
<div className="text-sm font-bold leading-relaxed inline-block mr-4 py-2 whitespace-no-wrap text-white">
<Link href="/" aria-label="Stryx Logo">
<h1 className="text-white font-extrabold text-2xl">Jack Merrill</h1>
</Link>
</div>
<button className="md:hidden text-gray-500 w-10 h-10 relative focus:outline-none" onClick={() => setCollapsed(!collapsed)}>
<span className="sr-only">Open menu</span>
<div className="block w-5 absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2">
<span aria-hidden="true" className={`block absolute h-0.5 w-5 bg-current transform transition duration-500 ease-in-out ${ !collapsed ? 'rotate-45' : '-translate-y-1.5' }`} />
<span aria-hidden="true" className={`block absolute h-0.5 w-5 bg-current transform transition duration-500 ease-in-out ${ !collapsed && 'opacity-0'}`} ></span>
<span aria-hidden="true" className={`block absolute h-0.5 w-5 bg-current transform transition duration-500 ease-in-out ${ !collapsed ? '-rotate-45' : 'translate-y-1.5' }`} ></span>
</div>
</button>
</div>
<div className={collapsed ? 'md:flex flex-grow items-center hidden' : 'md:flex flex-grow items-center'} id="navbar">
<ul className="flex flex-col md:flex-row list-none ml-auto items-center">
{links.map(({ label, href }) => (
<li className="nav-item">
<div className="px-3 py-2 flex items-center leading-snug text-white">
<Link href={href} passHref>
<a
className="font-bold text-gray-200 hover:underline"
>
{label}
</a>
</Link>
</div>
</li>
))}
</ul>
</div>
</div>
</nav>
)
}
export default Navbar;

10
interfaces/index.ts Normal file
View File

@ -0,0 +1,10 @@
// You can include shared interfaces/types in a separate file
// and then use them in any component by importing them. For
// example, to import the interface below do:
//
// import { User } from 'path/to/interfaces';
export type User = {
id: number
name: string
}

2
next-env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

5
next.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
future: {
webpack5: true,
},
}

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "with-typescript",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"type-check": "tsc"
},
"dependencies": {
"next": "latest",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"devDependencies": {
"@fullhuman/postcss-purgecss": "^4.0.3",
"@types/node": "^12.12.21",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"autoprefixer": "^10.2.5",
"postcss-preset-env": "^6.7.0",
"tailwindcss": "^2.0.4",
"typescript": "4.0"
},
"license": "MIT"
}

10
pages/_app.tsx Normal file
View File

@ -0,0 +1,10 @@
import React from 'react'
import { AppProps } from 'next/app'
import 'tailwindcss/tailwind.css'
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default MyApp

23
pages/_document.tsx Normal file
View File

@ -0,0 +1,23 @@
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument

50
pages/index.tsx Normal file
View File

@ -0,0 +1,50 @@
import Link from 'next/link'
import Navbar from '../components/Navbar'
function GetTimeString(): string {
const hours = new Date().getHours()
if (hours < 12) {
return 'Morning'
} else if (hours >= 12 && hours <= 17) {
return 'Afternoon'
} else if (hours >= 17 && hours <= 24) {
return 'Evening'
}
}
const IndexPage = () => (
<div id='app'>
<main className="bg-gray-800 w-screen h-full min-h-screen">
<Navbar links={[
{ label: 'Home', href: '/' },
{ label: 'Portfolio', href: '/portfolio' },
{ label: 'Projects', href: '/projects' },
]} />
<header className="flex flex-wrap flex-col overflow-hidden space-y-2 px-36 items-center justify-center h-screen w-screen">
<div className="my-3 px-3 w-full text-center">
<h1 className="text-white font-extrabold md:text-6xl text-3xl">Good <span className="text-blue-500">{GetTimeString()}</span>! I&apos;m <span className="text-purple-400">Jack Merrill</span>.</h1>
</div>
<div className="my-3 px-3 w-full text-center">
<h2 className="text-white font-bold md:text-4xl text-2xl">A Graphic and UI/UX Designer and Fullstack Developer from Chicago.</h2>
</div>
<div className="inline-flex items-center justify-center content-center space-x-4 my-3 px-3 w-full text-center">
<Link href="/portfolio">
<a className="bg-gradient-to-r from-green-400 to-blue-500 px-4 py-2 rounded-xl font-bold text-white">
See my Work
</a>
</Link>
<span className="text-sm font-light text-gray-400">or</span>
<Link href="mailto:me@jackmerrill.com">
<a className="bg-gradient-to-r from-green-400 to-blue-500 px-4 py-2 rounded-xl font-bold text-white">
Contact Me
</a>
</Link>
</div>
</header>
</main>
</div>
)
export default IndexPage

18
postcss.config.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
plugins: [
'tailwindcss',
process.env.NODE_ENV === 'production'
? [
'@fullhuman/postcss-purgecss',
{
content: [
'./pages/**/*.{js,jsx,ts,tsx}',
'./components/**/*.{js,jsx,ts,tsx}',
],
defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
},
]
: undefined,
'postcss-preset-env',
],
};

11
tailwind.config.js Normal file
View File

@ -0,0 +1,11 @@
module.exports = {
purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
darkMode: 'media', // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}

23
tsconfig.json Normal file
View File

@ -0,0 +1,23 @@
{
"compilerOptions": {
"allowJs": true,
"alwaysStrict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": ["dom", "es2017"],
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "esnext"
},
"exclude": ["node_modules"],
"include": ["**/*.ts", "**/*.tsx"]
}

9
utils/sample-data.ts Normal file
View File

@ -0,0 +1,9 @@
import { User } from '../interfaces'
/** Dummy user data. */
export const sampleUserData: User[] = [
{ id: 101, name: 'Alice' },
{ id: 102, name: 'Bob' },
{ id: 103, name: 'Caroline' },
{ id: 104, name: 'Dave' },
]

2716
yarn.lock Normal file

File diff suppressed because it is too large Load Diff