Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ninas Project Labyrinth #212

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
# Project Labyrinth

Replace this readme with your own information about your project.
This week's project is all about tying together the skills you've learnt to build an app that retrieves a list of actions from the backend and presents them to the user as interactable items.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
**What you need to do**

✓ Your page should be responsive.

✓ Use redux to store the current state of the game.

✓ Focus on making the UX of your app good. Handle the response delay.

✓ Use thunks to wrap your API calls.

## The problem

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?

In this week's project, you'll be building a project which allows a user to navigate a maze, in the form of a text-based adventure, provided by a backend.

The goal for this week is to use the API specified to build a frontend that gives the user control over what to do next. You'll focus on using thunks and redux to build the communication with the backend. Beyond that, you'll have a lot of freedom.

This week's project comes in the form of a text-based adventure. Classic games like this usually present the user with a description of where they are and provide several alternatives about what they can do.

## View it live

Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
https://labyrinth-game-redux.netlify.app/

Sound Effect by "https://pixabay.com/users/maxou-yt-30144327/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=music&amp;utm_content=141426">MAXOU-YT</a> from "https://pixabay.com/sound-effects//?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=music&amp;utm_content=141426">Pixabay
23 changes: 19 additions & 4 deletions code/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
# Project Labyrinth

Replace this readme with your own information about your project.
This week's project is all about tying together the skills you've learnt to build an app that retrieves a list of actions from the backend and presents them to the user as interactable items.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
**What you need to do**

✓ Your page should be responsive.

✓ Use redux to store the current state of the game.

✓ Focus on making the UX of your app good. Handle the response delay.

✓ Use thunks to wrap your API calls.

## The problem

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?

In this week's project, you'll be building a project which allows a user to navigate a maze, in the form of a text-based adventure, provided by a backend.

The goal for this week is to use the API specified to build a frontend that gives the user control over what to do next. You'll focus on using thunks and redux to build the communication with the backend. Beyond that, you'll have a lot of freedom.

This week's project comes in the form of a text-based adventure. Classic games like this usually present the user with a description of where they are and provide several alternatives about what they can do.

## View it live

Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
https://labyrinth-game-redux.netlify.app/

