Skip to content

Commit

Permalink
Merge pull request #17 from psworld/feat/submit_form
Browse files Browse the repository at this point in the history
feat: added submitFormResponse mutation
  • Loading branch information
piyushgarg-dev authored Oct 8, 2023
2 parents e34f7c5 + f1f7082 commit bacb6ce
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 4 deletions.
17 changes: 17 additions & 0 deletions functions/graphql/form/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,20 @@ export interface UpdateFormData {
autoApproveTestimonials?: boolean
autoAddTags?: [string]
}

export interface SubmitFormResponseData {
id: string
formId: string
name: string
email?: string
imageURL?: string
rating?: number
testimonial: string
jobTitle?: string
websiteUrl?: string
company?: string
}

export interface GetFormResponsesByFormIdInput {
formId: string
}
3 changes: 2 additions & 1 deletion functions/graphql/form/mutations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const mutations = `#graphql
createForm(data: CreateFormData!): String
updateForm(data: UpdateFormInput!): Boolean
`
submitFormResponse(data: SubmitFormResponseData!): String
`
1 change: 1 addition & 0 deletions functions/graphql/form/queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const queries = `#graphql
getForms(input: GetFormsInput!): [Form]
getFormById(id: ID!): Form
getFormResponses(input: GetFormResponsesByFormIdInput!): [FormResponse]
`
56 changes: 55 additions & 1 deletion functions/graphql/form/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import slugify from 'slugify'
import FormService from '../../../services/form'
import { ensureAuthenticated } from '../../../utils/auth'
import { ServerContext } from '../interfaces'
import { CreateFormData, GetFormsInput, UpdateFormData } from './interfaces'
import {
CreateFormData,
GetFormResponsesByFormIdInput,
GetFormsInput,
SubmitFormResponseData,
UpdateFormData,
} from './interfaces'
import BadRequestError from '../../../errors/BadRequestError'
import prismaClient from '../../../db'

const queries = {
getForms: async (
Expand All @@ -17,6 +25,14 @@ const queries = {
ensureAuthenticated(ctx)
return FormService.getFormById(id)
},
getFormResponses: async (
_: any,
{ input }: { input: GetFormResponsesByFormIdInput },
ctx: ServerContext
) => {
ensureAuthenticated(ctx)
return FormService.getFormResponsesByFormId(input.formId, ctx)
},
}

const mutations = {
Expand Down Expand Up @@ -57,6 +73,44 @@ const mutations = {
await FormService.updateFormById(data.id, data)
return true
},

submitFormResponse: async (
_: any,
{ data }: { data: SubmitFormResponseData },
ctx: ServerContext
) => {
const { formId } = data

//Check if form exist with given id
const form = await prismaClient.form.findUnique({
where: { id: formId },
select: { id: true, autoAddTags: true, autoApproveTestimonials: true },
})

if (!form || !form.id) {
throw new BadRequestError(`Form with id ${formId} does not exists`)
}

const formResponse = await FormService.createFormResponse({
data: {
//required field
name: data.name,
form: { connect: { id: formId } },
testimonial: data.testimonial,

email: data.email,
imageURL: data.imageURL,
rating: data.rating,
jobTitle: data.jobTitle,
websiteUrl: data.websiteUrl,
company: data.company,

approved: Boolean(form.autoApproveTestimonials),
tags: form.autoAddTags,
},
})
return formResponse.id
},
}

export const resolvers = { queries, mutations }
38 changes: 38 additions & 0 deletions functions/graphql/form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,42 @@ export const types = `#graphql
updatedAt: Date
}
type FormResponse {
id: ID!
formId: String!
name: String!
email: String
imageURL: String
rating: Int
testimonial: String!
jobTitle: String
websiteUrl: String
company: String
tags: [String]
approved: Boolean
reatedAt: Date
updatedAt: Date
}
input SubmitFormResponseData {
formId: String!
name: String!
email: String
imageURL: String
rating: Int
testimonial: String!
jobTitle: String
websiteUrl: String
company: String
}
input GetFormResponsesByFormIdInput {
formId: ID!
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "form_responses" ADD COLUMN "approved" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "tags" TEXT[] DEFAULT ARRAY[]::TEXT[];
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "form_responses" (
"id" TEXT NOT NULL,
"form_id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"email" TEXT,
"image_url" TEXT,
"rating" INTEGER,
"testimonial" TEXT NOT NULL,
"job_title" TEXT,
"website_url" TEXT,
"company" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,

CONSTRAINT "form_responses_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "form_responses" ADD CONSTRAINT "form_responses_form_id_fkey" FOREIGN KEY ("form_id") REFERENCES "forms"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
31 changes: 29 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,36 @@ model Form {
autoApproveTestimonials Boolean @default(false) @map("auto_approve_testimonials")
autoAddTags String[] @default([]) @map("auto_add_tags")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
responses FormResponse[]
@@unique([slug, projectId])
@@map("forms")
}

model FormResponse {
id String @id @default(uuid())
// Relations
form Form @relation(fields: [formId], references: [id])
formId String @map("form_id")
// Form filler details
name String
email String?
imageURL String? @map("image_url")
rating Int?
testimonial String @map("testimonial")
jobTitle String? @map("job_title")
websiteUrl String? @map("website_url")
company String?
tags String[] @default([]) @map("tags")
approved Boolean @default(false)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("form_responses")
}
23 changes: 23 additions & 0 deletions services/form.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import prismaClient from '../db'
import AccessDeniedError from '../errors/AccessDeniedError'
import { UpdateFormData } from '../functions/graphql/form/interfaces'
import { ServerContext } from '../functions/graphql/interfaces'

class FormService {
public static createForm = prismaClient.form.create
Expand Down Expand Up @@ -27,6 +29,27 @@ class FormService {
where: { id },
})
}

public static createFormResponse = prismaClient.formResponse.create

public static getFormResponsesByFormId(formId: string, ctx: ServerContext) {
if (!ctx.user?.id) throw new AccessDeniedError()

return prismaClient.formResponse.findMany({
where: {
AND: [
{
form: {
id: formId,
project: {
ProjectAccessMapping: { every: { user: { id: ctx.user.id } } }, // TODO: Need to test more deeply
},
},
},
],
},
})
}
}

export default FormService

0 comments on commit bacb6ce

Please sign in to comment.