Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vercel-Prisma-NextJS #179

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion apps/vercel/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ RUN apk add g++ && apk add make

WORKDIR /var/www/app

RUN yarn install
RUN yarn install

# Vercel CLIのインストール
RUN yarn global add vercel@latest
25 changes: 25 additions & 0 deletions apps/vercel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Fullstack Authentication Example with Next.js and NextAuth.js

This is the starter project for the fullstack tutorial with Next.js and Prisma. You can find the final version of this project in the [`final`](https://github.com/prisma/blogr-nextjs-prisma/tree/final) branch of this repo.

## Installation
```sh
$ docker compose up -d --build

# docker exec -it alife_lab sh
$ docker exec -it <container-name> sh

$ vercel env pull .env
```

## Development
### Migration
```sh
# change src/prisma/schema.prisma
$ yarn prisma db push
```

### Reset DB
```sh
$ yarn prisma db push --force-reset
```
3 changes: 2 additions & 1 deletion apps/vercel/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ services:
container_name: alife_lab
build: ./
ports:
- '8012:3000'
- '8012:3000' # 本体
- '8020:5555' # Prisma Studio
volumes:
- ./src:/var/www/app
tty: true
5 changes: 4 additions & 1 deletion apps/vercel/src/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

.next/
.vercel/
node_modules/
.env
.env
.DS_STORE
>>>>>>> main
211 changes: 211 additions & 0 deletions apps/vercel/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { signOut, useSession } from 'next-auth/react';

const Header: React.FC = () => {
const router = useRouter();
const isActive: (pathname: string) => boolean = (pathname) =>
router.pathname === pathname;

const { data: session, status } = useSession();

let left = (
<div className="left">
<Link href="/">
<a className="bold" data-active={isActive('/')}>
Feed
</a>
</Link>
<style jsx>{`
.bold {
font-weight: bold;
}

a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}

.left a[data-active='true'] {
color: gray;
}

a + a {
margin-left: 1rem;
}
`}</style>
</div>
);

let right = null;

if (status === 'loading') {
left = (
<div className="left">
<Link href="/">
<a className="bold" data-active={isActive('/')}>
Feed
</a>
</Link>
<style jsx>{`
.bold {
font-weight: bold;
}

a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}

.left a[data-active='true'] {
color: gray;
}

a + a {
margin-left: 1rem;
}
`}</style>
</div>
);
right = (
<div className="right">
<p>Validating session ...</p>
<style jsx>{`
.right {
margin-left: auto;
}
`}</style>
</div>
);
}

if (!session) {
right = (
<div className="right">
<Link href="/api/auth/signin">
<a data-active={isActive('/signup')}>Log in</a>
</Link>
<style jsx>{`
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}

a + a {
margin-left: 1rem;
}

.right {
margin-left: auto;
}

.right a {
border: 1px solid var(--geist-foreground);
padding: 0.5rem 1rem;
border-radius: 3px;
}
`}</style>
</div>
);
}

if (session) {
left = (
<div className="left">
<Link href="/">
<a className="bold" data-active={isActive('/')}>
Feed
</a>
</Link>
<Link href="/drafts">
<a data-active={isActive('/drafts')}>My drafts</a>
</Link>
<style jsx>{`
.bold {
font-weight: bold;
}

a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}

.left a[data-active='true'] {
color: gray;
}

a + a {
margin-left: 1rem;
}
`}</style>
</div>
);
right = (
<div className="right">
<p>
{session.user.name} ({session.user.email})
</p>
<Link href="/create">
<button>
<a>New post</a>
</button>
</Link>
<button onClick={() => signOut()}>
<a>Log out</a>
</button>
<style jsx>{`
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}

p {
display: inline-block;
font-size: 13px;
padding-right: 1rem;
}

a + a {
margin-left: 1rem;
}

.right {
margin-left: auto;
}

.right a {
border: 1px solid var(--geist-foreground);
padding: 0.5rem 1rem;
border-radius: 3px;
}

button {
border: none;
}
`}</style>
</div>
);
}

return (
<nav>
{left}
{right}
<style jsx>{`
nav {
display: flex;
padding: 2rem;
align-items: center;
}
`}</style>
</nav>
);
};

export default Header;
50 changes: 50 additions & 0 deletions apps/vercel/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { ReactNode } from "react";
import Header from "./Header";

type Props = {
children: ReactNode;
};

const Layout: React.FC<Props> = (props) => (
<div>
<Header />
<div className="layout">{props.children}</div>
<style jsx global>{`
html {
box-sizing: border-box;
}

*,
*:before,
*:after {
box-sizing: inherit;
}

body {
margin: 0;
padding: 0;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
background: rgba(0, 0, 0, 0.05);
}

input,
textarea {
font-size: 16px;
}

button {
cursor: pointer;
}
`}</style>
<style jsx>{`
.layout {
padding: 0 2rem;
}
`}</style>
</div>
);

export default Layout;
33 changes: 33 additions & 0 deletions apps/vercel/src/components/Post.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import Router from "next/router";
import ReactMarkdown from "react-markdown";

export type PostProps = {
id: string;
title: string;
author: {
name: string;
email: string;
} | null;
content: string;
published: boolean;
};

const Post: React.FC<{ post: PostProps }> = ({ post }) => {
const authorName = post.author ? post.author.name : "Unknown author";
return (
<div onClick={() => Router.push("/p/[id]", `/p/${post.id}`)}>
<h2>{post.title}</h2>
<small>By {authorName}</small>
<ReactMarkdown children={post.content} />
<style jsx>{`
div {
color: inherit;
padding: 2rem;
}
`}</style>
</div>
);
};

export default Post;
14 changes: 14 additions & 0 deletions apps/vercel/src/lib/prisma.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { PrismaClient } from "@prisma/client"

let prisma: PrismaClient

if (process.env.NODE_ENV === "production") {
prisma = new PrismaClient()
} else {
if (!global.prisma) {
global.prisma = new PrismaClient()
}
prisma = global.prisma
}

export default prisma
5 changes: 5 additions & 0 deletions apps/vercel/src/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
Loading