Todos application

No lets build the todos application. Previously we built the index page that holds the routes to our individual components.

Now let's create the components themselves. Create a /components directory at the root level.

Create 2 files:

/components/login.js

import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { auth } from "../utils/rockets";
 
export function Login(props) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const history = useHistory();
 
  async function handleSubmit(e) {
    e.preventDefault();
 
    // login
    try {
      await auth.signIn({email, password, provider: "local"});
    } catch (error) {
      alert("error logging in");
      console.error(error);
      return;
    }
 
    // redirect back to `/`
    history.push("/");
  }
 
  return (
    <div>
      <h1>Login</h1>
      <form onSubmit={handleSubmit}>
        <input
          type="email"
          placeholder="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <input
          type="password"
          placeholder="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        <button>Login</button>
      </form>
    </div>
  );
}

/components/signup

import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { auth } from "../utils/rockets";
 
export function Signup(props) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const history = useHistory();
 
  async function handleSubmit(e) {
    e.preventDefault();
 
    // signup
    try {
      await auth.register({email, password});
    } catch (error) {
      alert("error signing up");
      console.error(error);
      return;
    }
 
  }
 
  return (
    <div>
      <h1>Signup</h1>
      <form onSubmit={handleSubmit}>
        <input
          id="inputUserEmail"
          type="email"
          placeholder="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <input
          id="inputUserPassword"
          type="password"
          placeholder="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        <button id="signupButton">Signup</button>
      </form>
    </div>
  );
}

Next let's create the App itself. In the App.js copy the following code:

import React, { useState } from "react";
import { Link } from "react-router-dom";
import { auth } from "./utils/rockets";
import { gql, useQuery, useMutation, useSubscription } from "@apollo/client";
 
const GET_TODOS = gql`
  subscription {
    todos {
      id
      created_at
      name
    }
  }
`;
 
const INSERT_TODO = gql`
  mutation($todo: todos_insert_input!) {
    insert_todos(objects: [$todo]) {
      affected_rows
    }
  }
`;
 
function App() {
  const { data, loading } = useSubscription(GET_TODOS);
  const [insertTodo] = useMutation(INSERT_TODO);
  const [todoName, setTodoName] = useState("");
 
  console.log("todos: ", data);
  if (loading) {
    return <div>Loading</div>;
  }
 
  return (
    <div>
      <Link to="/login">Login</Link>
      <div onClick={() => auth.logout()}>Logout</div>
      <div>
        <form
          onSubmit={async (e) => {
            e.preventDefault();
 
            try {
              await insertTodo({
                variables: {
                  todo: {
                    name: todoName,
                  },
                },
              });
            } catch (error) {
              console.error(error);
              return alert("Error creating todo", todoName);
            }
            alert("Todo created");
          }}
        >
          <input
            id="inputTodo"
            type="text"
            placeholder="todo"
            value={todoName}
            onChange={(e) => setTodoName(e.target.value)}
          />
          <button id="createTodo">Create todo</button>
        </form>
      </div>
      {!data || !data.todos || !data.todos.length ? (
        "no data"
      ) : (
        <ul id="todosList">
          {data.todos.map((todo) => {
            return <li key={todo.id}>{todo.name}</li>;
          })}
        </ul>
      )}
    </div>
  );
}
 
export default App;