Skip to content

Commit

Permalink
Commited!
Browse files Browse the repository at this point in the history
  • Loading branch information
Obadja Ris committed Sep 15, 2020
1 parent 09571a7 commit 81eba2e
Show file tree
Hide file tree
Showing 27 changed files with 1,722 additions and 8 deletions.
16 changes: 16 additions & 0 deletions app/choices/mutations/createChoice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SessionContext } from "blitz"
import db, { ChoiceCreateArgs } from "db"

type CreateChoiceInput = {
data: ChoiceCreateArgs["data"]
}
export default async function createChoice(
{ data }: CreateChoiceInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const choice = await db.choice.create({ data })

return choice
}
17 changes: 17 additions & 0 deletions app/choices/mutations/deleteChoice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { SessionContext } from "blitz"
import db, { ChoiceDeleteArgs } from "db"

type DeleteChoiceInput = {
where: ChoiceDeleteArgs["where"]
}

export default async function deleteChoice(
{ where }: DeleteChoiceInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const choice = await db.choice.delete({ where })

return choice
}
18 changes: 18 additions & 0 deletions app/choices/mutations/updateChoice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { SessionContext } from "blitz"
import db, { ChoiceUpdateArgs } from "db"

type UpdateChoiceInput = {
where: ChoiceUpdateArgs["where"]
data: ChoiceUpdateArgs["data"]
}

export default async function updateChoice(
{ where, data }: UpdateChoiceInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const choice = await db.choice.update({ where, data })

return choice
}
21 changes: 21 additions & 0 deletions app/choices/queries/getChoice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NotFoundError, SessionContext } from "blitz"
import db, { FindOneChoiceArgs } from "db"

type GetChoiceInput = {
where: FindOneChoiceArgs["where"]
// Only available if a model relationship exists
// include?: FindOneChoiceArgs['include']
}

export default async function getChoice(
{ where /* include */ }: GetChoiceInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const choice = await db.choice.findOne({ where })

if (!choice) throw new NotFoundError()

return choice
}
35 changes: 35 additions & 0 deletions app/choices/queries/getChoices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { SessionContext } from "blitz"
import db, { FindManyChoiceArgs } from "db"

type GetChoicesInput = {
where?: FindManyChoiceArgs["where"]
orderBy?: FindManyChoiceArgs["orderBy"]
skip?: FindManyChoiceArgs["skip"]
take?: FindManyChoiceArgs["take"]
// Only available if a model relationship exists
// include?: FindManyChoiceArgs['include']
}

export default async function getChoices(
{ where, orderBy, skip = 0, take }: GetChoicesInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const choices = await db.choice.findMany({
where,
orderBy,
take,
skip,
})

const count = await db.choice.count()
const hasMore = typeof take === "number" ? skip + take < count : false
const nextPage = hasMore ? { take, skip: skip + take! } : null

return {
choices,
nextPage,
hasMore,
}
}
Empty file added app/layouts/style.css
Empty file.
26 changes: 26 additions & 0 deletions app/questions/components/QuestionForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react"

type QuestionFormProps = {
initialValues: any
onSubmit: React.FormEventHandler<HTMLFormElement>
}

const QuestionForm = ({ initialValues, onSubmit }: QuestionFormProps) => {
return (
<form
onSubmit={(event) => {
event.preventDefault()
onSubmit(event)
}}
>
<input placeholder="Name" />
<input placeholder="Choice 1" />
<input placeholder="Choice 2" />
<input placeholder="Choice 3" />
<div>{JSON.stringify(initialValues)}</div>
<button>Submit</button>
</form>
)
}

export default QuestionForm
16 changes: 16 additions & 0 deletions app/questions/mutations/createQuestion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SessionContext } from "blitz"
import db, { QuestionCreateArgs } from "db"

type CreateQuestionInput = {
data: QuestionCreateArgs["data"]
}
export default async function createQuestion(
{ data }: CreateQuestionInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const question = await db.question.create({ data })

return question
}
10 changes: 10 additions & 0 deletions app/questions/mutations/deleteQuestion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import db, { FindManyQuestionArgs } from "db"
export default async function deleteQuestion(
{ where }: DeleteQuestionInput,
ctx: Record<any, any> = {}
) {
// TODO: remove once Prisma supports cascading deletes
await db.choice.deleteMany({ where: { question: { id: where.id } } })
const question = await db.question.delete({ where })
return question
}
18 changes: 18 additions & 0 deletions app/questions/mutations/updateQuestion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { SessionContext } from "blitz"
import db, { QuestionUpdateArgs } from "db"

