diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1437c53
--- /dev/null
+++ b/.gitignore
@@ -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
diff --git a/Procfile b/Procfile
new file mode 100644
index 0000000..709e0a2
--- /dev/null
+++ b/Procfile
@@ -0,0 +1 @@
+web: yarn start
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0f980ed
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+---
+title: NextJS Prisma
+description: A NextJS app using Prisma with a PostgreSQL database
+tags:
+ - next
+ - prisma
+ - postgresql
+ - typescript
+---
+
+# NextJS Prisma Example
+
+This example is a [NextJS](https://nextjs.org/) todo app that uses
+[Prisma](https://www.prisma.io/) to store todos in Postgres.
+
+[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new?template=https%3A%2F%2Fgithub.com%2Frailwayapp%2Fexamples%2Ftree%2Fmaster%2Fexamples%2Fnextjs-prisma&plugins=postgresql)
+
+## ✨ Features
+
+- Prisma
+- NextJS
+- Postgres
+- TypeScript
+
+## 💁♀️ How to use
+
+- [Provision a Postgres container on Railway](https://dev.new)
+- Connect to your Railway project with `railway link`
+- Migrate the database `railway run yarn migrate:dev`
+- Run the NextJS app `railway run yarn dev`
+
+## 📝 Notes
+
+This app is a simple todo list where the data is persisted to Postgres. [Prisma
+migrations](https://www.prisma.io/docs/concepts/components/prisma-migrate#prisma-migrate)
+can be created with `railway run yarn migrate:dev` and deployed with `railway run yarn migrate:deploy`. The Prisma client can be regenerated with
+`yarn generate`.
+
+[swr](https://swr.vercel.app/) is used to fetch data on the client and perform optimistic updates.
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 0000000..7b7aa2c
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,2 @@
+///
+///
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..21b41e4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "with-nextjs-postgres",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "yarn migrate:deploy && next build",
+ "start": "next start --port ${PORT-3000}",
+ "migrate:dev": "prisma migrate dev --preview-feature",
+ "migrate:deploy": "prisma migrate deploy --preview-feature",
+ "migrate:status": "prisma migrate status --preview-feature",
+ "generate": "prisma generate"
+ },
+ "dependencies": {
+ "@prisma/client": "2.30.0",
+ "next": "12.1.0",
+ "pg": "^8.5.1",
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "swr": "^0.4.1"
+ },
+ "devDependencies": {
+ "prisma": "2.30.0",
+ "@types/node": "^14.14.22",
+ "@types/react": "^17.0.0",
+ "typescript": "^4.1.3"
+ }
+}
diff --git a/prisma/migrations/20210130000309_init/migration.sql b/prisma/migrations/20210130000309_init/migration.sql
new file mode 100644
index 0000000..f4c6c6e
--- /dev/null
+++ b/prisma/migrations/20210130000309_init/migration.sql
@@ -0,0 +1,9 @@
+-- CreateTable
+CREATE TABLE "Todo" (
+ "id" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "text" TEXT NOT NULL,
+ "completed" BOOLEAN NOT NULL,
+
+ PRIMARY KEY ("id")
+);
diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml
new file mode 100644
index 0000000..2cdb8f0
--- /dev/null
+++ b/prisma/migrations/migration_lock.toml
@@ -0,0 +1,2 @@
+# Please do not edit this file manually
+provider = "postgresql"
\ No newline at end of file
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
new file mode 100644
index 0000000..9a95238
--- /dev/null
+++ b/prisma/schema.prisma
@@ -0,0 +1,18 @@
+// This is your Prisma schema file,
+// learn more about it in the docs: https://pris.ly/d/prisma-schema
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+generator client {
+ provider = "prisma-client-js"
+}
+
+model Todo {
+ id String @id @default(uuid())
+ createdAt DateTime @default(now())
+ text String
+ completed Boolean
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..4965832
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/vercel.svg b/public/vercel.svg
new file mode 100644
index 0000000..fbf0e25
--- /dev/null
+++ b/public/vercel.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/src/api.ts b/src/api.ts
new file mode 100644
index 0000000..28d9e60
--- /dev/null
+++ b/src/api.ts
@@ -0,0 +1,42 @@
+import useSWR, { mutate } from "swr";
+import { Todo } from "./types";
+
+const todoPath = "/api/todos";
+
+export const useTodos = () => useSWR(todoPath);
+
+export const createTodo = async (text: string) => {
+ mutate(
+ todoPath,
+ todos => [{ text, completed: false, id: "new-todo" }, ...todos],
+ false,
+ );
+ await fetch(todoPath, {
+ method: "POST",
+ body: JSON.stringify({ text }),
+ });
+
+ mutate(todoPath);
+};
+
+export const toggleTodo = async (todo: Todo) => {
+ mutate(
+ todoPath,
+ todos =>
+ todos.map(t =>
+ t.id === todo.id ? { ...todo, completed: !t.completed } : t,
+ ),
+ false,
+ );
+ await fetch(`${todoPath}?todoId=${todo.id}`, {
+ method: "PUT",
+ body: JSON.stringify({ completed: !todo.completed }),
+ });
+ mutate(todoPath);
+};
+
+export const deleteTodo = async (id: string) => {
+ mutate(todoPath, todos => todos.filter(t => t.id !== id), false);
+ await fetch(`${todoPath}?todoId=${id}`, { method: "DELETE" });
+ mutate(todoPath);
+};
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
new file mode 100644
index 0000000..1e1cec9
--- /dev/null
+++ b/src/pages/_app.tsx
@@ -0,0 +1,7 @@
+import '../styles/globals.css'
+
+function MyApp({ Component, pageProps }) {
+ return
+}
+
+export default MyApp
diff --git a/src/pages/api/todos.ts b/src/pages/api/todos.ts
new file mode 100644
index 0000000..013fe3b
--- /dev/null
+++ b/src/pages/api/todos.ts
@@ -0,0 +1,38 @@
+import type { NextApiRequest, NextApiResponse } from "next";
+import { PrismaClient } from "@prisma/client";
+
+const prisma = new PrismaClient();
+
+export default async (req: NextApiRequest, res: NextApiResponse) => {
+ if (req.method === "GET") {
+ // get all todos
+ const todos = await prisma.todo.findMany({
+ orderBy: { createdAt: "desc" },
+ });
+ res.json(todos);
+ } else if (req.method === "POST") {
+ // create todo
+ const text = JSON.parse(req.body).text;
+ const todo = await prisma.todo.create({
+ data: { text, completed: false },
+ });
+
+ res.json(todo);
+ } else if (req.method === "PUT") {
+ // update todo
+ const id = req.query.todoId as string;
+ const data = JSON.parse(req.body);
+ const todo = await prisma.todo.update({
+ where: { id },
+ data,
+ });
+
+ res.json(todo);
+ } else if (req.method === "DELETE") {
+ // delete todo
+ const id = req.query.todoId as string;
+ await prisma.todo.delete({ where: { id } });
+
+ res.json({ status: "ok" });
+ }
+};
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
new file mode 100644
index 0000000..061b2a9
--- /dev/null
+++ b/src/pages/index.tsx
@@ -0,0 +1,95 @@
+import { NextPage } from "next";
+import Head from "next/head";
+import { useMemo, useState } from "react";
+import { createTodo, deleteTodo, toggleTodo, useTodos } from "../api";
+import styles from "../styles/Home.module.css";
+import { Todo } from "../types";
+
+export const TodoList: React.FC = () => {
+ const { data: todos, error } = useTodos();
+
+ if (error != null) return Error loading todos...
;
+ if (todos == null) return Loading...
;
+
+ if (todos.length === 0) {
+ return Try adding a todo ☝️️
;
+ }
+
+ return (
+
+ {todos.map(todo => (
+
+ ))}
+
+ );
+};
+
+const TodoItem: React.FC<{ todo: Todo }> = ({ todo }) => (
+
+
+
+
+
+);
+
+const AddTodoInput = () => {
+ const [text, setText] = useState("");
+
+ return (
+
+ );
+};
+
+const Home: NextPage = () => {
+ return (
+
+
+
Railway NextJS Prisma
+
+
+
+
+ Todos
+
+ NextJS app connected to Postgres using Prisma and hosted on{" "}
+ Railway
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Home;
diff --git a/src/styles/Home.module.css b/src/styles/Home.module.css
new file mode 100644
index 0000000..f67d477
--- /dev/null
+++ b/src/styles/Home.module.css
@@ -0,0 +1,131 @@
+.container {
+ padding: 0 0.5rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.header {
+ padding: 4rem 0 2rem 0;
+}
+
+.main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ min-width: 500px;
+}
+
+.title {
+ margin: 0;
+ line-height: 1.15;
+ font-size: 4rem;
+ font-weight: bold;
+}
+
+.title,
+.desc {
+ text-align: center;
+}
+
+.desc {
+ line-height: 1.5;
+ font-size: 1rem;
+ font-weight: normal;
+}
+
+.addTodo {
+ display: flex;
+ width: 100%;
+ margin: 0 auto;
+ margin-bottom: 2rem;
+}
+
+.input {
+ padding: 1rem;
+ border: solid 2px;
+ border-color: #cccccc;
+ border-radius: 4px;
+ flex-grow: 1;
+ margin-right: 0.5rem;
+ font-size: 1em;
+}
+
+.addButton {
+ width: 80px;
+ color: white;
+ background-color: #0070f3;
+ border-color: #0070f3;
+ font-size: 1em;
+ border: solid 2px;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+.addButton:hover {
+ color: #0070f3;
+ background-color: white;
+ border-color: #0070f3;
+}
+
+.code {
+ background: #fafafa;
+ border-radius: 5px;
+ padding: 0.75rem;
+ font-size: 1.1rem;
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
+ Bitstream Vera Sans Mono, Courier New, monospace;
+}
+
+.todoList {
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+}
+
+.todo {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.label {
+ flex-grow: 1;
+ font-size: 1.1rem;
+ padding: 0.5rem 0;
+ cursor: pointer;
+}
+
+.checkbox {
+ margin-right: 1rem;
+}
+
+.checked {
+ text-decoration: line-through;
+}
+
+.deleteButton {
+ font-size: 1rem;
+ border: none;
+ background: none;
+ color: darkgrey;
+ cursor: pointer;
+}
+
+.deleteButton:hover {
+ color: var(--primary);
+}
+
+.emptyState {
+}
+
+@media (max-width: 600px) {
+ .main {
+ min-width: auto;
+ width: 100%;
+ }
+}
diff --git a/src/styles/globals.css b/src/styles/globals.css
new file mode 100644
index 0000000..319e937
--- /dev/null
+++ b/src/styles/globals.css
@@ -0,0 +1,26 @@
+:root {
+ --primary: #c049ff;
+}
+
+html,
+body {
+ padding: 0;
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
+ Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
+}
+
+a {
+ color: var(--primary);
+ text-decoration: none;
+}
+
+a:hover,
+a:focus,
+a:active {
+ text-decoration: underline;
+}
+
+* {
+ box-sizing: border-box;
+}
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..279563b
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,6 @@
+export interface Todo {
+ id: string;
+ created: string;
+ text: string;
+ completed: boolean;
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..35d51ea
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,29 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve"
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..d28920d
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,333 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@next/env@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314"
+ integrity sha512-nrIgY6t17FQ9xxwH3jj0a6EOiQ/WDHUos35Hghtr+SWN/ntHIQ7UpuvSi0vaLzZVHQWaDupKI+liO5vANcDeTQ==
+
+"@next/swc-android-arm64@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.1.0.tgz#865ba3a9afc204ff2bdeea49dd64d58705007a39"
+ integrity sha512-/280MLdZe0W03stA69iL+v6I+J1ascrQ6FrXBlXGCsGzrfMaGr7fskMa0T5AhQIVQD4nA/46QQWxG//DYuFBcA==
+
+"@next/swc-darwin-arm64@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.1.0.tgz#08e8b411b8accd095009ed12efbc2f1d4d547135"
+ integrity sha512-R8vcXE2/iONJ1Unf5Ptqjk6LRW3bggH+8drNkkzH4FLEQkHtELhvcmJwkXcuipyQCsIakldAXhRbZmm3YN1vXg==
+
+"@next/swc-darwin-x64@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.1.0.tgz#fcd684497a76e8feaca88db3c394480ff0b007cd"
+ integrity sha512-ieAz0/J0PhmbZBB8+EA/JGdhRHBogF8BWaeqR7hwveb6SYEIJaDNQy0I+ZN8gF8hLj63bEDxJAs/cEhdnTq+ug==
+
+"@next/swc-linux-arm-gnueabihf@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.1.0.tgz#9ec6380a27938a5799aaa6035c205b3c478468a7"
+ integrity sha512-njUd9hpl6o6A5d08dC0cKAgXKCzm5fFtgGe6i0eko8IAdtAPbtHxtpre3VeSxdZvuGFh+hb0REySQP9T1ttkog==
+
+"@next/swc-linux-arm64-gnu@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.1.0.tgz#7f4196dff1049cea479607c75b81033ae2dbd093"
+ integrity sha512-OqangJLkRxVxMhDtcb7Qn1xjzFA3s50EIxY7mljbSCLybU+sByPaWAHY4px97ieOlr2y4S0xdPKkQ3BCAwyo6Q==
+
+"@next/swc-linux-arm64-musl@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.1.0.tgz#b445f767569cdc2dddee785ca495e1a88c025566"
+ integrity sha512-hB8cLSt4GdmOpcwRe2UzI5UWn6HHO/vLkr5OTuNvCJ5xGDwpPXelVkYW/0+C3g5axbDW2Tym4S+MQCkkH9QfWA==
+
+"@next/swc-linux-x64-gnu@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.1.0.tgz#67610e9be4fbc987de7535f1bcb17e45fe12f90e"
+ integrity sha512-OKO4R/digvrVuweSw/uBM4nSdyzsBV5EwkUeeG4KVpkIZEe64ZwRpnFB65bC6hGwxIBnTv5NMSnJ+0K/WmG78A==
+
+"@next/swc-linux-x64-musl@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.1.0.tgz#ea19a23db08a9f2e34ac30401f774cf7d1669d31"
+ integrity sha512-JohhgAHZvOD3rQY7tlp7NlmvtvYHBYgY0x5ZCecUT6eCCcl9lv6iV3nfu82ErkxNk1H893fqH0FUpznZ/H3pSw==
+
+"@next/swc-win32-arm64-msvc@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.1.0.tgz#eadf054fc412085659b98e145435bbba200b5283"
+ integrity sha512-T/3gIE6QEfKIJ4dmJk75v9hhNiYZhQYAoYm4iVo1TgcsuaKLFa+zMPh4056AHiG6n9tn2UQ1CFE8EoybEsqsSw==
+
+"@next/swc-win32-ia32-msvc@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.1.0.tgz#68faeae10c89f698bf9d28759172b74c9c21bda1"
+ integrity sha512-iwnKgHJdqhIW19H9PRPM9j55V6RdcOo6rX+5imx832BCWzkDbyomWnlzBfr6ByUYfhohb8QuH4hSGEikpPqI0Q==
+
+"@next/swc-win32-x64-msvc@12.1.0":
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.1.0.tgz#d27e7e76c87a460a4da99c5bfdb1618dcd6cd064"
+ integrity sha512-aBvcbMwuanDH4EMrL2TthNJy+4nP59Bimn8egqv6GHMVj0a44cU6Au4PjOhLNqEh9l+IpRGBqMTzec94UdC5xg==
+
+"@prisma/client@2.30.0":
+ version "2.30.0"
+ resolved "https://registry.yarnpkg.com/@prisma/client/-/client-2.30.0.tgz#b0ed9db67405f619e428577f2d45843104142e00"
+ integrity sha512-tjJNHVfgyNOwS2F+AkjMMCJGPnXzHuUCrOnAMJyidAu4aNzxbJ8jWwjt96rRMpyrg9Hwen3xqqQ2oA+ikK7nhQ==
+ dependencies:
+ "@prisma/engines-version" "2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb"
+
+"@prisma/engines-version@2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb":
+ version "2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb"
+ resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb.tgz#1360113dc19e1d43d4442e3b638ccfa0e1711943"
+ integrity sha512-oThNpx7HtJ0eEmnvrWARYcNCs6dqFdAK3Smt2bJVDD6Go4HLuuhjx028osP+rHaFrGOTx7OslLZYtvvFlAXRDA==
+
+"@prisma/engines@2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb":
+ version "2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb"
+ resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb.tgz#b4d91ff876662b1de83e0cc913149a1c088becc7"
+ integrity sha512-LPKq88lIbYezvX0OOc1PU42hHdTsSMPJWmK8lusaHK7DaLHyXjDp/551LbsVapypbjW6N3Jx/If6GoMDASSMSw==
+
+"@types/node@^14.14.22":
+ version "14.14.22"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18"
+ integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==
+
+"@types/prop-types@*":
+ version "15.7.3"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
+ integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
+
+"@types/react@^17.0.0":
+ version "17.0.0"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8"
+ integrity sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^3.0.2"
+
+buffer-writer@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
+ integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
+
+caniuse-lite@^1.0.30001283:
+ version "1.0.30001334"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001334.tgz#892e9965b35285033fc2b8a8eff499fe02f13d8b"
+ integrity sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw==
+
+csstype@^3.0.2:
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.5.tgz#7fdec6a28a67ae18647c51668a9ff95bb2fa7bb8"
+ integrity sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==
+
+dequal@2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d"
+ integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==
+
+"js-tokens@^3.0.0 || ^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+loose-envify@^1.1.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
+nanoid@^3.1.30:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
+ integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
+
+next@12.1.0:
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/next/-/next-12.1.0.tgz#c33d753b644be92fc58e06e5a214f143da61dd5d"
+ integrity sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==
+ dependencies:
+ "@next/env" "12.1.0"
+ caniuse-lite "^1.0.30001283"
+ postcss "8.4.5"
+ styled-jsx "5.0.0"
+ use-subscription "1.5.1"
+ optionalDependencies:
+ "@next/swc-android-arm64" "12.1.0"
+ "@next/swc-darwin-arm64" "12.1.0"
+ "@next/swc-darwin-x64" "12.1.0"
+ "@next/swc-linux-arm-gnueabihf" "12.1.0"
+ "@next/swc-linux-arm64-gnu" "12.1.0"
+ "@next/swc-linux-arm64-musl" "12.1.0"
+ "@next/swc-linux-x64-gnu" "12.1.0"
+ "@next/swc-linux-x64-musl" "12.1.0"
+ "@next/swc-win32-arm64-msvc" "12.1.0"
+ "@next/swc-win32-ia32-msvc" "12.1.0"
+ "@next/swc-win32-x64-msvc" "12.1.0"
+
+object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+ integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
+
+packet-reader@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
+ integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
+
+pg-connection-string@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10"
+ integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==
+
+pg-int8@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
+ integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
+
+pg-pool@^3.2.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.2.2.tgz#a560e433443ed4ad946b84d774b3f22452694dff"
+ integrity sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==
+
+pg-protocol@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.4.0.tgz#43a71a92f6fe3ac559952555aa3335c8cb4908be"
+ integrity sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==
+
+pg-types@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
+ integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
+ dependencies:
+ pg-int8 "1.0.1"
+ postgres-array "~2.0.0"
+ postgres-bytea "~1.0.0"
+ postgres-date "~1.0.4"
+ postgres-interval "^1.1.0"
+
+pg@^8.5.1:
+ version "8.5.1"
+ resolved "https://registry.yarnpkg.com/pg/-/pg-8.5.1.tgz#34dcb15f6db4a29c702bf5031ef2e1e25a06a120"
+ integrity sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==
+ dependencies:
+ buffer-writer "2.0.0"
+ packet-reader "1.0.0"
+ pg-connection-string "^2.4.0"
+ pg-pool "^3.2.2"
+ pg-protocol "^1.4.0"
+ pg-types "^2.1.0"
+ pgpass "1.x"
+
+pgpass@1.x:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306"
+ integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=
+ dependencies:
+ split "^1.0.0"
+
+picocolors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
+ integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+
+postcss@8.4.5:
+ version "8.4.5"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
+ integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==
+ dependencies:
+ nanoid "^3.1.30"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.1"
+
+postgres-array@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
+ integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
+
+postgres-bytea@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
+ integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
+
+postgres-date@~1.0.4:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.5.tgz#710b27de5f27d550f6e80b5d34f7ba189213c2ee"
+ integrity sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==
+
+postgres-interval@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
+ integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==
+ dependencies:
+ xtend "^4.0.0"
+
+prisma@2.30.0:
+ version "2.30.0"
+ resolved "https://registry.yarnpkg.com/prisma/-/prisma-2.30.0.tgz#5b12091c480d538540b898d364b73651d44b4a01"
+ integrity sha512-2XYpSibcVpMd1JDxYypGDU/JKq0W2f/HI1itdddr4Pfg+q6qxt/ItWKcftv4/lqN6u/BVlQ2gDzXVEjpHeO5kQ==
+ dependencies:
+ "@prisma/engines" "2.30.0-28.60b19f4a1de4fe95741da371b4c44a92f4d1adcb"
+
+react-dom@17.0.1:
+ version "17.0.1"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
+ integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ scheduler "^0.20.1"
+
+react@17.0.1:
+ version "17.0.1"
+ resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
+ integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
+scheduler@^0.20.1:
+ version "0.20.1"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.1.tgz#da0b907e24026b01181ecbc75efdc7f27b5a000c"
+ integrity sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
+source-map-js@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
+split@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
+ integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
+ dependencies:
+ through "2"
+
+styled-jsx@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77"
+ integrity sha512-qUqsWoBquEdERe10EW8vLp3jT25s/ssG1/qX5gZ4wu15OZpmSMFI2v+fWlRhLfykA5rFtlJ1ME8A8pm/peV4WA==
+
+swr@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/swr/-/swr-0.4.1.tgz#4bb1f9e994a8f8d7a2e9220dbc7aef296bc4a673"
+ integrity sha512-/jQWPjCwy7rNbEJKpuObfbtJHtneTKhlzjy8VkuAEGg/kkYhZoKWVdGtIXrz9vuTGdy/grLVWpA6DfiNk9ECWg==
+ dependencies:
+ dequal "2.0.2"
+
+through@2:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+
+typescript@^4.1.3:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
+ integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
+
+use-subscription@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
+ integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==
+ dependencies:
+ object-assign "^4.1.1"
+
+xtend@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
+ integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==