[ PART 14 ] Creating a Twitter clone with GraphQL, Typescript, and React ( starting the Frontend )
Published: 2021-01-17 08:58:36

Hi everyone ;).

As a reminder, I'm doing this [Tweeter challenge](https://devchallenges.io/challenges/rleoQc34THclWx1cFFKH)

[Github repository](https://github.com/ips-coding-challenge/challenge_twitter)

[Db diagram](https://dbdiagram.io/d/5f75c0243a78976d7b75f7be)

## A little bit of Frontend

For the Frontend part, I will use React + Tailwindcss + Typescript. I just found a template so let's try it. If I can win some time avoiding to configure everything... I'll take it ^^. For the design , every challenge on [devChallenges.io](https://devchallenges.io/) provides a Figma file so I don't have to start the design from scratch. You can thanks {% user nghiemthu %} :D

```sh
npx create-react-app challenge_twitter_front --template tailwindcss-typescript
```

```sh
yarn start
```

Everything seems to work. Let's add more libraries that I will need.

```sh
yarn add @apollo/client graphql recoil react-hook-form @hookform/resolvers yup react-router-dom date-fns react-icons
```

- @apollo/client and graphql : for our queries/mutation & graphql related stuff
- recoil: for our global state management
- react-hook-form @hookform/resolvers yup: for our form validation
- react-router-dom: The router
- date-fns: we'll have some date to format
- react-icons: To have some icons to play with ;)

To start, let's just add the Router with some pages:

*src/App.tsx*

```typescript
import React from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import Home from './pages/Home'
import Login from './pages/Login'
import Register from './pages/Register'

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/login">
          <Login />
        </Route>
        <Route exact path="/register">
          <Register />
        </Route>
        <Route exact path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  )
}

export default App

```

And as an example, here is my Register page:

*src/pages/Register.tsx*

```typescript
import React from 'react'

const Register = () => {
  return <div>Register</div>
}

export default Register
```



## Register a user

We will start with the authentication. We will use **react-hooker-form** with **yup** for the validation. But before working on the Register page, let's create our apolloClient.

*src/client/index.ts*

```typescript
import { ApolloClient, InMemoryCache } from '@apollo/client'

const client = new ApolloClient({
  uri: process.env.REACT_APP_BACKEND_URL || 'http://localhost:4000',
  cache: new InMemoryCache(),
})

export default client

```

For now, I just follow the documentation ;). To have access to some hooks provided by the apolloClient, we will wrap our App with the ApolloProvider

*src/index.tsx*

```typescript
import { ApolloProvider } from '@apollo/client'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import client from './client'
import './styles/index.css'

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById('root')
)

```

Just for the sake of testing if everything works as expected I will play in my Register page ;).

*src/pages/Register.ts*

```typescript
import { gql, useMutation } from '@apollo/client'
import React from 'react'

const REGISTER = gql`
  mutation($input: RegisterPayload!) {
    register(input: $input) {
      token
      user {
        id
        username
        display_name
        email
        created_at
        updated_at
      }
    }
  }
`

const Register = () => {
  const [register, { loading, data, error }] = useMutation(REGISTER)

  return (
    <div>
      <button
        onClick={() => {
          register({
            variables: {
              input: {
                username: 'new',
                email: 'new@test.fr',
                display_name: 'New',
                password: 'password',
              },
            },
          })
        }}
      >
        Register
      </button>
      {loading && <div>Loading...</div>}
      {data && <div>{data.register.user.username}</div>}
    </div>
  )
}

export default Register

```

Don't forget to start the server and let's give a try ;).

![Register Page with result in console](https://dev-to-uploads.s3.amazonaws.com/i/pzs3njtbzp0w7as7go8j.png)

Nice ;). The client seems to work as expected.

I will stop here for now and I will start to **really** work on the user's registration in the next part ;).

Ciao & Take care ;).