Game of Thrones Quiz Game with React and GraphQL: Creating the Question Modal
Publikováno: 17.6.2019
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:
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.