Skip to content

Commit

Permalink
feat(app-create-game): add navigation with game id
Browse files Browse the repository at this point in the history
  • Loading branch information
rams23 committed Jan 14, 2021
1 parent de21b18 commit 5c2566e
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 35 deletions.
2 changes: 1 addition & 1 deletion packages/game-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function App() {
<Suspense fallback={null}>
<Switch>
<PrivateRoute path={RoutingPath.Dashboard} component={Dashboard} />
<PrivateRoute path={RoutingPath.Game} component={GameView} />
<PrivateRoute path={`${RoutingPath.Game}/:id`} component={GameView} />
<PrivateRoute path={RoutingPath.CreateGame} component={CreateGameView} />
{renderAuthRoutes(user)}
</Switch>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Props = {
const StyledTextArea = styled.textarea`
border: 0;
border-radius: 10px;
resize: none;
`;

const TextArea: React.FC<Props> = ({ name, value, errorMessage, label, onChange, disabled }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { RoutingPath } from './routingPath';
* @param condition the condition to check
* @param route the route to go
*/
export default function useNavigateOnCondition(condition: boolean, route: RoutingPath) {
export default function useNavigateOnCondition(condition: boolean, route: RoutingPath | string) {
const [alreadyNavigated, setAlreadyNavigated] = useState<boolean>(false);

const history = useHistory();
Expand Down
5 changes: 3 additions & 2 deletions packages/game-app/src/createGame/apis/callCreateGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FirebaseCollections, Game } from '@pipeline/common';

const DEFAULT_DECK_ID = '7p5qqvE8kCV9WWysVc2n';

export default function callCreateGame(data: GameCreationData, userId: string) {
export default function callCreateGame(data: GameCreationData, userId: string): Promise<string> {
return firebase
.firestore()
.collection(FirebaseCollections.Games)
Expand All @@ -18,5 +18,6 @@ export default function callCreateGame(data: GameCreationData, userId: string) {
},
deckId: DEFAULT_DECK_ID,
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
} as Game);
} as Game)
.then(res => res.id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ type Props = {};
const CreateGameView: React.FC<Props> = () => {
const [selectedScenarioCard, setSelectedScenario] = useState<string | null>(null);

const selectScenario = useCallback((scenarioId: string) => {
setSelectedScenario(prevState => (scenarioId === prevState ? null : scenarioId));
}, []);
const t = useTranslate();

const methods = useForm<GameCreationData>({
defaultValues: {
Expand All @@ -32,11 +30,21 @@ const CreateGameView: React.FC<Props> = () => {
resolver: yupResolver(createGameValidationSchema),
});

const t = useTranslate();

const { handleSubmit } = methods;

const { call, success, loading, translatedError } = useCreateGame();
const { setValue, clearErrors } = methods;

const selectScenario = useCallback(
(scenarioId: string) => {
setSelectedScenario(prevState => (scenarioId === prevState ? null : scenarioId));
setValue('scenarioTitle', '');
setValue('scenarioContent', '');
clearErrors();
},
[setValue, clearErrors],
);

const { call, success, loading, translatedError, newCreatedId } = useCreateGame();

const { cards } = useCards(CardTypes.Scenario);

Expand All @@ -58,7 +66,7 @@ const CreateGameView: React.FC<Props> = () => {

const history = useHistory();

useNavigateOnCondition(success, RoutingPath.Game);
useNavigateOnCondition(success, `${RoutingPath.Game}/${newCreatedId}`);

const cancel = useCallback(() => {
history.replace(RoutingPath.Dashboard);
Expand Down Expand Up @@ -92,7 +100,7 @@ const CreateGameView: React.FC<Props> = () => {
{translatedError && <span className="error-message">{translatedError}</span>}
</div>
<div className="text-center">
<Link onClick={cancel}>{t('createGame.createButtonText')}</Link>
<Link onClick={cancel}>{t('general.cancel')}</Link>
</div>
</div>
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const Wrapper = styled.div`
flex-direction: row;
padding: 5px;
overflow-x: scroll;
overflow-y: hidden;
height: 433px;
padding-top: 20px;
::-webkit-scrollbar {
height: 6px;
Expand All @@ -36,12 +36,14 @@ const ScenariosList: React.FC<Props> = ({ cards, onScenarioSelected, selectedSce

return (
<Wrapper>
{cards.map((value, index) => (
{cards.map((card, index) => (
<SelectableScenario
title={value.title}
content={value.content}
key={card.id}
id={card.id}
title={card.title}
content={card.content}
onClick={callbacks[index]}
selected={selectedScenario === value.id}
selected={selectedScenario === card.id}
/>
))}
</Wrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@ import React from 'react';
import styled from 'styled-components';

type Props = {
id: string;
title: string;
content: string;
selected: boolean;
onClick: () => void;
};

const ScenarioCard = styled.div<{ selected: boolean }>(({ selected }) => ({
minWidth: '400px',
height: '408px',
background: 'white',
borderRadius: '10px',
backdropFilter: 'blur(20px)',
padding: selected ? '22px' : '24px',
marginRight: '20px',
boxSizing: 'border-box',
border: selected ? '2px solid #00867C' : '',
}));
const ScenarioCard = styled.div<{ selected: boolean }>`
min-width: 400px;
height: 408px;
background: white;
border-radius: 10px;
backdrop-filter: blur(20px);
padding: ${({ selected }) => (selected ? '22px' : '24px')};
margin-right: 20px;
box-sizing: border-box;
border: ${({ selected }) => (selected ? '2px solid #00867C' : '')};
transition: transform 0.5s;
&:hover {
transform: translate(0, -20px);
}
`;
const ScenarioTitle = styled.h5({
fontSize: '20px',
fontWeight: 'bold',
Expand All @@ -37,9 +42,9 @@ const ScenarioContent = styled.div({
lineHeight: '22px',
});

const SelectableScenario: React.FC<Props> = ({ title, content, selected, onClick }) => {
const SelectableScenario: React.FC<Props> = ({ id, title, content, selected, onClick }) => {
return (
<ScenarioCard selected={selected} onClick={onClick}>
<ScenarioCard id={`scenario-${id}`} selected={selected} onClick={onClick}>
<ScenarioTitle>{title}</ScenarioTitle>
<ScenarioContent>{content}</ScenarioContent>
</ScenarioCard>
Expand Down
15 changes: 13 additions & 2 deletions packages/game-app/src/createGame/hook/useCreateGame.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { createRequestHook } from '@pipeline/requests-status';
import * as actions from '../actions';
import { useSelector } from 'react-redux';
import { selectors } from '../../gameView/slice';

const useCreateGame = createRequestHook('createGame', actions.createGame);
const _useCreateGame = createRequestHook('createGame', actions.createGame);

export default useCreateGame;
export default function useCreateGame() {
const request = _useCreateGame();

const newCreatedId = useSelector(selectors.getSelectedGameId);

return {
...request,
newCreatedId,
};
}
6 changes: 4 additions & 2 deletions packages/game-app/src/createGame/sagas/createGame.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { call, select, takeEvery } from 'redux-saga/effects';
import { call, put, select, takeEvery } from 'redux-saga/effects';
import * as actions from '../actions';
import { addRequestStatusManagement } from '@pipeline/requests-status';
import callCreateGame from '../apis/callCreateGame';
import { actions as gameActions } from '../../gameView/slice';
import { AuthUser, selectors as authSelectors } from '@pipeline/auth';

function* executeCreateGame(action: ReturnType<typeof actions.createGame>) {
const user: AuthUser = yield select(authSelectors.getCurrentUser);
yield call(callCreateGame, action.payload, user.id);
const newGameId: string = yield call(callCreateGame, action.payload, user.id);
yield put(gameActions.setSelectedGameId(newGameId));
}

export default function* createGameSaga() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Dashboard: React.FC<Props> = () => {
<button type="button" className="primary test-game" onClick={() => history.push(RoutingPath.CreateGame)}>
{t('dashboard.newGameLabel')}
</button>
<button type="button" className="link test-game" onClick={() => history.push(RoutingPath.Game)}>
<button type="button" className="link test-game" onClick={() => history.push(`${RoutingPath.Game}/test-id`)}>
Game board test
</button>
</div>
Expand Down
8 changes: 8 additions & 0 deletions packages/game-app/src/gameView/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import { CardEntity } from '@pipeline/common';

export interface State {
cards: EntityState<CardEntity>;
selectedGameId: string | null;
}

const adapter = createEntityAdapter<CardEntity>();

const initialState = {
cards: adapter.getInitialState(),
selectedGameId: null,
} as State;

const slice = createSlice({
Expand All @@ -25,6 +27,9 @@ const slice = createSlice({
saveCards(state, action: PayloadAction<CardEntity[]>) {
state.cards = adapter.addMany(state.cards, action.payload);
},
setSelectedGameId(state, action: PayloadAction<string>) {
state.selectedGameId = action.payload;
},
},
});

Expand All @@ -37,6 +42,8 @@ const getSlice = createSelector(

const getAllCards = createSelector(getSlice, slice => cardsEntitiesSelectors.selectAll(slice.cards));

const getSelectedGameId = createSelector(getSlice, slice => slice.selectedGameId);

export const reducer = slice.reducer;
export const name = slice.name;

Expand All @@ -47,4 +54,5 @@ export const actions = {

export const selectors = {
getAllCards,
getSelectedGameId,
};
2 changes: 2 additions & 0 deletions packages/game-app/src/temporary.css
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ input + button.icon-button {
display: inline-block;
z-index: 100;
padding: 15px;
box-sizing: border-box;
border: 1px solid black;
}

.draggable {
Expand Down

0 comments on commit 5c2566e

Please sign in to comment.