Tuesday, 18 June, 2019 UTC


Summary

Create a folder named question-modal within the src/components directory and a file index.js within it. Open the file and update it with the snippet below:
import React from "react";
import Modal from "react-modal";
import QuestionForm from "../question-form";
import "./modal.css";
import Close from "./cancel.svg";
const customStyles = {
  content: {
    top: "40%",
    left: "50%",
    right: "auto",
    bottom: "auto",
    marginRight: "-50%",
    transform: "translate(-50%, -50%)",
    border: "none",
    width: "450px",
    height: "400px",
    background: "#f7f8f9",
    boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
  }
};
Modal.setAppElement("#root");
const QuestionModal = ({ isOpen, closeModal }) => {
  return (
    <Modal
      isOpen={isOpen}
      onRequestClose={closeModal}
      style={customStyles}
      contentLabel="Question Modal"
    >
      <div className="modal-header">
        <p />
        <p>Add a question</p>
        <span onClick={closeModal} className="close">
          <img src={Close} alt="Press button to close modal" />
        </span>
      </div>
      <QuestionForm closeModal={closeModal} />
    </Modal>
  );
};
export default QuestionModal;
You can find the cancel asset used here.
Calling the setAppElement method with a query value. It renders the modal within the selected element. The QuestionModal takes two props, isOpen to toggle the display of the modal and closeModal for closing the modal.
We import and render the QuestionForm here and pass the closeModal function as a prop.
Next, we’ll create the modal.css file referenced in the snippet above; create a file modal.css within the src/components/question-modal directory. Open the file and copy the contents below into it:
.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 35px;
}
.modal-header .close img {
  width: 12px;
  opacity: 0.6;
  cursor: pointer;
}
.close img:hover {
  color: rgba(0, 0, 0, 0.9);
}
.modal-header p {
  margin: 0;
  font-weight: 500;
  font-size: 13px;
  color: rgba(0, 0, 0, 0.5);
  text-transform: uppercase;
}
Displaying the question modal
To display the question modal, we’ll need to include a trigger for the user to interact with. The trigger will be a button to display the form on click. Let’s update the App component to render the modal and to add the button trigger.
Open the App.js file and update it to be similar to the snippet below:
// src/App.js
import React, { useState } from "react";
import { ApolloProvider } from "react-apollo";
import ApolloClient from "apollo-boost";
import { toast } from 'react-toastify';
import Questions from "./components/questions";
import QuestionModal from "./components/question-modal";
import Add from './add.svg';
import 'react-toastify/dist/ReactToastify.css';
import "./App.css";

toast.configure(); //  --- 1
const client = new ApolloClient({
  uri: "https://api.8base.com/cjvp33au9000201ru4hupd7r5"
});

function App() {
  const [modalOpen, setModalOpen] = useState(false); // -- 2
  const closeModal = () => {
    setModalOpen(false); // --- 3
  }; 
  return (
    <ApolloProvider client={client}>
      <div className="App">
        <header>
          <div>GOT Quizapp</div>
        </header>
        <Questions />
        <button className="add-question" onClick={_ => setModalOpen(true)}> // --- 4
          <img src={Add} alt="Click to create a new question"/>
        </button>
        <QuestionModal // --- 5
          isOpen={modalOpen}
          closeModal={closeModal}
        />
      </div>
    </ApolloProvider>
  );
}
export default App;
You can find the assets used in this component here
Let’s go through some of the new changes to the App component. Each new change is denoted by a comment, we’ll go through each one:
-- 1 - here we call the configure method on the toast object. This allows us to make use of the toast component everywhere in the application without rendering.
-- 2 - we define state values to manage the display state of the modal
-- 3 - we create the function for closing the modal.
-- 4 - the button trigger for displaying the modal
-- 5 - here, we render the modal component and pass the closeModal function as a prop.
Now we can fetch questions as well as creating questions to be stored on the 8base platform. The final view of the application should be similar to the screenshot below:
You can now create questions successfully, your games nights will have the Game of Thrones edge from now on. Enjoy.