type UpdateQuestionInput = {
where: QuestionUpdateArgs["where"]
data: QuestionUpdateArgs["data"]
}

export default async function updateQuestion(
{ where, data }: UpdateQuestionInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()

const question = await db.question.update({ where, data })

return question
}
79 changes: 79 additions & 0 deletions app/questions/pages/questions/[questionId].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { Suspense } from "react"
import Layout from "app/layouts/Layout"
import { Head, Link, useRouter, useQuery, useParam, BlitzPage } from "blitz"
import getQuestion from "app/questions/queries/getQuestion"
import deleteQuestion from "app/questions/mutations/deleteQuestion"
import updateChoice from "app/choices/mutations/updateChoice"

export const Question = () => {
const router = useRouter()
const questionId = useParam("questionId", "number")
const [question, { refetch }] = useQuery(getQuestion, { where: { id: questionId } })
const handleVote = async (id, votes) => {
try {
const updated = await updateChoice({
where: { id },
data: { votes: votes + 1 },
})
refetch()
} catch (error) {
alert("Error creating question " + JSON.stringify(error, null, 2))
}
}

return (
<div>
<h1>{question.text}</h1>
<ul>
{question.choices.map((choice) => (
<li key={choice.id}>
{choice.text} - {choice.votes} votes
<button onClick={() => handleVote(choice.id, choice.votes)}>Vote</button>
</li>
))}
</ul>

<Link href="/questions/[questionId]/edit" as={`/questions/${question.id}/edit`}>
<a>Edit</a>
</Link>

<button
type="button"
onClick={async () => {
if (window.confirm("This will be deleted")) {
await deleteQuestion({ where: { id: question.id } })
router.push("/questions")
}
}}
>
Delete
</button>
</div>
)
}

const ShowQuestionPage: BlitzPage = () => {
return (
<div>
<Head>
<title>Question</title>
</Head>

<main>
<p>
<Link href="/questions">
<a>Questions</a>
</Link>
</p>

<Suspense fallback={<div>Loading...</div>}>
<Question />
</Suspense>
</main>
</div>
)
}

ShowQuestionPage.getLayout = (page) => <Layout title={"Question"}>{page}</Layout>

export default ShowQuestionPage
63 changes: 63 additions & 0 deletions app/questions/pages/questions/[questionId]/edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { Suspense } from "react"
import Layout from "app/layouts/Layout"
import { Head, Link, useRouter, useQuery, useParam, BlitzPage } from "blitz"
import getQuestion from "app/questions/queries/getQuestion"
import updateQuestion from "app/questions/mutations/updateQuestion"
import QuestionForm from "app/questions/components/QuestionForm"

export const EditQuestion = () => {
const router = useRouter()
const questionId = useParam("questionId", "number")
const [question, { mutate }] = useQuery(getQuestion, { where: { id: questionId } })

return (
<div>
<h1>Edit Question {question.id}</h1>
<pre>{JSON.stringify(question)}</pre>

<QuestionForm
initialValues={question}
onSubmit={async () => {
try {
const updated = await updateQuestion({
where: { id: question.id },
data: { text: "Do you really love Blitz?" },
})
mutate(updated)
alert("Success!" + JSON.stringify(updated))
router.push("/questions/[questionId]", `/questions/${updated.id}`)
} catch (error) {
console.log(error)
alert("Error creating question " + JSON.stringify(error, null, 2))
}
}}
/>
</div>
)
}

const EditQuestionPage: BlitzPage = () => {
return (
<div>
<Head>
<title>Edit Question</title>
</Head>

<main>
<Suspense fallback={<div>Loading...</div>}>
<EditQuestion />
</Suspense>

<p>
<Link href="/questions">
<a>Questions</a>
</Link>
</p>
</main>
</div>
)
}

EditQuestionPage.getLayout = (page) => <Layout title={"Edit Question"}>{page}</Layout>

export default EditQuestionPage
Loading

0 comments on commit 81eba2e

Please sign in to comment.