Bladeren bron

working on the user module.

Tomi Cvetic 5 jaren geleden
bovenliggende
commit
14e7d7bb98

+ 3 - 9
backend/schema.graphql

@@ -13,16 +13,9 @@ type Query {
   training(
     where: TrainingWhereUniqueInput!
   ): Training
-  trainings(
-    where: TrainingWhereInput
-    orderBy: TrainingOrderByInput
-    skip: Int
-    after: String
-    before: String
-    first: Int
-    last: Int
-  ): [Training]!
+  trainings(where: TrainingWhereInput, orderBy: TrainingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Training]!
   trainingTypes(where: TrainingTypeWhereInput, orderBy: TrainingTypeOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [TrainingType]!
+  blocks(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block]!
   me: User!
 }
 
@@ -30,6 +23,7 @@ type Mutation {
   createUser(name: String!, email: String!, password: String!): User!
   createTraining(title: String!): Training!
   createTrainingType(name: String!, description: String!): TrainingType!
+  createBlock(sequence: Int!, title: String!, duration: Int!, variation: String, format: ID, tracks: [ID]!, exercises: [ID]!, description: String!): Block!
   login(email: String!, password: String!): User!
   signup(name: String!, email: String!, password: String!): User!
   logout: String!

+ 13 - 4
backend/src/resolvers.js

@@ -18,6 +18,10 @@ const Query = {
     if (!context.request.userId) throw LoginError
     return context.db.query.trainingTypes()
   },
+  blocks: async (parent, args, context, info) => {
+    if (!context.request.userId) throw LoginError
+    return context.db.query.trainingTypes()
+  },
   me: (parent, args, context, info) => {
     if (!context.request.userId) throw LoginError
     return context.db.query.user({ where: { id: context.request.userId } }, info)
@@ -83,20 +87,25 @@ const Mutation = {
     return 'Logged out.'
   },
   createTraining: async (parent, args, context, info) => {
-    const { userId } = context.request
-    if (!userId) throw LoginError
+    if (!context.request.userId) throw LoginError
     const training = await context.db.mutation.createTraining(
       { data: args }, info
     )
     return training
   },
   createTrainingType: async (parent, args, context, info) => {
-    const { userId } = context.request
-    if (!userId) throw LoginError
+    if (!context.request.userId) throw LoginError
     const trainingType = await context.db.mutation.createTrainingType(
       { data: args }, info
     )
     return trainingType
+  },
+  createBlock: async (parent, args, context, info) => {
+    if (!context.request.userId) throw LoginError
+    const block = await context.db.mutation.createBlock(
+      { data: args }, info
+    )
+    return block
   }
 }
 

+ 2 - 1
frontend/.babelrc

@@ -1,5 +1,6 @@
 {
   "presets": [
-    "next/babel"
+    "next/babel",
+    "@zeit/next-typescript/babel"
   ]
 }

+ 4 - 4
frontend/components/content.js

@@ -3,7 +3,7 @@ import { adopt } from 'react-adopt'
 import { Formik, Form } from 'formik'
 
 import { TextInput } from '../lib/forms'
-import { CREATE_TRAINING_TYPE, TRAINING_TYPES } from '../lib/graphql'
+import { BLOCKS, CREATE_BLOCK } from '../lib/graphql'
 import Overlay from './overlay'
 
 const ContentInput = props => {
@@ -15,7 +15,7 @@ const ContentInput = props => {
   }
 
   return (
-    <Query query={TRAINING_TYPES}>
+    <Query query={BLOCKS}>
       {({ data, error, loading }) => (
         <>
           <label>Training type</label>
@@ -53,8 +53,8 @@ const ContentInput = props => {
 const ContentAdoption = adopt({
   mutation: ({ render }) => (
     <Mutation
-      mutation={CREATE_TRAINING_TYPE}
-      refetchQueries={[{ query: TRAINING_TYPES }]}
+      mutation={CREATE_BLOCK}
+      refetchQueries={[{ query: BLOCKS }]}
     >
       {(createTrainingType, { data, error, loading }) => render({ createTrainingType, data, error, loading })}
     </Mutation>

+ 14 - 0
frontend/components/form/TextInput.tsx

@@ -0,0 +1,14 @@
+import { InputProps } from './forms'
+
+interface TextInputProps extends InputProps {
+  label: string
+}
+
+const TextInput = ({ label, ...inputProps }: TextInputProps) => (
+  <>
+    <label htmlFor={inputProps.name}>{label}</label>
+    <input {...inputProps} />
+  </>
+)
+
+export default TextInput

+ 0 - 0
frontend/lib/__tests__/forms.test.tsx → frontend/components/form/__tests__/forms.test.tsx


+ 0 - 5
frontend/components/form/form.js

@@ -1,5 +0,0 @@
-const Form = (props, ref) => (
-    <form onReset={formikProps.handleReset} onSubmit={formikProps.handleSubmit} {...props} />
-)
-
-export default Form

+ 35 - 41
frontend/lib/forms.ts → frontend/components/form/forms.ts

@@ -1,11 +1,21 @@
-import { useEffect, useState } from 'react'
+import { useEffect, useState, FormEvent, ChangeEvent, SyntheticEvent } from 'react'
 
-type FormHandler = {
-  inputProps: (name: string) => {},
-  submitProps: () => {},
-  handleSubmit: (event: Event) => void,
-  handleChange: (event: Event) => void,
-  handleBlur: (event: Event) => void,
+import TextInput from './TextInput'
+
+export interface InputProps {
+  id: string,
+  name: string,
+  value: any,
+  onChange: (event: SyntheticEvent) => void,
+  onBlur: (event: SyntheticEvent) => void,
+  placeholder: string,
+  label: string
+}
+
+interface FormHandler {
+  inputProps: (name: string) => InputProps,
+  handleChange: (event: SyntheticEvent) => void,
+  handleBlur: (event: SyntheticEvent) => void,
   values: Dict,
   errors: Dict,
   isSubmitting: boolean
@@ -13,22 +23,23 @@ type FormHandler = {
 
 /**
  * Provides hooks for forms.
- * 
+ *
  * @remarks
  * You can use it like this
  * ```ts
- * const {inputParams, submitParams} = useFormHandler()
+ * const {inputParams, formParams} = useFormHandler()
  * ```
- * 
- * @param initialValues - Initial values of inputs 
+ *
+ * @param initialValues - Initial values of inputs
  * @param validate - validation function for the form
  * @returns hooks to handle the form
  */
 function useFormHandler(
   initialValues: Dict,
-  validate: (values: Dict) => {}
+  validate?: (values: Dict) => {}
 ): FormHandler {
 
+  console.log('useFormHandler called.', initialValues)
   const [values, setValues] = useState(initialValues)
   const [errors, setErrors] = useState({})
   const [isSubmitting, setIsSubmitting] = useState(false)
@@ -45,20 +56,7 @@ function useFormHandler(
     }
   }, [errors])
 
-  function handleSubmit(
-    event: Event,
-    callback?: (event: Event, data?: {}) => void, data?: {}
-  ): void {
-    event.preventDefault()
-    const validationErrors = validate(values)
-    setErrors(validationErrors)
-    setIsSubmitting(true)
-    if (callback !== undefined) {
-      callback(event, data)
-    }
-  }
-
-  function handleChange(event: Event): void {
+  function handleChange(event: SyntheticEvent): void {
     setValues({
       ...values,
       [(event.target as HTMLInputElement).name]:
@@ -66,34 +64,30 @@ function useFormHandler(
     })
   }
 
-  function handleBlur(event: Event): void {
-    const validationErrors = validate(values)
-    setErrors(validationErrors)
+  function handleBlur(event: SyntheticEvent): void {
+    if (validate) {
+      const validationErrors = validate(values)
+      setErrors(validationErrors)
+    }
   }
 
-  function inputProps(name: string): {} {
+  function inputProps(name: string, label?: string): InputProps {
     if (!values.hasOwnProperty(name)) {
       throw Error(`${name} is not an existing field.`)
     }
     return {
-      name,
       id: name,
+      name,
+      value: values[name],
       onChange: handleChange,
       onBlur: handleBlur,
-      value: values[name]
-    }
-  }
-
-  function submitProps(): {} {
-    return {
-      onSubmit: handleSubmit
+      placeholder: label || name,
+      label: label || name
     }
   }
 
   return {
     inputProps,
-    submitProps,
-    handleSubmit,
     handleChange,
     handleBlur,
     values,
@@ -102,4 +96,4 @@ function useFormHandler(
   }
 }
 
-export default useFormHandler
+export { useFormHandler, TextInput }

+ 38 - 0
frontend/components/user/LoginForm.tsx

@@ -0,0 +1,38 @@
+import { useMutation } from '@apollo/react-hooks'
+
+import { USER_LOGIN, CURRENT_USER } from './graphql'
+import { useFormHandler, TextInput } from '../form/forms'
+import { FormEvent } from 'react'
+
+
+const initialValues = {
+  email: 'tomislav.cvetic@u-blox.com',
+  password: '1234'
+}
+
+const LoginForm = () => {
+
+  const [login, { loading, error }] = useMutation(USER_LOGIN)
+  const { inputProps, values } = useFormHandler(initialValues)
+
+  return (
+    <form onSubmit={async (event: FormEvent) => {
+      event.preventDefault()
+      try {
+        const data = await login({
+          variables: values,
+          refetchQueries: [{ query: CURRENT_USER }]
+        })
+        console.log(data)
+      } catch (error) {
+        console.log(error)
+      }
+    }}>
+      <TextInput label='Email' {...inputProps('email')} />
+      <TextInput label='Password' {...inputProps('password')} />
+      <button type='submit' disabled={loading}>Login!</button>
+    </form>
+  )
+}
+
+export default LoginForm

+ 16 - 0
frontend/components/user/LogoutButton.tsx

@@ -0,0 +1,16 @@
+import { useMutation } from 'react-apollo'
+import { USER_LOGOUT, CURRENT_USER } from './graphql'
+
+interface LogoutButtonProps {
+  title?: string
+}
+
+const LogoutButton = (props: LogoutButtonProps) => {
+  const [logout, { loading, error }] = useMutation(USER_LOGOUT)
+
+  return (
+    <button disabled={loading} onClick={() => logout({ refetchQueries: [{ query: CURRENT_USER }] })}>{props.title || 'Log out'}</button>
+  )
+}
+
+export default LogoutButton

+ 35 - 0
frontend/components/user/RequestPassword.tsx

@@ -0,0 +1,35 @@
+import { useMutation } from '@apollo/react-hooks'
+
+import { USER_REQUEST_PASSWORD } from './graphql'
+import { useFormHandler, TextInput } from '../form/forms'
+import { FormEvent } from 'react'
+
+
+const initialValues = {
+  email: '',
+  password: ''
+}
+
+const RequestPassword = () => {
+
+  const [login, { loading, error }] = useMutation(USER_REQUEST_PASSWORD)
+  const { inputProps } = useFormHandler(initialValues)
+
+  return (
+    <form onSubmit={async (event: FormEvent) => {
+      event.preventDefault()
+      try {
+        const data = await login()
+        console.log(data)
+      } catch (error) {
+        console.log(error)
+      }
+    }}>
+      <TextInput label='Email' {...inputProps('email')} />
+      <TextInput label='Password' {...inputProps('password')} />
+      <button type='submit' disabled={loading}>Login!</button>
+    </form>
+  )
+}
+
+export default RequestPassword

+ 35 - 0
frontend/components/user/ResetPassword.tsx

@@ -0,0 +1,35 @@
+import { useMutation } from '@apollo/react-hooks'
+
+import { USER_RESET_PASSWORD } from './graphql'
+import { useFormHandler, TextInput } from '../form/forms'
+import { FormEvent } from 'react'
+
+
+const initialValues = {
+  email: '',
+  password: ''
+}
+
+const ResetPassword = () => {
+
+  const [login, { loading, error }] = useMutation(USER_RESET_PASSWORD)
+  const { inputProps } = useFormHandler(initialValues)
+
+  return (
+    <form onSubmit={async (event: FormEvent) => {
+      event.preventDefault()
+      try {
+        const data = await login()
+        console.log(data)
+      } catch (error) {
+        console.log(error)
+      }
+    }}>
+      <TextInput label='Email' {...inputProps('email')} />
+      <TextInput label='Password' {...inputProps('password')} />
+      <button type='submit' disabled={loading}>Login!</button>
+    </form>
+  )
+}
+
+export default ResetPassword

+ 44 - 69
frontend/components/user/SignupForm.tsx

@@ -1,10 +1,10 @@
-import { Formik, Form } from 'formik'
-import { Mutation } from 'react-apollo'
-import { adopt } from 'react-adopt'
+import { Mutation, useMutation } from 'react-apollo'
+import * as Yup from 'yup'
+
+import { useFormHandler, TextInput } from '../form/forms'
+import { USER_SIGNUP } from './graphql'
+import { SyntheticEvent } from 'react'
 
-import { useFormHandling } from '../../lib/forms'
-import { USER_SIGNUP, CURRENT_USER } from './graphql'
-import { signupValidation } from './validation'
 
 const initialValues = {
   name: 'Tomi',
@@ -13,67 +13,43 @@ const initialValues = {
   passwordAgain: '1234'
 }
 
-async function onSubmit(values, mutation) {
-  try {
-    const user = await mutation({ variables: values })
-    console.log(user)
-  } catch (error) {
-    console.log(error)
-  }
-}
-
-const SignupAdoption = adopt({
-  mutation: ({ render }) => (
-    <Mutation
-      mutation={USER_SIGNUP}
-      refetchQueries={[{ query: CURRENT_USER }]}
-    >{(signup, { data, error, loading }) => render({ signup, data, error, loading, render })}
-    </Mutation>
-  ),
-  form: ({ mutation, render }) => (
-    <Formik
-      initialValues={initialValues}
-      validationSchema={validationSchema}
-      onSubmit={values => onSubmit(values, mutation)}
-    >
-      {render}
-    </Formik>
-  )
+const validationScheme = Yup.object({
+  name: Yup.string()
+    .required('Required')
+    .max(40, 'Must be 40 characters or less'),
+  email: Yup.string()
+    .email('Invalid email address')
+    .required('Required'),
+  password: Yup.string()
+    .min(4, 'Must have at least 8 characters'),
+  passwordAgain: Yup.string()
+    .oneOf([Yup.ref('password'), null], 'Passwords must match')
 })
 
-const SignupForm = props => (
-  <SignupAdoption>
-    {({ form, mutation: { signup, data, error, loading } }) => (
-      <Form>
-        <TextInput
-          label='Name'
-          name='name'
-          type='text'
-          placeholder='Name'
-        />
-        <TextInput
-          label='Email'
-          name='email'
-          type='email'
-          placeholder='Email Address'
-        />
-        <TextInput
-          label='Password'
-          name='password'
-          type='password'
-          placeholder='1234'
-        />
-        <TextInput
-          label='Repeat password'
-          name='passwordAgain'
-          type='password'
-          placeholder='1234'
-        />
-        <button type='reset' disabled={loading}>Sign Up!</button>
-        <button type='submit' disabled={loading}>Sign Up!</button>
 
-        <style jsx>
-          {`
+const SignupForm = () => {
+
+  const { inputProps, values } = useFormHandler(initialValues, validationScheme.isValid)
+  const [userSignup, { loading, error }] = useMutation(USER_SIGNUP)
+
+  return (
+    <form onSubmit={async (event: SyntheticEvent) => {
+      event.preventDefault()
+      try {
+        const data = await userSignup({ variables: values })
+      } catch (error) {
+        console.log(error)
+      }
+    }}>
+      <TextInput label='Name' {...inputProps('name')} />
+      <TextInput label='Email' {...inputProps('email')} />
+      <TextInput label='Password' {...inputProps('password')} />
+      <TextInput label='Repeat password' {...inputProps('passwordAgain')} />
+      <button type='reset' disabled={loading}>Reset</button>
+      <button type='submit' disabled={loading}>Sign Up!</button>
+
+      <style jsx>
+        {`
             select, input {
               color: rgba(0,0,127,1);
             }
@@ -95,10 +71,9 @@ const SignupForm = props => (
               margin-top: 1rem;
             }
           `}
-        </style>
-      </Form>
-    )}
-  </SignupAdoption>
-)
+      </style>
+    </form>
+  )
+}
 
 export default SignupForm

+ 25 - 0
frontend/components/user/UserDetails.tsx

@@ -0,0 +1,25 @@
+import { useQuery } from "react-apollo"
+import { CURRENT_USER } from "./graphql"
+
+const UserDetails = () => {
+
+  const { data, error, loading } = useQuery(CURRENT_USER)
+
+  if (error) {
+    console.log(error)
+    return (
+      <p>Error</p>
+    )
+  } else if (loading) {
+    return (
+      <p>Loading...</p>
+    )
+  } else {
+    console.log(data)
+    return (
+      <p>Data</p>
+    )
+  }
+}
+
+export default UserDetails

+ 33 - 0
frontend/components/user/UserEditForm.tsx

@@ -0,0 +1,33 @@
+import { useQuery, useMutation } from "react-apollo"
+import { useFormHandler, TextInput } from "../form/forms"
+import { CURRENT_USER, USER_EDIT } from "./graphql"
+import { SyntheticEvent } from "react"
+
+const initialData = {
+  name: '',
+  email: '',
+  password: '',
+  passwordAgain: ''
+}
+
+
+const UserEditForm = () => {
+
+  const currentUser = useQuery(CURRENT_USER)
+  const [updateUser, userEdit] = useMutation(USER_EDIT)
+  const { inputProps } = useFormHandler(currentUser.data ? { ...initialData, ...currentUser.data.me } : initialData)
+
+  return (
+    <form onSubmit={(event: SyntheticEvent) => {
+      event.preventDefault()
+    }}>
+      <TextInput label='Name' {...inputProps('name')} />
+      <TextInput label='Email' {...inputProps('email')} />
+      <TextInput label='Password' {...inputProps('password')} />
+      <TextInput label='Repeat password' {...inputProps('passwordAgain')} />
+      <button type='submit' disabled={userEdit.loading}>Update</button>
+    </form>
+  )
+}
+
+export default UserEditForm

+ 27 - 1
frontend/components/user/graphql.js

@@ -36,4 +36,30 @@ const CURRENT_USER = gql`
   }
 `
 
-export { USER_SIGNUP, USER_LOGIN, USER_LOGOUT, CURRENT_USER }
+const USER_REQUEST_PASSWORD = gql`
+  mutation USER_REQUEST_PASSWORD($email: String!) {
+    userRequestPassword(email: $email)
+  }
+`
+
+const USER_RESET_PASSWORD = gql`
+  mutation USER_RESET_PASSWORD($key: String!, $password: String!, $passwordAgain: String!) {
+    userResetPassword(key: $key, password: $password, passwordAgain: $passwordAgain)
+  }
+`
+
+const USER_EDIT = gql`
+  mutation USER_EDIT($email: String!, $password: String!, $name: String!){
+    userEdit(email: $email, password: $password, name: $name)
+  }
+`
+
+export {
+  USER_SIGNUP,
+  USER_LOGIN,
+  USER_LOGOUT,
+  CURRENT_USER,
+  USER_REQUEST_PASSWORD,
+  USER_RESET_PASSWORD,
+  USER_EDIT
+}

+ 0 - 53
frontend/components/user/login.js

@@ -1,53 +0,0 @@
-import { useMutation } from '@apollo/react-hooks'
-import { Formik, Form } from 'formik'
-
-import { USER_LOGIN, CURRENT_USER } from '../../lib/graphql'
-import { TextInput } from '../../lib/forms'
-
-const LoginAdoption = adopt({
-  login: ({ render }) => (
-    <Mutation mutation={USER_LOGIN} refetchQueries={[{ query: CURRENT_USER }]}>
-      {(login, { data, error, loading }) =>
-        render({ login, data, error, loading })
-      }
-    </Mutation>
-  ),
-  form: ({ login: { login }, render }) => (
-    <Formik
-      initialValues={{
-        email: '',
-        password: ''
-      }}
-      onSubmit={async values => {
-        try {
-          const user = await login({ variables: values })
-          console.log(user)
-        } catch (error) {
-          console.log(error)
-        }
-      }}
-    >
-      {render}
-    </Formik>
-  )
-})
-
-const LoginForm = props => {
-  const [login, {loading, error}] = useMutation(USER_LOGIN)
-  const {data, loading, error} = useQuery(CURRENT_USER)
-  if 
-  return (
-    <Form>
-      <TextInput label='Email' name='email' type='email' placeholder='email' />
-      <TextInput
-        label='Password'
-        name='password'
-        type='password'
-        placeholder='password'
-      />
-      <button type='submit'>Login!</button>
-    </Form>
-  )
-}
-
-export default LoginForm

+ 12 - 39
frontend/components/user/user.js

@@ -1,48 +1,21 @@
-import { Query, Mutation } from 'react-apollo'
-import { adopt } from 'react-adopt'
+import { useState } from 'react'
 import Link from 'next/link'
 
-import { CURRENT_USER, USER_LOGOUT } from '../../lib/graphql'
-import LoginForm from './login'
-
-const UserAdoption = adopt({
-  user: ({ render }) => <Query query={CURRENT_USER}>{render}</Query>,
-  logout: ({ render }) => <Mutation mutation={USER_LOGOUT} refetchQueries={[{ query: CURRENT_USER }]}>{render}</Mutation>
-})
-
 const UserNav = props => {
-  const [menu, setMenu] = React.useState(false)
+  const [menu, setMenu] = useState(false)
 
   return (
     <>
-      <UserAdoption>{({ user, logout }) => {
-        if (user.loading) {
-          return (
-            <p>Loading...</p>
-          )
-        }
-        if (user.error) {
-          return (
-            <LoginForm />
-          )
-        }
-        const { name, email, id } = user.data.me
-        return (
-          <>
-            <a
-              href='' onClick={ev => {
-                ev.preventDefault()
-                setMenu(!menu)
-              }}
-            >{name}
-            </a>
-            {menu ? (
-              <UserNavMenu />
-            ) : null}
-          </>
-        )
-      }}
-      </UserAdoption>
+      <a
+        href='' onClick={ev => {
+          ev.preventDefault()
+          setMenu(!menu)
+        }}
+      >sali
+      </a>
+      {menu ? (
+        <UserNavMenu />
+      ) : null}
     </>
   )
 }

+ 41 - 1
frontend/lib/graphql.js

@@ -108,8 +108,48 @@ const CREATE_TRAINING_TYPE = gql`
   }
 `
 
+const BLOCKS = gql`
+  query BLOCKS {
+    blocks {
+      sequence
+      title
+      duration
+      variation
+      format {
+        name
+        description
+      }
+      tracks {
+        title
+        artist
+        duration
+        link
+      }
+      exercise {
+        name
+        description
+        video
+        targets
+        baseExercise {
+          name
+        }
+      }
+      description
+    }
+  }
+`
+
+const CREATE_BLOCK = gql`
+  mutation CREATE_BLOCK($sequence: Int!, $title: String!, $duration: Int!, $variation: String, $format: ID, $tracks: [ID]!, $exercises: [ID]!, $description: String!) {
+    createBlock(sequence: $sequence, title: $title, duration: $duration, variation: $variation, format: $format, tracks: $tracks, exercises: $exercises, description: $description) {
+      id
+    }
+  }
+`
+
 export {
   USER_LOGIN, USER_LOGOUT, USER_SIGNUP, CURRENT_USER,
   TRAINING, TRAININGS, CREATE_TRAINING,
-  TRAINING_TYPES, CREATE_TRAINING_TYPE
+  TRAINING_TYPES, CREATE_TRAINING_TYPE,
+  BLOCKS, CREATE_BLOCK
 }

+ 0 - 0
frontend/lib/tests/regex.js


+ 3 - 3
frontend/package-lock.json

@@ -2534,9 +2534,9 @@
       "dev": true
     },
     "@types/react": {
-      "version": "16.9.16",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.16.tgz",
-      "integrity": "sha512-dQ3wlehuBbYlfvRXfF5G+5TbZF3xqgkikK7DWAsQXe2KnzV+kjD4W2ea+ThCrKASZn9h98bjjPzoTYzfRqyBkw==",
+      "version": "16.9.17",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.17.tgz",
+      "integrity": "sha512-UP27In4fp4sWF5JgyV6pwVPAQM83Fj76JOcg02X5BZcpSu5Wx+fP9RMqc2v0ssBoQIFvD5JdKY41gjJJKmw6Bg==",
       "dev": true,
       "requires": {
         "@types/prop-types": "*",

+ 2 - 2
frontend/package.json

@@ -42,7 +42,7 @@
     "@babel/preset-react": "^7.7.4",
     "@testing-library/react": "^9.4.0",
     "@testing-library/react-hooks": "^3.2.1",
-    "@types/react": "^16.9.16",
+    "@types/react": "^16.9.17",
     "@types/yup": "^0.26.27",
     "@zeit/next-typescript": "^1.1.1",
     "babel-eslint": "^10.0.3",
@@ -71,4 +71,4 @@
   "standard": {
     "parser": "babel-eslint"
   }
-}
+}

+ 0 - 5
frontend/pages/test.tsx

@@ -1,5 +0,0 @@
-const IndexPage = () => (
-    <h1>Hello Next with TypeScript!</h1>
-)
-
-export default IndexPage

+ 0 - 18
frontend/pages/test2.tsx

@@ -1,18 +0,0 @@
-let a = 12
-
-type Style = 'bold' | 'italic'
-
-interface Person {
-    first: string
-    last: string
-}
-
-(x: number, y?: number): string {
-    return Math.pow(x, y).toString()
-}
-
-const About = ({ name }: { name: string }) => (
-    <h1>This page is about {name}</h1>
-)
-
-export default About

+ 15 - 21
frontend/pages/user.tsx

@@ -1,26 +1,20 @@
-import User from '../components/user/user'
+import SignupForm from '../components/user/SignupForm'
+import LoginForm from '../components/user/LoginForm'
+import LogoutButton from '../components/user/LogoutButton'
+import RequestPassword from '../components/user/RequestPassword'
+import ResetPassword from '../components/user/ResetPassword'
+import UserEditForm from '../components/user/UserEditForm'
+import UserDetails from '../components/user/UserDetails'
 
-interface Gogo {
-  g: string
-  h: number
-}
-
-let gg: Gogo = { g: 'hello', h: 45 }
-
-function letsGogo(anyGogo?: Gogo): void {
-  console.log(anyGogo)
-  return
-}
-
-letsGogo(gg)
-letsGogo({ g: '12', h: 12 })
-
-const myObj = { className: 'bongers' }
-
-const UserPage = (props?: Gogo) => (
+const UserPage = () => (
   <>
-    <h1 {...myObj}>TypeScript User</h1>
-    <User />
+    <SignupForm />
+    <LoginForm />
+    <LogoutButton />
+    <RequestPassword />
+    <ResetPassword />
+    <UserEditForm />
+    <UserDetails />
   </>
 )
 

+ 2 - 1
frontend/tsconfig.json

@@ -17,7 +17,8 @@
     "noEmit": true,
     "esModuleInterop": true,
     "resolveJsonModule": true,
-    "isolatedModules": true
+    "isolatedModules": true,
+    "noImplicitAny": true
   },
   "exclude": [
     "node_modules"