From b97fbb6c7f601e8c8900e09d815f1516b5c3e1c5 Mon Sep 17 00:00:00 2001 From: Hope Fourie Date: Wed, 13 Apr 2022 09:26:16 -0400 Subject: [PATCH] users api --- components/{date.js => date.tsx} | 0 components/{layout.js => layout.tsx} | 26 ++++--- next-env.d.ts | 5 ++ package-lock.json | 111 ++++++++++++++++++++++++++- package.json | 8 +- pages/{_app.js => _app.tsx} | 0 pages/api/hello.js | 3 - pages/api/users.tsx | 6 ++ pages/api/users/[id].tsx | 20 +++++ pages/{index.js => index.tsx} | 44 +++++++---- pages/posts/{[id].js => [id].tsx} | 0 pages/users/[id].tsx | 17 ++++ tsconfig.json | 30 ++++++++ 13 files changed, 242 insertions(+), 28 deletions(-) rename components/{date.js => date.tsx} (100%) rename components/{layout.js => layout.tsx} (80%) create mode 100644 next-env.d.ts rename pages/{_app.js => _app.tsx} (100%) delete mode 100644 pages/api/hello.js create mode 100644 pages/api/users.tsx create mode 100644 pages/api/users/[id].tsx rename pages/{index.js => index.tsx} (53%) rename pages/posts/{[id].js => [id].tsx} (100%) create mode 100644 pages/users/[id].tsx create mode 100644 tsconfig.json diff --git a/components/date.js b/components/date.tsx similarity index 100% rename from components/date.js rename to components/date.tsx diff --git a/components/layout.js b/components/layout.tsx similarity index 80% rename from components/layout.js rename to components/layout.tsx index 92f0214..147dc4c 100644 --- a/components/layout.js +++ b/components/layout.tsx @@ -1,16 +1,22 @@ -import Head from 'next/head' -import Image from 'next/image' -import styles from './layout.module.css' -import utilStyles from '../styles/utils.module.css' -import Link from 'next/link' +import React from 'react' +import Head from "next/head"; +import Image from "next/image"; +import styles from "./layout.module.css"; +import utilStyles from "../styles/utils.module.css"; +import Link from "next/link"; -const name = '[Your Name]' -export const siteTitle = 'Next.js Sample Website' +const name = "[Your Name]"; +export const siteTitle = "Next.js Sample Website"; -export default function Layout({ children, home }) { +type Props = { + children: React.ReactNode; + home?: boolean; +}; + +export default function Layout({ children, home }: Props) { return (
- + )}
- ) + ); } diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/package-lock.json b/package-lock.json index 1069da8..800553f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,13 @@ "react": "17.0.2", "react-dom": "17.0.2", "remark": "^14.0.1", - "remark-html": "^15.0.0" + "remark-html": "^15.0.0", + "swr": "^1.3.0" + }, + "devDependencies": { + "@types/node": "^17.0.23", + "@types/react": "^18.0.3", + "typescript": "^4.6.3" } }, "node_modules/@next/env": { @@ -233,6 +239,35 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, + "node_modules/@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.0.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.3.tgz", + "integrity": "sha512-P8QUaMW4k+kH9aKNPl9b3XWcKMSSALYprLL8xpAMJOLUn3Pl6B+6nKC4F7dsk9oJPwkiRx+qlwhG/Zc1LxFVuQ==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -315,6 +350,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", + "dev": true + }, "node_modules/date-fns": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", @@ -1400,6 +1441,14 @@ "node": ">=0.10.0" } }, + "node_modules/swr": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz", + "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==", + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", @@ -1409,6 +1458,19 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", @@ -1675,6 +1737,35 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true + }, + "@types/react": { + "version": "18.0.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.3.tgz", + "integrity": "sha512-P8QUaMW4k+kH9aKNPl9b3XWcKMSSALYprLL8xpAMJOLUn3Pl6B+6nKC4F7dsk9oJPwkiRx+qlwhG/Zc1LxFVuQ==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -1723,6 +1814,12 @@ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==" }, + "csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", + "dev": true + }, "date-fns": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", @@ -2370,11 +2467,23 @@ "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=" }, + "swr": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz", + "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==", + "requires": {} + }, "trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==" }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true + }, "unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", diff --git a/package.json b/package.json index dde93f3..2fe657f 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,12 @@ "react": "17.0.2", "react-dom": "17.0.2", "remark": "^14.0.1", - "remark-html": "^15.0.0" + "remark-html": "^15.0.0", + "swr": "^1.3.0" + }, + "devDependencies": { + "@types/node": "^17.0.23", + "@types/react": "^18.0.3", + "typescript": "^4.6.3" } } diff --git a/pages/_app.js b/pages/_app.tsx similarity index 100% rename from pages/_app.js rename to pages/_app.tsx diff --git a/pages/api/hello.js b/pages/api/hello.js deleted file mode 100644 index 2e22ab3..0000000 --- a/pages/api/hello.js +++ /dev/null @@ -1,3 +0,0 @@ -export default (req, res) => { - res.status(200).json({ text: 'Hello' }) -} diff --git a/pages/api/users.tsx b/pages/api/users.tsx new file mode 100644 index 0000000..acf704e --- /dev/null +++ b/pages/api/users.tsx @@ -0,0 +1,6 @@ +const users = [{ id: 1 }, { id: 2 }, { id: 3 }] + +export default function handler(req, res) { + // Get data from your database + res.status(200).json(users) +} \ No newline at end of file diff --git a/pages/api/users/[id].tsx b/pages/api/users/[id].tsx new file mode 100644 index 0000000..2f6fbcb --- /dev/null +++ b/pages/api/users/[id].tsx @@ -0,0 +1,20 @@ +export default function userHandler(req, res) { + const { + query: { id, name }, + method, + } = req + + switch (method) { + case 'GET': + // Get data from your database + res.status(200).json({ id, name: `User ${id}` }) + break + case 'PUT': + // Update or create data in your database + res.status(200).json({ id, name: name || `User ${id}` }) + break + default: + res.setHeader('Allow', ['GET', 'PUT']) + res.status(405).end(`Method ${method} Not Allowed`) + } + } \ No newline at end of file diff --git a/pages/index.js b/pages/index.tsx similarity index 53% rename from pages/index.js rename to pages/index.tsx index f09aed3..5b60bc7 100644 --- a/pages/index.js +++ b/pages/index.tsx @@ -1,20 +1,28 @@ -import Head from 'next/head' -import Layout, { siteTitle } from '../components/layout' -import utilStyles from '../styles/utils.module.css' -import { getSortedPostsData } from '../lib/posts' -import Link from 'next/link' -import Date from '../components/date' +import Head from "next/head"; +import Layout, { siteTitle } from "../components/layout"; +import utilStyles from "../styles/utils.module.css"; +import { getSortedPostsData } from "../lib/posts"; +import Link from "next/link"; +import Date from "../components/date"; +import useSwr from 'swr' + + +const fetcher = (url) => fetch(url).then((res) => res.json()) export default function Home({ allPostsData }) { + const { data, error } = useSwr('/api/users', fetcher) + + if (error) return
Failed to load users
+ if (!data) return
Loading...
return ( - + {siteTitle}

[Your Self Introduction]

- (This is a sample website - you’ll be building a site like this in{' '} + (This is a sample website - you’ll be building a site like this in{" "} our Next.js tutorial.)

@@ -33,16 +41,26 @@ export default function Home({ allPostsData }) { ))} +

Users

+
- ) + ); } export async function getStaticProps() { - const allPostsData = getSortedPostsData() + const allPostsData = getSortedPostsData(); return { props: { - allPostsData - } - } + allPostsData, + }, + }; } diff --git a/pages/posts/[id].js b/pages/posts/[id].tsx similarity index 100% rename from pages/posts/[id].js rename to pages/posts/[id].tsx diff --git a/pages/users/[id].tsx b/pages/users/[id].tsx new file mode 100644 index 0000000..2a6b6ed --- /dev/null +++ b/pages/users/[id].tsx @@ -0,0 +1,17 @@ +import { useRouter } from 'next/router' +import useSwr from 'swr' + +const fetcher = (url) => fetch(url).then((res) => res.json()) + +export default function User() { + const router = useRouter() + const { data, error } = useSwr( + router.query.id ? `/api/users/${router.query.id}` : null, + fetcher + ) + + if (error) return
Failed to load user
+ if (!data) return
Loading...
+ + return
{data.name}
+} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6db37c0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx" + ], + "exclude": [ + "node_modules" + ] +}