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

Project Labyrinth #216

Open
wants to merge 2 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
31,523 changes: 31,523 additions & 0 deletions code/package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
@@ -4,14 +4,18 @@
"private": true,
"dependencies": {
"@babel/eslint-parser": "^7.18.9",
"@lottiefiles/react-lottie-player": "^3.5.3",
"@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",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"styled-components": "^5.3.10"
},
"scripts": {
"start": "react-scripts start",
19 changes: 14 additions & 5 deletions code/src/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import React from 'react'
import React from 'react';
import { Provider } from 'react-redux';
import { combineReducers, configureStore } from '@reduxjs/toolkit';
import { StartScreen } from 'components/StartScreen.js';
import game from 'reducers/game.js';

export const App = () => {
const reducer = combineReducers({
game: game.reducer
})

const store = configureStore({ reducer })
return (
<div>
Find me in src/app.js!
</div>
<Provider store={store}>
<StartScreen />
</Provider>
)
}
}
30 changes: 30 additions & 0 deletions code/src/components/Directions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// import React, { useState } from 'react'
// import { useSelector, useDispatch } from 'react-redux'
// import { actionsGame } from 'reducers/game.js'

// export const Directions = () => {
// const actions = useSelector((store) => store.game.actions)
// const [isActive, setActive] = useState('false')

// const dispatch = useDispatch()

// const toggleDisplay = () => {
// setActive(!isActive);
// }

// return (
// <>
// <button className={isActive ? null : 'instructions-btn'} type="button" onClick={toggleDisplay}>Click here to see directions</button>
// {actions.map((action) => {
// return (
// <div className={isActive ? 'hidden-instructions' : 'instructions'}>
// <p>{action.description}</p>
// <button type="button" onClick={() => dispatch(actionsGame(action.type, action.direction))}> Go {action.direction}</button>
// </div>
// )
// })}
// </>
// )
// }

// export default Directions
69 changes: 69 additions & 0 deletions code/src/components/GameContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { actionsGame } from 'reducers/game';
// import { Map } from './Map.js'

export const GameContent = () => {
const { actions, coordinates } = useSelector((store) => store.game.position)
// const { description, actions, coordinates } = useSelector((store) => store.game.position)
const dispatch = useDispatch()
const username = useSelector((store) => store.game.username)

const onDirectionBtnClick = (direction) => {
dispatch(actionsGame(direction))
}

const onRestartBtnClick = () => {

Choose a reason for hiding this comment

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

Good job with the restart button!

return (
window.location.reload()
)
}

return (
<div className="name-content-container">
<player>
<h2>{username}</h2>
<button type="button" onClick={onRestartBtnClick}>Restart game
</button>
</player>
<div className="game-container">
<div className="navigation-container">
<div className="actions-container">
{actions.map((singleAction) => (

Choose a reason for hiding this comment

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

I think singleAction should be a different colour if it is working, so perhaps something is wrong with singleAction - and that might be why your button click doesn’t load the next move….
Could it be something to do with line 7?

<section className="action-move">
<p>{singleAction.description}</p>
<button
// buttonText={`Go ${singleAction.direction}`}
type="button"
onClick={() => onDirectionBtnClick(singleAction.direction)}>Button
</button>
</section>
))}
</div>
</div>
{/* <Map coordinates={coordinates} /> */}
<p>coordinates={coordinates}</p>
</div>
</div>
)
}

/* const GameContent = () => {
const direction = useSelector((store) => store.game.direction)
const loadingState = useSelector((store) => store.loading.load)

if (loadingState) {
return (
<Loading />
)
}
return (
<div direction={direction}>
{direction === '' && <StartScreen />}
{direction !== '' && <GameScreen />}
</div>
)
}
*/

export default GameContent
53 changes: 53 additions & 0 deletions code/src/components/GameScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// import TypeIt from 'typeit-react';
import React, { useState } from 'react';
import game, { startGame } from 'reducers/game.js';
import { useDispatch } from 'react-redux';

export const GameScreen = () => {
const [userNameInputValue, setUserNameInputValue] = useState('')
const dispatch = useDispatch()

const onFormSubmit = (event) => {
event.preventDefault();
dispatch(game.actions.setUsername(userNameInputValue))
dispatch(startGame())
}

return (
<form onSubmit={(event) => onFormSubmit(event)}>
<h1>Please enter your name:
</h1>
<label htmlFor="username">
<input
id="username"
type="text"
placeholder="Please enter name"
value={userNameInputValue}
onChange={(event) => setUserNameInputValue(event.target.value)} />
<button type="submit" onClick={onFormSubmit}>Start the game</button>

Choose a reason for hiding this comment

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

Good job with this page - you got the game to start after entering a username!

</label>
</form>
)
}

// export const GameScreen = () => {
// const description = useSelector((store) => store.game.description)
// const direction = useSelector((store) => store.game.direction)
// const dispatch = useDispatch()

// const restart = () => {
// dispatch(game.actions.setUsername(''))
// window.location.reload()
// }
// return (
// <GameCard>
// <TypeIt>{description}</TypeIt>
// <FlexDiv>
// {direction !== '1,3' && <Directions />}
// <button className="restart-btn" type="button" onClick={restart}>Restart</button>
// </FlexDiv>
// </GameCard>
// )
// }

// export default GameScreen
43 changes: 43 additions & 0 deletions code/src/components/Loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// import { Player } from '@lottie-react';
import React from 'react';
// import { Player, Controls } from '@lottiefiles/react-lottie-player';
import { Player } from '@lottiefiles/react-lottie-player'

