-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: new library and login related components
• Extracted login/register modal component from login button. • Extracted AddToLibraryButton from GameProfile • Moved the game search drop list from components to pages (as the homepage). • Moved logged in state to top level. • Added functionality to render list of games in Library page. • Fixed some async/rerender errors when logging in and out. • Pending to lift the state up in Library and AddToLibraryButton (needs some backend refactoring).
- Loading branch information
Showing
15 changed files
with
278 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
import { useHistory } from 'react-router-dom'; | ||
import { useMutation, useQuery } from '@apollo/client'; | ||
import { GET_LIBRARY_IDS } from '../graphql/queries'; | ||
import TooltipButton from '../components/TooltipButton'; | ||
import { FaPlusCircle, FaBook } from 'react-icons/fa'; | ||
import { ADD_TO_LIBRARY } from '../graphql/mutations'; | ||
import { GameInUserLibrary, libraryIdsResponse } from '../types'; | ||
|
||
const AddToLibraryButton = ({ gameId }: { gameId: string }) => { | ||
const history = useHistory(); | ||
|
||
const { data: library } = useQuery(GET_LIBRARY_IDS, { | ||
onError: (err) => console.log(err), | ||
}); | ||
|
||
const isGameInLibrary: boolean = library?.getLibraryIds.find( | ||
(game: GameInUserLibrary) => game.igdb_game_id === parseInt(gameId) | ||
) | ||
? true | ||
: false; | ||
|
||
const [ | ||
addGameToLibrary, | ||
{ loading: addingToLibrary, error: libraryError }, | ||
] = useMutation(ADD_TO_LIBRARY, { | ||
variables: { gameId: parseInt(gameId) }, | ||
// refetchQueries: [{ query: GET_LIBRARY_IDS }], | ||
// awaitRefetchQueries: true, | ||
|
||
// I use update instead of refetchQueries for optimization. | ||
// This way we can manually update the cache instead of refetching the query. | ||
update: (store, response) => { | ||
try { | ||
const dataInStore: libraryIdsResponse | null = store.readQuery({ | ||
query: GET_LIBRARY_IDS, | ||
}); | ||
|
||
store.writeQuery({ | ||
query: GET_LIBRARY_IDS, | ||
data: { | ||
...dataInStore, | ||
getLibraryIds: dataInStore | ||
? [...dataInStore.getLibraryIds, response.data.addGameToLibrary] | ||
: [response.data.addGameToLibrary], | ||
}, | ||
}); | ||
} catch (err) { | ||
console.log(`Error updating the cache after addGameToLibrary query: ${err}`); | ||
} | ||
}, | ||
onError: (err) => console.log(`Error adding game to library: ${err}`) | ||
}); | ||
|
||
return ( | ||
<div> | ||
{isGameInLibrary ? ( | ||
<TooltipButton | ||
label='In library' | ||
onClick={() => history.push('/library')} | ||
icon={<FaBook />} | ||
isLoading={false} | ||
/> | ||
) : ( | ||
<TooltipButton | ||
label='Add to library' | ||
onClick={addGameToLibrary} | ||
icon={<FaPlusCircle />} | ||
isLoading={addingToLibrary} | ||
isError={libraryError ? true : false} | ||
errorMessage={libraryError?.message} | ||
/> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default AddToLibraryButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
|
||
import { useMutation } from '@apollo/client'; | ||
import { LOGIN, REGISTER_NEW_USER } from '../graphql/mutations'; | ||
|
||
import { capitalizeFirstLetter } from '../utils/misc'; | ||
import { LoginDetails, LoginOrRegisterModalProps } from '../types'; | ||
|
||
import { CircleButton } from './styledComponentsLibrary'; | ||
import LoginForm from '../components/LoginForm'; | ||
import { Dialog } from '@reach/dialog'; | ||
import { CURRENT_USER } from '../graphql/queries'; | ||
|
||
const LoginRegisterModal = ({ | ||
loginOrRegister, | ||
setOpenModal, | ||
openModal, | ||
}: LoginOrRegisterModalProps) => { | ||
const [registerNewUser, { loading: registerLoading }] = useMutation( | ||
REGISTER_NEW_USER, | ||
{ | ||
onCompleted: (result) => { | ||
console.log(result); | ||
setOpenModal('none'); | ||
}, | ||
onError: (err) => { | ||
console.log(err.message); | ||
}, | ||
refetchQueries: [{ query: CURRENT_USER }], | ||
} | ||
); | ||
|
||
const [login, { loading: loginLoading }] = useMutation(LOGIN, { | ||
onCompleted: (result) => { | ||
console.log('login result: ', result); | ||
setOpenModal('none'); | ||
}, | ||
onError: (err) => { | ||
console.log('login error:', err.message); | ||
}, | ||
refetchQueries: [{ query: CURRENT_USER }], | ||
}); | ||
|
||
const submitLogin = async (data: LoginDetails) => { | ||
login({ variables: { email: data.email, password: data.password } }); | ||
}; | ||
|
||
const submitRegistration = (data: LoginDetails) => { | ||
registerNewUser({ | ||
variables: { email: data.email, password: data.password }, | ||
}); | ||
}; | ||
|
||
const ariaLabel = | ||
loginOrRegister === 'login' ? 'Login form' : 'Registration form'; | ||
const handleSubmit = | ||
loginOrRegister === 'login' ? submitLogin : submitRegistration; | ||
const loading = loginOrRegister === 'login' ? loginLoading : registerLoading; | ||
|
||
return ( | ||
<Dialog | ||
aria-label={ariaLabel} | ||
isOpen={openModal === loginOrRegister} | ||
css={{ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
':click': { | ||
transition: 'transform 0.3s', | ||
transitionDuration: '0.3s', | ||
transitionTimingFunction: 'ease', | ||
transitionProperty: 'all', | ||
}, | ||
}} | ||
> | ||
<div css={{ alignSelf: 'flex-end' }}> | ||
<CircleButton onClick={() => setOpenModal('none')}>x</CircleButton> | ||
</div> | ||
<h3>{capitalizeFirstLetter(loginOrRegister)}</h3> | ||
<LoginForm | ||
onSubmit={handleSubmit} | ||
buttonLabel={capitalizeFirstLetter(loginOrRegister)} | ||
loading={loading} | ||
/> | ||
</Dialog> | ||
); | ||
}; | ||
|
||
export default LoginRegisterModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.