├── .gitignore
├── README.md
├── src
├── data
│ └── data.js
└── components
│ └── nav.jsx
├── next.config.js
├── pages
├── api
│ └── note
│ │ ├── index.js
│ │ └── [id].js
├── _app.jsx
├── index.jsx
└── notes
│ ├── [id].jsx
│ └── index.jsx
├── theme.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | public
4 | .next
5 | .env
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Next.js course
2 | > Learn Next.js
3 |
4 | Follow along with [the course](https://hendrixer.github.io/nextjs-course/)
5 |
--------------------------------------------------------------------------------
/src/data/data.js:
--------------------------------------------------------------------------------
1 | const notes = new Array(15)
2 | .fill(1)
3 | .map((_, i) => ({
4 | id: Date.now() + i,
5 | title: `Note ${i}`
6 | }))
7 |
8 | module.exports = notes
9 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | const nextEnv = require('next-env')
2 | const dotenvLoad = require('dotenv-load')
3 |
4 | dotenvLoad()
5 |
6 | const withNextEnv = nextEnv()
7 | module.exports = withNextEnv()
8 |
--------------------------------------------------------------------------------
/pages/api/note/index.js:
--------------------------------------------------------------------------------
1 | import nc from 'next-connect'
2 | import notes from '../../../src/data/data'
3 |
4 | const handler = nc()
5 | .get((req, res) => {
6 | res.json({data: notes})
7 | })
8 | .post((req, res) => {
9 | const id = Date.now()
10 | const note = {...req.body, id}
11 |
12 | notes.push(note)
13 | res.json({data: note})
14 | })
15 |
16 |
17 | export default handler
18 |
--------------------------------------------------------------------------------
/pages/_app.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from 'theme-ui'
3 | import { ThemeProvider } from 'theme-ui'
4 | import theme from '../theme'
5 | import Nav from '../src/components/nav'
6 |
7 | export default function App({ Component, pageProps }) {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/theme.js:
--------------------------------------------------------------------------------
1 | import { roboto } from '@theme-ui/presets'
2 |
3 | const theme = {
4 | ...roboto,
5 | containers: {
6 | card: {
7 | boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)',
8 | border: '1px solid',
9 | borderColor: 'muted',
10 | borderRadius: '4px',
11 | p: 2,
12 | },
13 | page: {
14 | width: '100%',
15 | maxWidth: '960px',
16 | m: 0,
17 | mx: 'auto',
18 | }
19 | },
20 | styles: {
21 | ...roboto.styles
22 | }
23 | }
24 |
25 | export default theme
26 |
--------------------------------------------------------------------------------
/pages/index.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from 'theme-ui'
3 | import Link from 'next/link'
4 |
5 | export default ({content}) => (
6 |
7 |
8 |
{content.title}
9 |
10 |
11 | )
12 |
13 |
14 | export async function getStaticProps() {
15 | return {
16 | props: {
17 | content: {
18 | title: 'Look at my note app tho'
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "author": "Scott Moss ",
6 | "license": "MIT",
7 | "dependencies": {
8 | "@theme-ui/presets": "^0.3.0",
9 | "body-parser": "^1.19.0",
10 | "dotenv-load": "^2.0.0",
11 | "next": "^9.5.0",
12 | "next-connect": "^0.8.1",
13 | "next-env": "^1.1.1",
14 | "react": "^16.13.1",
15 | "react-dom": "^16.13.1",
16 | "theme-ui": "^0.3.1"
17 | },
18 | "scripts": {
19 | "dev": "next",
20 | "build": "next build",
21 | "start": "next start"
22 | },
23 | "devDependencies": {}
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/nav.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from 'theme-ui'
3 | import Link from 'next/link'
4 |
5 | const Nav = () => (
6 |
19 | )
20 |
21 | export default Nav
22 |
--------------------------------------------------------------------------------
/pages/notes/[id].jsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from 'theme-ui'
3 | import { useRouter } from 'next/router'
4 | import Link from 'next/link'
5 |
6 | const Note = () => {
7 | const router = useRouter()
8 | const { id }= router.query
9 |
10 | return (
11 |
12 |
Note: {id}
13 |
14 | )
15 | }
16 |
17 | export default Note
18 |
19 | export async function getServerSideProps({params, req, res}) {
20 | const response = await fetch(`http://localhost:3000/api/note/${params.id}`)
21 |
22 | if (!response.ok) {
23 | res.writeHead(302, { Location: '/notes' })
24 | res.end()
25 | return {props: {}}
26 | }
27 |
28 | const {data} = await response.json()
29 |
30 |
31 | if (data) {
32 | return {
33 | props: {note: data}
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/pages/notes/index.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx } from 'theme-ui'
3 | import Link from 'next/link'
4 |
5 | export default ({notes}) => {
6 | return (
7 |
8 |
My Notes
9 |
10 |
11 | {notes.map(note => (
12 |
21 | ))}
22 |
23 |
24 | )
25 | }
26 |
27 |
28 | export async function getServerSideProps() {
29 | const res = await fetch(`http://localhost:3000/api/note`)
30 | const {data} = await res.json()
31 |
32 | return {
33 | props: {notes: data}
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/pages/api/note/[id].js:
--------------------------------------------------------------------------------
1 | import nc from 'next-connect'
2 | import notes from '../../../src/data/data'
3 |
4 | const getNote = id => notes.find(n => n.id === parseInt(id))
5 |
6 | const handler = nc()
7 | .get((req, res) => {
8 |
9 | const note = getNote(req.query.id)
10 |
11 | if (!note) {
12 | res.status(404)
13 | res.end()
14 | return
15 | }
16 |
17 | res.json({data: note})
18 | })
19 | .patch((req, res) => {
20 | const note = getNote(req.query.id)
21 |
22 | if (!note) {
23 | res.status(404)
24 | res.end()
25 | return
26 | }
27 |
28 | const i = notes.findIndex(n => n.id === parseInt(req.query.id))
29 | const updated = {...note, ...req.body}
30 |
31 | notes[i] = updated
32 | res.json({data: updated})
33 | })
34 | .delete((req, res) => {
35 | const note = getNote(req.query.id)
36 |
37 | if (!note) {
38 | res.status(404)
39 | res.end()
40 | return
41 | }
42 | const i = notes.findIndex(n => n.id === parseInt(req.query.id))
43 |
44 | notes.splice(i, 1)
45 |
46 | res.json({data: req.query.id})
47 | })
48 |
49 |
50 | export default handler
51 |
--------------------------------------------------------------------------------