export const Loading = () => {
return (
<div className="loading-container">
<Player
autoplay
loop
src="https://assets2.lottiefiles.com/packages/lf20_rwbbf6ns.json">

Choose a reason for hiding this comment

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

Cool that you got the Lottie to work!

{/* {style={{ height: '150px', width: '150px' }} */}
{/* <Controls visible={false} buttons={['play', 'repeat', 'frame', 'debug']} /> */}
</Player>
</div>
)
}

// const Loading = () => {
// return (
// <div
// src="https://assets8.lottiefiles.com/packages/lf20_3e0g4gjg.json"
// className="Player"
// autoPlay
// speed={2}
// style={{ height: '300px', width: '300px' }} />
// )
// }

// export default Loading

// import React from 'react';
// import { Player } from '@lottiefiles/react-lottie-player';
// const Loading = () => (
// <Player
// autoplay
// loop
// src="https://assets10.lottiefiles.com/packages/lf20_q7uarxsb.json"
// style={{ height: '300px', width: '300px' }} />
// )

// export default Loading;
Empty file added code/src/components/Map.js
Empty file.
17 changes: 17 additions & 0 deletions code/src/components/StartScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { useSelector } from 'react-redux';
// import { Player } from '@lottiefiles/react-lottie-player';
import { Loading } from './Loading.js';
import { GameScreen } from './GameScreen.js';
import { GameContent } from './GameContent.js';

export const StartScreen = () => {
const isUserNameProvided = useSelector((store) => store.game.username)
const isLoading = useSelector((store) => store.game.loading)

return (
<div className="start-screen-container">
{isLoading ? <Loading /> : (<> {isUserNameProvided === '' ? <GameScreen /> : <GameContent />} </>)}
</div>
)
}
20 changes: 20 additions & 0 deletions code/src/components/StylesGlobal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// export const GlobalStyles = createGlobalStyle`
// `

// export const Outerwrapper = styled.div`
// width: 100%;
// height: 100%;
// display: flex;
// align-items:center;
// justify-content: center;
// background-size: cover;
// background-image: url(${(props) => (props.directions === '' ? Start : props.directions === '0,0' ? Zero : props.directions === '1,0' ? One : props.directions === '1,1' ? OneOne : props.directions === '0,1' ? ZeroOne : props.directions === '0,2' ? ZeroTwo : props.directions === '0,3' ? ZeroThree : props.directions === '1,3' ? OneThree : Start)})
// `

// export const Innerwrapper = styled.div`
// margin: 0 auto;
// width: 80%;
// height: 100%;
// display: flex;
// align-items: center;
// justify-content: center;
93 changes: 93 additions & 0 deletions code/src/reducers/game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { createSlice } from '@reduxjs/toolkit';
// import loading from './loading';

// const initialState = {
// username: '',
// // description: '',
// // direction: '',
// position: '',
// loading: false // should it be placed here?
// // actions: []
// }

const game = createSlice({
name: 'game',
initialState: {
username: '',
position: '',
loading: false
},
reducers: {
// an action to save the joke to global state
setUsername: (store, action) => {
store.username = action.payload;
},
setLoading: (store, action) => {
store.loading = action.payload;
},
setPosition: (store, action) => {
store.position = action.payload;
}
}
});

// a thunk to handle api call
// https://labyrinth.technigo.io/start
// https://labyrinth.technigo.io/action
// start game
export const startGame = () => {
return (dispatch, getState) => {
// set loading to true
// dispatch(loading.actions.setLoading(true))
dispatch(game.actions.setLoading(true))
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: getState().game.username
})
};
// what replaces jokes.category?
fetch('https://labyrinth.technigo.io/start', options)
.then((response) => response.json())
// below, json = data
.then((json) => {
console.log(json)
// get the data from the api - save it as the joke in global state
// set loading to false
dispatch(game.actions.setPosition(json))
})
.catch((error) => console.error(error))
.finally(() => dispatch(game.actions.setLoading(false)))
}
}
// export const actionsGame = (type, direction) => {

export const actionsGame = (direction) => {
return (dispatch, getState) => {
dispatch(game.actions.setLoading(true))
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: getState().loading.username,

Choose a reason for hiding this comment

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

Your console shows the problem "cannot read ‘username’"
Wondering if you could change this line to username: getState().game.username? Because ‘username’ is defined in your game reducer, not the loading reducer.

type: 'move',

Choose a reason for hiding this comment

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

I was told 'type' is the same throughout the labyrinth, so it isn't needed here. I wonder if it is doing anything though, because you haven't passed it in as an argument in line 68...

direction

Choose a reason for hiding this comment

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

It looks like this word ‘direction’ isn’t doing anything. I think if you change line 77 it might work. OR, it might work if you take out 'type', as this isn't doing anything since it's not being passed as an argument in line 68.

})
}
fetch('https://labyrinth.technigo.io/action', options)
.then((response) => response.json())
.then((json) => {
console.log(json)
dispatch(game.actions.setPosition(json))
})
.catch((error) => console.error(error))
.finally(() => dispatch(game.actions.setLoading(false)))
}
}

export default game
15 changes: 15 additions & 0 deletions code/src/reducers/loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// import { createSlice } from '@reduxjs/toolkit'

Choose a reason for hiding this comment

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

How come you decided not to use this as a separate reducer?


// export const loading = createSlice({
// name: 'loading',
// initialState: {
// load: false
// },
// reducers: {
// setLoading: (state, action) => {
// state.load = action.payload
// }
// }
// })

// export default loading