Slack Clone with React | Semantic UI | GraphQL | PostgresSQL (PART 6)

Slack Clone with React | Semantic UI | GraphQL | PostgresSQL (PART 6)

·

5 min read

Previously, we created our Graphql queries and mutations. You can find that article here

Today, we're gonna take a step back from the backend for a moment and get our Frontend setup with Apollo Client.

Create React Project

For simplicity, I'm going to have a different folder for my frontend.

cd desktop
mkdir chatroom_front
cd chatroom_front

Create a react project inside the chatroom_front folder, don't give it a name.

npx create-react-app .

of course, this takes some time :)

Project Clean up

remove all the test files. Therefore anything with a .test.js extension you can remove. Also remove, logo.svg, serviceWorkers.js and setupTests.js

Install Packages

For starters, let's install all the packages we need.

npm i @apollo/client graphql react-hook-form semantic-ui-css semantic-ui-react react-router-dom
  • @apollo/client used to connect/communicate to the apollo server on the backend
  • graphql enables us to call queries and mutations in frontend - react-hook-form form validation package for our forms using hooks (personal preference, not required)
  • semantic-ui-css and semantic-ui-react what were using for our UI.
  • react-router-dom used for routing throughout our app.

Setup Apollo Client

let's get apollo setup. inside src > index.js add this

import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client";

const client = new ApolloClient({
  uri: "http://localhost:4000/graphql",
  cache: new InMemoryCache()
});

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

We are importing ApolloClient which sets up our connection to our backend apollo server, we need to pass in the uri to the backend apollo server we want to connect to. ApolloProvider is the wrapper that gives our app access to everything, then we pass in the client.

While we're at it, let's add the semantic CSS styles in this file as well.

import "semantic-ui-css/semantic.min.css";

So, in the end, your index.js file should look like this now

import React from "react";
import ReactDOM from "react-dom";
import "semantic-ui-css/semantic.min.css";
import App from "./App";
import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client";

const client = new ApolloClient({
  uri: "http://localhost:4000/graphql",
  cache: new InMemoryCache()
});
ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById("root")
);

Project Structure so far

At the moment, I have a simple setup. I have all the form components that we'll need.

Inside src dir, create a Home.js component.

import React from "react";

const Home = () => {
  return <div>Auth or Slack</div>;
};

export default Home;

This will be the component that will render either the Auth page (will create in a minute) if not logged in or the Slack component if we're logged in.

Create a components folder in src dir. Inside src > components, add these following folders =>

src > components > auth
src > components > channel
src > components > message
src > components > team

For now, these folders will have form components.

  • src > components > auth > Login.js and Register.js and login.css
  • src > components > channel > CreateChannel.js
  • src > components > message > CreateMessage.js
  • src > components > team > CreateTeam.js

Inside src > App.js file let's add the routes for these components.

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Login from "./components/auth/Login";
import Register from "./components/auth/Register";
import CreateTeam from "./components/team/CreateTeam";
import Channel from "./components/channel/CreateChannel";
import Home from "./Home";

function App() {
  return (
    <div className="App">
      <Router>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/login" component={Login} />
          <Route path="/register" component={Register} />
          <Route path="/create-team" component={CreateTeam} />
           <Route path="/create-message" component={CreateMessage} />
          <Route path="/create-channel" component={CreateChannel} />
        </Switch>
      </Router>
    </div>
  );
}
export default App;

Nothing special here, just some basic routing setup. In the end, our files should look like this =>

src > components > auth > Login.js

import React from "react";

const Login = () => {
  return <div>login</div>;
};
export default Login;

src > components > auth > Register.js

import React from "react";

const Register = () => {
  return <div>register</div>;
};
export default Register;

src > components > channel > CreateChannel.js

import React from 'react'

const CreateChannel = () => {
    return (
        <div>
            create channel
        </div>
    )
}
export default CreateChannel;

src > components > message > CreateMessage.js

import React from "react";

const CreateMessage = () => {
  return <div>im the create message component</div>;
};

export default CreateMessage;

src > components > team > CreateTeam.js

import React from 'react'

const CreateTeam = () => {
    return (
        <div>
            create team 
        </div>
    )
}

export default CreateTeam

In the end, your folder structure should look like this.

Screen Shot 2020-09-19 at 2.11.04 AM.png

That's all for this one folks. In the next article, we'll work on getting the login and register UI done using Semantic with react-hook-form. Stay tuned! :)

FYI the login.css file is empty, so no worries about that :)