diff --git a/.gitignore b/.gitignore
index 6b26568..e00931e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,4 +22,5 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
-*.local*
\ No newline at end of file
+*.local*
+*.gen*
\ No newline at end of file
diff --git a/codegen.yml b/codegen.yml
new file mode 100644
index 0000000..2d64352
--- /dev/null
+++ b/codegen.yml
@@ -0,0 +1,13 @@
+overwrite: true
+schema: 'src/apollo/typeDefs.gql'
+documents: null
+generates:
+ src/apollo/typeDefs.gen.ts:
+ config:
+ useIndexSignature: true
+ wrapFieldDefinitions: true
+ enumsAsTypes: true
+ declarationKind: 'interface'
+
+ plugins:
+ - 'typescript'
diff --git a/package.json b/package.json
index e645900..a45f10e 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,8 @@
},
"scripts": {
"start": "react-scripts start",
- "build": "react-scripts build"
+ "build": "react-scripts build",
+ "codegen": "graphql-codegen --config codegen.yml"
},
"eslintConfig": {
"extends": "react-app"
@@ -34,5 +35,9 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "@graphql-codegen/cli": "^1.17.10",
+ "@graphql-codegen/typescript": "^1.17.10"
}
}
diff --git a/src/apollo/defs.ts b/src/apollo/defs.ts
index 0d05073..0639a2d 100644
--- a/src/apollo/defs.ts
+++ b/src/apollo/defs.ts
@@ -11,7 +11,27 @@ const LOGIN = gql`
const FORM = gql`
query Form($id: Int!) {
form(id: $id) {
+ author {
+ email
+ id
+ name
+ }
+ dateCreated
id
+ questions {
+ number
+ ... on ChoisesQuestion {
+ title
+ type
+ variants {
+ text
+ }
+ }
+ ... on InputQuestion {
+ number
+ title
+ }
+ }
title
}
}
@@ -27,4 +47,12 @@ const USER = gql`
}
`
-export { LOGIN, FORM, USER }
+const FORMSUBMIT = gql`
+ mutation FormSubmit($formId: Int!, $answers: String!) {
+ formSubmit(formId: $formId, answers: $answers) {
+ success
+ }
+ }
+`
+
+export { LOGIN, FORM, USER, FORMSUBMIT }
diff --git a/src/apollo/typeDefs.gql b/src/apollo/typeDefs.gql
new file mode 100644
index 0000000..dbcb68d
--- /dev/null
+++ b/src/apollo/typeDefs.gql
@@ -0,0 +1,84 @@
+type Query {
+ form(id: Int!): Form
+ forms: [Form!]!
+ user(id: Int): User
+}
+
+type Mutation {
+ createForm(title: String!, questions: String!): serverAnswer
+ formSubmit(formId: Int!, answers: String!): serverAnswer
+ login(email: String!): serverAnswer
+ register(name: String!, email: String!): serverAnswer
+}
+
+type Form {
+ author: User
+ dateCreated: String!
+ id: Int!
+ questions: [Question!]!
+ submissions: [FormSubmission!]
+ title: String!
+}
+
+interface Question {
+ number: Int!
+ title: String!
+}
+
+type ChoisesQuestion implements Question {
+ number: Int!
+ title: String!
+ type: ChoiseType!
+ variants: [Variant!]!
+}
+
+type Variant {
+ text: String!
+}
+
+type InputQuestion implements Question {
+ number: Int!
+ title: String!
+}
+
+type FormSubmission {
+ answers: [Answer!]!
+ date: String!
+ id: Int!
+}
+
+interface Answer {
+ type: AnswerType!
+}
+
+type InputAnswer implements Answer {
+ type: AnswerType!
+ userInput: String
+}
+
+type ChoiseAnswer implements Answer {
+ type: AnswerType!
+ userChoise: Int!
+}
+
+enum ChoiseType {
+ CHECK
+ CHOOSE
+ SELECT
+}
+
+enum AnswerType {
+ CHOISE
+ INPUT
+}
+
+type User {
+ email: String!
+ forms: [Form!]
+ id: Int!
+ name: String!
+}
+
+type serverAnswer {
+ success: Boolean!
+}
diff --git a/src/components/App.tsx b/src/components/App.tsx
index a39064a..6d9c1bf 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -6,36 +6,10 @@ import client from '../apollo'
import Context from '../context'
import { useUser } from '../hooks'
import Authorize from './Authorize'
+import DoForm from './DoForm'
import Login from './Login'
import UserPage from './UserPage'
-// const TestComponent: React.FC = () => {
-// const { loading, error, data } = useQuery(FORM, {
-// variables: {
-// id: 1
-// }
-// })
-
-// const { user } = useContext(Context)
-
-// const [doLogin] = useMutation(LOGIN)
-
-// if (loading) return
Loading...
-// if (error) return Error :(
-
-// return (
-//
-//
-// {user.id}
-// {data.form.id}
-//
-// )
-// }
-
const App: React.FC = () => {
const userContext = useUser()
@@ -48,6 +22,7 @@ const App: React.FC = () => {
+
diff --git a/src/components/DoForm/Lists.tsx b/src/components/DoForm/Lists.tsx
new file mode 100644
index 0000000..b92697e
--- /dev/null
+++ b/src/components/DoForm/Lists.tsx
@@ -0,0 +1,36 @@
+import React from 'react'
+
+interface IProps {
+ variants: { text: string }[]
+ name: string
+ type: 'CHECK' | 'CHOOSE'
+ onChange: (num: number) => void
+}
+
+const Lists: React.FC = ({ variants, name, type, onChange }) => {
+ const inputType =
+ (type === 'CHECK' && 'check') || (type === 'CHOOSE' && 'radio') || undefined
+
+ return (
+
+ {variants.map((el, index) => (
+
+ ))}
+
+ )
+}
+
+export default Lists
diff --git a/src/components/DoForm/hooks.ts b/src/components/DoForm/hooks.ts
new file mode 100644
index 0000000..00f5524
--- /dev/null
+++ b/src/components/DoForm/hooks.ts
@@ -0,0 +1,28 @@
+import { useState } from 'react'
+import { ChoiseAnswer, InputAnswer } from '../../apollo/typeDefs.gen'
+
+export const useForm = (initialValue?: (InputAnswer | ChoiseAnswer)[]) => {
+ console.log(initialValue, 'Inside hook')
+
+ const [answers, setAnswer] = useState<(InputAnswer | ChoiseAnswer)[]>(
+ initialValue || []
+ )
+
+ const answerChange = (num: number) => {
+ return (value: number | string) => {
+ setAnswer((prev) => {
+ return prev.map((el, index) => {
+ if (index === num) {
+ if (el.__typename === 'ChoiseAnswer' && typeof value === 'number')
+ return { ...el, userChoise: value }
+ if (el.__typename === 'InputAnswer' && typeof value === 'string')
+ return { ...el, userInput: value }
+ }
+ return el
+ })
+ })
+ }
+ }
+
+ return [answers, answerChange]
+}
diff --git a/src/components/DoForm/index.tsx b/src/components/DoForm/index.tsx
new file mode 100644
index 0000000..fe15db2
--- /dev/null
+++ b/src/components/DoForm/index.tsx
@@ -0,0 +1,171 @@
+import { useMutation, useQuery } from '@apollo/client'
+import React, { FormEvent, useEffect, useState } from 'react'
+import { Redirect, useParams } from 'react-router-dom'
+import { FORM, FORMSUBMIT } from '../../apollo'
+import {
+ ChoiseAnswer,
+ ChoisesQuestion,
+ Form,
+ InputAnswer,
+ InputQuestion,
+ QueryFormArgs,
+} from '../../apollo/typeDefs.gen'
+import Lists from './Lists'
+
+interface IFormQuery {
+ form: Form
+}
+
+const DoForm: React.FC = () => {
+ const { id: idString } = useParams<{ id: string }>()
+
+ const id = parseInt(idString)
+
+ const { data, error, loading } = useQuery(FORM, {
+ variables: { id },
+ skip: isNaN(id),
+ })
+
+ const [
+ doFormSubmit,
+ { error: submitError, data: submitData, loading: submitLoading },
+ ] = useMutation(FORMSUBMIT)
+
+ const [answers, setAnswer] = useState<(InputAnswer | ChoiseAnswer)[]>([])
+
+ const getInitialState = (data: IFormQuery) => {
+ if (data && data.form) {
+ return data.form.questions.flatMap(
+ (el: InputQuestion | ChoisesQuestion) => {
+ if (el.__typename === 'ChoisesQuestion')
+ return [
+ { __typename: 'ChoiseAnswer', type: 'CHOISE', userChoise: -1 },
+ ]
+ if (el.__typename === 'InputQuestion')
+ return [{ __typename: 'InputAnswer', type: 'INPUT', userInput: '' }]
+ return []
+ }
+ )
+ }
+ return []
+ }
+
+ useEffect(() => {
+ if (data) {
+ const initialState = getInitialState(data)
+ setAnswer(initialState)
+ }
+ }, [data])
+
+ useEffect(() => console.log(answers), [answers])
+
+ if (isNaN(id)) return
+
+ if (loading) return Loading...
+ if (error) return {error.message}
+
+ const { form } = data!
+
+ const handleSubmit = (e: FormEvent) => {
+ e.preventDefault()
+ console.log('Submited form:', answers)
+
+ answers.forEach((el) => {
+ delete el.__typename
+ })
+
+ const submitAnswers = JSON.stringify(answers)
+
+ console.log('Filtered answers: ', submitAnswers)
+
+ doFormSubmit({
+ variables: {
+ formId: id,
+ answers: submitAnswers,
+ },
+ })
+ }
+
+ const answerChange = (num: number) => {
+ return (value: number | string) => {
+ setAnswer((prev) => {
+ return prev.map((el, index) => {
+ if (index === num) {
+ if (el.__typename === 'ChoiseAnswer' && typeof value === 'number')
+ return { ...el, userChoise: value }
+ if (el.__typename === 'InputAnswer' && typeof value === 'string')
+ return { ...el, userInput: value }
+ }
+ return el
+ })
+ })
+ }
+ }
+
+ return (
+
+
{form.title}
+
{form.dateCreated}
+
{form.author?.name || 'No author'}
+
+
+ {submitError &&
{submitError.message}
}
+ {submitData && submitData.formSubmit && submitData.formSubmit.success && (
+
Successfully uploaded
+ )}
+
+ )
+}
+
+export default DoForm
diff --git a/src/components/UserPage/index.tsx b/src/components/UserPage/index.tsx
index 2a62f60..4bd5c57 100644
--- a/src/components/UserPage/index.tsx
+++ b/src/components/UserPage/index.tsx
@@ -8,15 +8,15 @@ const UserPage: React.FC = () => {
if (error) return {error.message}
- console.log(Object.entries(data.user))
+ const { name, email, id } = data.user
- const user = Object.entries(data.user).map((el, index) => (
-
- {el[0]}: {el[1]}
-
- ))
-
- return
+ return (
+
+
Username: {name}
+
Email: {email}
+
User ID: {id}
+
+ )
}
export default UserPage