Sound Effect by "https://pixabay.com/users/maxou-yt-30144327/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=music&amp;utm_content=141426">MAXOU-YT</a> from "https://pixabay.com/sound-effects//?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=music&amp;utm_content=141426">Pixabay
18,293 changes: 18,293 additions & 0 deletions code/package-lock.json

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
@@ -4,14 +4,21 @@
"private": true,
"dependencies": {
"@babel/eslint-parser": "^7.18.9",
"@reduxjs/toolkit": "^1.9.5",
"eslint": "^8.21.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"lottie-react": "^2.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.10.0",
"redux": "^4.2.1",
"styled-components": "^5.3.10",
"uniqid": "^5.4.0"
},
"scripts": {
"start": "react-scripts start",
23 changes: 20 additions & 3 deletions code/src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import React from 'react'
import { Provider } from 'react-redux';
import { combineReducers, configureStore } from '@reduxjs/toolkit';
import { labyrinth, game } from 'reducers/labyrinth';
import { Background } from 'components/BackGround';
import { StartPage } from 'components/StartPage';

const reducer = combineReducers({
labyrinth: labyrinth.reducer,
game: game.reducer
});

const store = configureStore({ reducer });

export const App = () => {
return (
<div>
Find me in src/app.js!
</div>
<section className="main-container">
<Provider store={store}>
<Background />
<div>
<StartPage />
</div>
</Provider>
</section>
)
}
19 changes: 19 additions & 0 deletions code/src/components/BackGround.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import styled from 'styled-components';
import backgroundImage from 'images/background.jpg'

const StyledBackground = styled.div`
background-image: url(${backgroundImage}); // replace with your image path
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: -1;
`;
export const Background = () => {
return <StyledBackground />;
};
74 changes: 74 additions & 0 deletions code/src/components/Direction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { nextMove } from 'reducers/labyrinth';
import styled from 'styled-components';

export const Direction = ({ actions = [] }) => {
const dispatch = useDispatch();

useEffect(() => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done with this code!

const handleKeyDown = (event) => {
switch (event.keyCode) {
case 37: // left arrow
dispatch(nextMove('west'));
break;
case 38: // up arrow
dispatch(nextMove('north'));
break;
case 39: // right arrow
dispatch(nextMove('east'));
break;
case 40: // down arrow
dispatch(nextMove('south'));
break;
default:
break;
}
};

document.addEventListener('keydown', handleKeyDown);

return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, [dispatch]);

const DirectionSection = styled.div`
display: flex;
flex-direction: column;
align-items: center;
`

const MoveBtn = styled.button`
font-family: 'Castoro Titling', cursive;
background-color: #000;
border-radius: 5px;
padding: 5px 10px;
font-size: 1rem;
cursor: pointer;
margin-bottom: 20px;
color: lightgoldenrodyellow;
&:hover {
background-color: #999966;
color: #000;
}
@media (min-width: 668px) {
font-size: 1.2rem;
}
`
const moveOnClick = (direction) => {
dispatch(nextMove(direction))
}
return (
actions.map((action) => (
<DirectionSection>
<div key={action.direction} className="direction-div">
<p>{action.description}</p>
<div>
<MoveBtn type="button" onClick={() => moveOnClick(action.direction)}>Go {action.direction}</MoveBtn>
</div>
</div>
</DirectionSection>
))
);
};
83 changes: 83 additions & 0 deletions code/src/components/Game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* eslint-disable react/no-unescaped-entities */
import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import endPageImage from 'images/end-game-image.jpg'
import soundFile from 'images/angels-singing.mp3'
import { Direction } from './Direction';

export const Game = () => {
const description = useSelector((store) => store.game.description);
const [showEndPage, setShowEndPage] = useState(false);
const onRestartButtonClick = () => {
window.location.reload()
}

useEffect(() => {
const audio = new Audio(soundFile); // Create an Audio object with the sound file

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great input with the sound-effect!

if (showEndPage) {
audio.play(); // Play the sound when showEndPage becomes true
}
}, [showEndPage]);

const ResetBtn = styled.button`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create a separate file for your design and styled components to keep function-files a bit cleaner/easy to follow :) But just an input, nothing major!

font-family: 'Castoro Titling', cursive;
background-color: #293d3d;
border-radius: 5px;
padding: 5px 10px;
font-size: 1rem;
cursor: pointer;
margin-bottom: 20px;
color: #FEF5BD;
&:hover {
background-color: #FEF5BD;
color: #000;
}
@media (min-width: 668px) and (max-width: 1023px) {
font-size: 1.2rem;
}
@media (min-width: 1024px) {
font-size: 1.2rem;
margin-top: 30px;
}
`
const EndBtn = styled(ResetBtn)`
background-color: #b3cccc;
font-size: 1.5rem;
padding: 10px 20px;
`;

const StyledParagraph = styled.p`
background-color: #c2d6d6;
border-radius: 30px;
padding: 10px;
text-align: center;
margin-top: 100px;
`
const StyledImage = styled.img`
max-width: 100%;
max-height: 500px;
border-radius: 30px;
`;

return (
<div className="game-div">
<p className="game-p">{description.description} <br /> <span style={{ textDecoration: 'underline' }}>which path will you choose?</span></p>
<Direction actions={description.actions} />
{description.coordinates === '1,3' && (
<>
<ResetBtn type="button" onClick={onRestartButtonClick}>Play again</ResetBtn>
{!showEndPage && (
<EndBtn type="button" onClick={() => setShowEndPage(true)}>Show the light!</EndBtn>
)}
{showEndPage && (
<StyledImage src={endPageImage} alt="End Page" />
)}
<div>
<StyledParagraph>~By Nina W~ <br /> Student at Technigo</StyledParagraph>
</div>
</>
)}
</div>
)
}
15 changes: 15 additions & 0 deletions code/src/components/Loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import Lottie from 'lottie-react';
import myAnimation from '../images/lottie2.json'

const Loading = () => {
return (
<Lottie
animationData={myAnimation} // Replace animationData with your own Lottie animation data
loop
autoplay
style={{ height: '300px', width: '300px' }} />
);
};

export default Loading;
62 changes: 62 additions & 0 deletions code/src/components/StartGame.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { game, labyrinth } from 'reducers/labyrinth';
import styled from 'styled-components/macro';

const StyledForm = styled.form`
display: flex;
flex-direction: column;
align-items: center;
`
const StyledInput = styled.input`
font-family: 'Castoro Titling', cursive;
background-color: #FEF5BD;
border: none;
padding: 7px 5px 7px 10px;
outline: none;
font-size: 1rem;
color: #000;
margin: 5vh 0 7vh 0;
width: 145px;
border-radius: 5px;
@media (min-width: 668px) {
font-size: 1.5rem;
width: 210px;
}
`
const StyledBtn = styled.button`
font-family: 'Castoro Titling', cursive;
background-color: #408000;
color: white;
border: none;
border-radius: 20px;
padding: 5px 10px;
font-size: 1rem;
cursor: pointer;
&:hover {
box-shadow: 2px 2px 5px rgba(254, 245, 189, 0.5), -2px -2px 5px rgba(254, 245, 189, 0.5);
}
@media (min-width: 668px) {
font-size: 1.5rem;
}
`
export const StartGame = () => {
const [userName, setUserName] = useState('');
const dispatch = useDispatch();

const InputUserName = (event) => {
event.preventDefault();
dispatch(game.actions.setUserName(userName));
dispatch(labyrinth());
}

return (
<StyledForm onSubmit={InputUserName}>
<label htmlFor="user-input">
<StyledInput id="user-input" type="text" placeholder="Name..." onChange={(event) => setUserName(event.target.value)} value={userName} required />
</label>
<StyledBtn type="submit">Enter Labyrinth</StyledBtn>
</StyledForm>
)
}
23 changes: 23 additions & 0 deletions code/src/components/StartPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { useSelector } from 'react-redux';
import Loading from 'components/Loading';
import { Game } from './Game';
import { StartGame } from './StartGame';

export const StartPage = () => {
const gameStarted = useSelector((store) => store.game.isStarted);
const loading = useSelector((store) => store.game.loading);

return (
<div className={gameStarted ? 'game-page' : 'start-page'}>
{!gameStarted && <h1>Welcome to the Labyrinth</h1>}
{loading && <Loading />}
{!loading && (
<div>
{!gameStarted && <StartGame />}
{gameStarted && <Game />}
</div>
)}
</div>
)
}
Binary file added code/src/images/angels-singing.mp3
Binary file not shown.
Binary file added code/src/images/background.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added code/src/images/end-game-image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions code/src/images/lottie.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"v":"5.4.2","fr":50,"ip":0,"op":100,"w":500,"h":500,"nm":"navigation","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"navigation Outlines - Group 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.477],"y":[1]},"o":{"x":[0.768],"y":[0]},"n":["0p477_1_0p768_0"],"t":0,"s":[0],"e":[-27]},{"i":{"x":[0.435],"y":[1]},"o":{"x":[0.63],"y":[0]},"n":["0p435_1_0p63_0"],"t":25,"s":[-27],"e":[0]},{"i":{"x":[0.33],"y":[1]},"o":{"x":[0.619],"y":[0]},"n":["0p33_1_0p619_0"],"t":50,"s":[0],"e":[27]},{"i":{"x":[0.503],"y":[1]},"o":{"x":[0.622],"y":[0]},"n":["0p503_1_0p622_0"],"t":77,"s":[27],"e":[0]},{"t":99}],"ix":10},"p":{"a":0,"k":[250.281,229.995,0],"ix":2},"a":{"a":0,"k":[150.281,144.495,0],"ix":1},"s":{"a":0,"k":[110,110,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[45.583,44.635],[-0.206,-44.635],[-45.583,43.823],[-0.206,20.489]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.223528977936,0.192156967462,0.674509983437,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.281,144.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Merged Shape Layer","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250.25,262.648,0],"ix":2},"a":{"a":0,"k":[250.25,262.648,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,33.474],[53.496,0],[0,-33.474],[-53.496,0]],"o":[[0,-33.474],[-53.496,0],[0,33.474],[53.496,0]],"v":[[96.863,0],[0,-60.609],[-96.863,0],[0,60.609]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.223528981209,0.192156970501,0.674510002136,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[150.25,150],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[250.25,250],"ix":2},"a":{"a":0,"k":[150.25,150],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"navigation Outlines - Group 2","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-53.496,0],[0,33.474],[0,0]],"o":[[0,0],[0,33.474],[53.496,0],[0,0],[0,0]],"v":[[-96.863,-27.952],[-96.863,-17.656],[0,42.952],[96.863,-17.656],[96.863,-27.952]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.223528981209,0.192156970501,0.674510002136,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[150.25,182.452],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[250.25,292.953],"ix":2},"a":{"a":0,"k":[150.25,192.952],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"navigation Outlines - Group 3","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0}],"markers":[]}
1 change: 1 addition & 0 deletions code/src/images/lottie2.json

