[Gametize Tech] Knowledge: Sample mix of HTML + JS Pseudo-code in React JS
FeaturedOur app.gametize.com platform is rendered using ReactJS,
paired with the PureCSS library (https://purecss.io/) for our grids.
Feel free to use any frameworks or CSS libraries for your perusal;
I will be explaining our Challenge module with a mix of HTML
and JS pseudo-code examples.
Should you require the specifics of how the elements are styled, I
strongly suggest you visit https://app.gametize.com/topic/5459,
view the available challenges, and use your browser's developer console
to inspect the CSS.
Likewise, feel free to play with the Challenges in https://app.gametize.com/topic/5459
to better understand how the different Challenge types are handled.
For brevity, let's assume that the Challenge examples below are published,
public, not expired, unlocked, players can complete the challenge only once,
and the player user is logged in.
On page load, we will be retrieving information about the challenge
using the Challenge Profile API (see https://developers.gametize.com/#challenge-profile).
Error-handling wise, watch out for cases where the response code is not
200 (usually it is 500 if there's an error), and scrutinise the error message.
Render any error-handling interfaces based on the code and messages, if necessary.
Arbitrarily, our Challenge module is structured this way: (1) render the Challenge information
(image, title, description etc), (2) the form the player will use to complete the challenge
(this changes depending on the challenge type), (3) any maps, if the Admin chooses to
embed a map/location, and (4) the challenge result. It looks a little like this:
<div class="challenge">
<div class="container">
{ renderChallengeInformation() }
</div>
<div class="container">
{ renderChallengeForm() }
</div>
<div class="container">
{ renderMap() }
</div>
<div class="container">
{ renderChallengeResult() }
</div>
</div>
Below is how we render the Challenge information. We have buttons for
navigating between the individual Challenges; the "next challenge" and
"previous challenge" information can be retrieved using the aforementioned
Challenge Profile API.
The rest of the Challenge information (image, description, text with the
number of comments/completions, buttons) here is self-explanatory. I will
not go into detail about their front-end implementation, but they can be
re-arranged however you like depending on your own grid CSS framework.
<div class="row">
<div class="column">
{ renderPreviousChallengeButton() - if any }
</div>
<div class="column">
<div class="subcolumn">
{ renderChallengeImage() }
</div>
<div class="subcolumn">
{ renderChallengeTitle() }
{ renderChallengeDescription() }
{ renderNumberOfComments() }
{ renderNumberOfCompletions() }
{ renderChallengeBookmarkButton() }
{ renderChallengeCommentButton() }
</div>
</div>
<div class="column">
{ renderNextChallengeButton() - if any }
</div>
</div>
For rendering the Challenge Form, we rely on JS switch-case logic to determine
the correct Challenge interface to display. We are checking the challengeTypeId
from the API call to determine which interface to render. For simplicity, I will
only be showing your the rendering logic of our Standard Challenge below.
Our image uploader is a <input type="file"> paired with a <label>, with some
CSS trickery to hide the default file upload interface, and replace it with a
photo upload image in <label>. For more, you can read https://stackoverflow.com/a/25825731.
We use JS logic to check for the file type to be uploaded before allowing the
Players to successfully upload it.
Clicking the Submit Button at the end of each Challenge Form relies on the 'Complete
Challenge' API (see https://developers.gametize.com/#complete-challenge). Depending
on the challenge type, you will need to save/cache certain parameters from your
front-end to be passed as queries for this POST.
<div class="form grid">
<div class="row challenge-type-row">
<div class="column">
{ renderTextInput() }
</div>
<div class="column">
{ renderImageUploader() }
</div>
</div>
<div class="row">
<div class="column">
{ renderSubmitButton() }
</div>
</div>
</div>
In prose, this is how we handle some of other Challenge types on the front-end -
(1) Photo Challenge: a front-end validation check to ensure that there is an image
prepared in the uploader before clicking on the Submit button.
(2) Video Challenge: similar to photo challenge, except the JS logic now checks for
video file types
(3) Quiz Challenge: remove the submit button. instead, render a series of full-width
buttons with the quiz options as the button texts. clicking on any of the option
buttons trigger the 'Complete Challenge' API, and the clicked option button's
quiz_option_id should be sent as a query. Remove the text input and image
uploader from the Standard Challenge example above.
(4) Prediction Challenge: same as Quiz Challenge
(5) Single-selection Poll Challenge: same as Quiz Challenge
(6) Multiple-selection Poll Challenge: keep the submit button. add JS logic for
rendering "active" or "inactive" states to the full-width poll option buttons.
Click on the poll option buttons to toggle between their states. When submitting,
send over the option IDs of the "active" buttons to the 'Complete Challenge' API.
Multiple quiz_option_ids can be submitted as an array. Remove the text input and
image uploader from the Standard Challenge example above.
(7) Confirmation Challenge: change the copywriting of the submit button to the
confirmation button text (which can be retrieved using the 'Challenge Profile' API
call). API works similarly to Quiz Challenge, so you will need to send over
the quiz_option_id as a query to the 'Complete Challenge' API. Remove the text input
and image uploader from the Standard Challenge example above.
(8) Fixed Answer Challenge: similar to Standard Challenge, but remove the image uploader.
Checking for the correct 'Fixed Answer' is handled by the 'Complete Challenge' API.
For rendering the map, we simply use an <img> tag, with the source from maps.google.com.
The information regarding the latitude and longitude can be retrieved from the 'Challenge
Profile' API
<div class="row">
<div class="column">
<img src="https://maps.google.com/maps/api/staticmap?&markers=[latitude],[longitude]&size=[setYourSizehere-forExample100x100]&key=[yourGoogleMapsKey]" />
</div>
</div>
For rendering the Challenge Result module, we rely on switch-case logic to render different
interfaces depending on the Challenge type. The different interfaces are the following:
(1) View Completed Button: a full-width button occupying the container. The button will
route the player to the Player Activity component for said Challenge. An example of
this Player Activity is https://app.gametize.com/challenge/86188/activity
(2) Quiz Result: a non-interactable interface displaying the number of players got a Quiz
Challenge right or wrong. You can view said interface by visiting https://app.gametize.com/challenge/86193, and scrolling to the bottom of the page.
(3) Poll Result: this interface replaces the Challenge Form interface above only if the player
has completed the challenge (ie. show one or the other, not both). Confirmation, Poll,
Prediction Challenges only allow for single-attempts, and we only want to show the results
upon completion.
(4) Nothing: Simply, we do not render any of the prior 3 interfaces.
<div class="row">
{
renderViewCompletedButton() if the Challenge is:
- Standard Challenge, or
- Photo Challenge, or
- Video Challenge, or
- Custom Form Challenge
}
{
renderQuizResult() if the Challenge is:
- Single-Attempt Quiz Challenge
- Repeatable Quiz Challenge
}
{
renderPollResult() if the Challenge is:
- Confirmation Challenge
- Poll Challenge (Single- or Multiple-Selection)
- Prediction Challenge
}
{
renderNothing() if the Challenge is:
- A Flashcard
- Fixed Answer Challenge
- Personality Quiz Challenge
- Any other Challenges not already listed in the interfaces above.
}
</div>
Note:
The article's technical specifications and details are subject to potential changes based on our discretion. It is important to note that the information presented in the article might have become outdated or lost its relevance in the present context.
If you are interested to learn more about this, please drop an email to support@gametize.com with your queries regarding the article!
Please sign in to leave a comment.
Comments
0 comments