Skip to content

Commit

Permalink
Merge pull request #59 from piyushgarg-dev/feature/public-form-submis…
Browse files Browse the repository at this point in the history
…sion

Feature/public form submission
  • Loading branch information
piyushgarg-dev authored Oct 19, 2023
2 parents e85d111 + 3582cf8 commit 7cbdf65
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 4 deletions.
11 changes: 11 additions & 0 deletions functions/graphql/form/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,14 @@ export interface SubmitFormResponseData {
export interface GetFormResponsesByFormIdInput {
formId: string
}

export interface GetFormResponsesByProjectId {
projectId: string
itemsPerPage?: number
cursor?: string
}

export interface GetPublicFormDataInput {
domain: string
formSlug: string
}
4 changes: 3 additions & 1 deletion functions/graphql/form/queries.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export const queries = `#graphql
getForms(input: GetFormsInput!): [Form]
getFormById(id: ID!): Form
getFormResponses(input: GetFormResponsesByFormIdInput!): [FormResponse]
getFormResponsesByFormId(input: GetFormResponsesByFormIdInput!): [FormResponse]
getFormResponsesByProjectId(input: GetFormResponsesByProjectIdInput!): [FormResponse]
getPublicFormData(input: GetPublicFormDataInput!): FormPublicData
`
25 changes: 24 additions & 1 deletion functions/graphql/form/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { ServerContext } from '../interfaces'
import {
CreateFormData,
GetFormResponsesByFormIdInput,
GetFormResponsesByProjectId,
GetFormsInput,
GetPublicFormDataInput,
SubmitFormResponseData,
UpdateFormData,
} from './interfaces'
Expand All @@ -25,14 +27,35 @@ const queries = {
ensureAuthenticated(ctx)
return FormService.getFormById(id)
},
getFormResponses: async (
getFormResponsesByFormId: async (
_: any,
{ input }: { input: GetFormResponsesByFormIdInput },
ctx: ServerContext
) => {
ensureAuthenticated(ctx)
return FormService.getFormResponsesByFormId(input.formId, ctx)
},
getFormResponsesByProjectId: async (
_: any,
{ input }: { input: GetFormResponsesByProjectId },
ctx: ServerContext
) => {
ensureAuthenticated(ctx)
const { projectId, itemsPerPage = 10, cursor } = input
return FormService.getFormResponsesByProjectId(projectId, ctx, {
cursor,
itemsPerPage,
})
},
getPublicFormData: async (
_: any,
{ input }: { input: GetPublicFormDataInput }
) => {
return FormService.getPublicFormData({
domain: input.domain,
slug: input.formSlug,
})
},
}

const mutations = {
Expand Down
47 changes: 45 additions & 2 deletions functions/graphql/form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ export const types = `#graphql
projectId: String!
}
input GetPublicFormDataInput {
domain: String!
formSlug: String!
}
input UpdateFormInput {
id: ID!
Expand Down Expand Up @@ -45,6 +50,38 @@ export const types = `#graphql
input GetFormsInput {
projectId: ID!
}
type FormPublicData {
id: ID!
primaryColor: String!
backgroundColor: String!
introTitle: String!
introMessage: String
promptTitle: String!
promptDescription: String
thankyouTitle: String!
thankyouMessage: String
name: String!
enableCTA: Boolean!
ctaTitle: String
ctaURL: String
collectVideoTestimonials: Boolean!
collectTextTestimonials: Boolean!
collectRatings: Boolean!
collectImages: Boolean!
collectEmail: Boolean!
collectJobTitle: Boolean!
collectUserImage: Boolean!
collectWebsiteURL: Boolean!
collectCompany: Boolean!
lang: String
}
type Form {
id: ID!
Expand Down Expand Up @@ -75,7 +112,7 @@ export const types = `#graphql
primaryColor: String!
backgroundColor: String!
lang: String!
lang: String
collectVideoTestimonials: Boolean!
collectTextTestimonials: Boolean!
Expand Down Expand Up @@ -112,7 +149,7 @@ export const types = `#graphql
tags: [String]
approved: Boolean
reatedAt: Date
createdAt: Date
updatedAt: Date
}
Expand All @@ -132,4 +169,10 @@ export const types = `#graphql
input GetFormResponsesByFormIdInput {
formId: ID!
}
input GetFormResponsesByProjectIdInput {
projectId: ID!
itemsPerPage: Int
cursor: String
}
`
75 changes: 75 additions & 0 deletions services/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import AccessDeniedError from '../errors/AccessDeniedError'
import { UpdateFormData } from '../functions/graphql/form/interfaces'
import { ServerContext } from '../functions/graphql/interfaces'

interface GetFormResponsesByProjectIdOptions {
itemsPerPage?: number
cursor?: string
}

class FormService {
public static createForm = prismaClient.form.create

Expand All @@ -14,6 +19,49 @@ class FormService {
return prismaClient.form.findUnique({ where: { id } })
}

public static getPublicFormData({
domain,
slug,
}: {
domain: string
slug: string
}) {
return prismaClient.form.findFirst({
where: {
AND: [
{
project: { OR: [{ subdomain: domain }, { customDomain: domain }] },
},
{ slug },
],
},
select: {
backgroundColor: true,
collectCompany: true,
collectEmail: true,
collectImages: true,
collectJobTitle: true,
collectRatings: true,
collectUserImage: true,
collectTextTestimonials: true,
collectVideoTestimonials: true,
collectWebsiteURL: true,
ctaTitle: true,
enableCTA: true,
ctaURL: true,
introMessage: true,
introTitle: true,
name: true,
primaryColor: true,
promptDescription: true,
promptTitle: true,
thankyouMessage: true,
thankyouTitle: true,
id: true,
},
})
}

public static updateFormById(id: string, formData: UpdateFormData) {
return prismaClient.form.update({
data: {
Expand All @@ -32,6 +80,33 @@ class FormService {

public static createFormResponse = prismaClient.formResponse.create

public static getFormResponsesByProjectId(
projectId: string,
ctx: ServerContext,
options?: GetFormResponsesByProjectIdOptions
) {
if (!ctx.user?.id) throw new AccessDeniedError()

return prismaClient.formResponse.findMany({
where: {
form: {
project: {
id: projectId,
ProjectAccessMapping: { every: { user: { id: ctx.user.id } } }, // TODO: Need to test more deeply
},
},
},
cursor: options?.cursor
? {
id: options?.cursor,
}
: undefined,
take: options?.itemsPerPage ?? 10,
skip: options?.cursor ? 1 : 0, // Skip the cursor
orderBy: { createdAt: 'desc' },
})
}

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

Expand Down

0 comments on commit 7cbdf65

Please sign in to comment.