Large diffs are not rendered by default.

135 changes: 130 additions & 5 deletions code/src/index.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,138 @@
@import url('https://fonts.googleapis.com/css2?family=Castoro+Titling&display=swap');
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
font-family: 'Castoro Titling', cursive;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
font-family: 'Castoro Titling', cursive;
}


.main-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30px;
}

h1 {
color: white;
display: flex;
justify-content: center;
text-align: center;
font-size: 2.5rem;
width: 260px;
}
.top-lottie-container {
margin-top: 60px;
}
.top-lottie {
width: 100px;
}

.maze-span {
color: #F8E152;
}
.large-span {
white-space: nowrap;
}
.game-div {
width: 90vw;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 100px;
}
.game-p {
font-weight: 700;
font-size: 1.4rem;
text-align: center;
width: 80vw;
color: white;
background-color: rgba(128, 128, 128, 0.5);
border-radius: 10px;
margin-bottom: 30px;
}
.direction-div {
width: 90vw;
height: auto;
background-color: rgba(128, 128, 128, 0.5);
color: #e7e3c8;
border-radius: 5px;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 10px;
}
.direction-div p {
text-align: justify;
width: 80vw;
padding: 5px 15px;
font-size: 1rem;
word-spacing: -3px;
}

@media (min-width: 668px) and (max-width: 1023px) {
.top-lottie {
width: 150px;
}
h1 {
font-size: 3rem;
}
.spinner {
height: 300px;
width: 300px;
}

.game-p {
font-size: 2rem;
}
.direction-div {
margin-bottom: 20px;
}
.direction-div p {
font-size: 1.3rem;
width: auto;
}


@media (min-width: 1024px) {
.top-lottie-container {
position: absolute;
top: 2vh;
left: 2vh;
margin: 0;
}
.top-lottie {
width: 100px;
}
}
.main-container {
margin-top: 10px;
width: 1024px;
}
.game-div {
margin-top: 40px;
}
h1 {
font-size: 2rem;
}
.game-p {
width: 70vw;
font-size: 1.6rem;
max-width: 1024px;
}
.direction-div {
width: 70vw;
max-width: 1024px;
}
.direction-div p {
width: 60vw;
font-size: 1.3rem;
max-width: 924px;
}

}
75 changes: 75 additions & 0 deletions code/src/reducers/labyrinth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
user: '',
isStarted: false,
description: '',
isLoading: false,
move: []
}

export const game = createSlice({
name: 'game',
initialState,
reducers: {
setUserName: (store, action) => {
store.user = action.payload
},
gameIsStarted: (store, action) => {
store.isStarted = action.payload
},
setDescription: (store, action) => {
store.description = action.payload
},
setMove: (store, action) => {
store.move = [...store.move, action.payload]
},
isLoading: (store, action) => {
store.loading = action.payload
}
}

})
// the two thunks:
export const labyrinth = () => {
return (dispatch, getState) => {
dispatch(game.actions.isLoading(true))

const start = {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify({ username: getState().game.user })
}
fetch('https://labyrinth.technigo.io/start', start)
.then((res) => res.json())
.then((data) => {
dispatch(game.actions.setDescription(data))
dispatch(game.actions.gameIsStarted(true))
})
.finally(() => {
dispatch(game.actions.isLoading(false))
})
}
}

export const nextMove = (direction) => {
return (dispatch, getState) => {
dispatch(game.actions.isLoading(true))

const move = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: getState().game.user,
type: 'move',
direction })
}
fetch('https://labyrinth.technigo.io/action', move)
.then((res) => res.json())
.then((data) => {
dispatch(game.actions.setDescription(data))
})
.finally(() => {
dispatch(game.actions.isLoading(false))
})
}
}