diff --git a/src/Admin/Components/Components/Inputs/EditItem/EditItem.js b/src/Admin/Components/Components/Inputs/EditItem/EditItem.js index ed31960cf7670d9a7ca1d50ae49367f4d81e3686..08a0ba24f28d6ca47526572cbd64db6c71572c6a 100644 --- a/src/Admin/Components/Components/Inputs/EditItem/EditItem.js +++ b/src/Admin/Components/Components/Inputs/EditItem/EditItem.js @@ -189,7 +189,7 @@ const EditItem = ({ match }) => { "state": itemState, "item_type": itemType, "achievement_id": parseInt(achievementID), - "image" : image + "image": image } } putRequest( @@ -199,6 +199,8 @@ const EditItem = ({ match }) => { if (data.id) HandleSnack('O item foi alterado com sucesso!', true, 'success', '#228B22') else { + if (!data) + HandleSnack(`Erro com servidor interno!`, true, 'warning', '#FA8072') if (data.errors) { HandleSnack(`${data.errors[0]}`, true, 'warning', '#FA8072') } diff --git a/src/Components/HelperFunctions/getAxiosConfig.js b/src/Components/HelperFunctions/getAxiosConfig.js index 15a461129312976a379c9c5e81a16da611b611b1..80f46b73263c8ffa7f9f136d00bcb2e637ced6eb 100644 --- a/src/Components/HelperFunctions/getAxiosConfig.js +++ b/src/Components/HelperFunctions/getAxiosConfig.js @@ -1,13 +1,13 @@ -import {apiUrl} from '../../env.js' +import { apiUrl } from '../../env.js' -export function getAxiosConfigFromJSON () { +export function getAxiosConfigFromJSON() { let config = { - headers : JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) + headers: JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) } return config } -export function updateHeaders (newHeaders) { +export function updateHeaders(newHeaders) { sessionStorage.setItem('@portalmec/accessToken', newHeaders['access-token']) @@ -27,7 +27,7 @@ export function updateHeaders (newHeaders) { sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) } -function fetchHeaders () { +function fetchHeaders() { let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers')) if (auth_headers) { @@ -39,7 +39,7 @@ function fetchHeaders () { } } -function checkPreviousTokens (new_token) { +function checkPreviousTokens(new_token) { let prev_tokens = JSON.parse(sessionStorage.getItem('@portalmec/tokens')) @@ -62,7 +62,7 @@ function checkPreviousTokens (new_token) { } -function updateAccessToken (newAccessToken) { +function updateAccessToken(newAccessToken) { if (checkPreviousTokens(newAccessToken)) { @@ -78,9 +78,10 @@ function updateAccessToken (newAccessToken) { } } -export async function getRequest (url, onSuccess, onError) { +export async function getRequest(url, onSuccess, onError) { let response = await fetch((`${apiUrl}${url}`), { - headers : fetchHeaders() + method: 'GET', + headers: fetchHeaders() }) if (response.ok) { if (response.headers.has('access-token')) { @@ -93,30 +94,30 @@ export async function getRequest (url, onSuccess, onError) { else { onError(response.error) } - // .then(response => { - // if (response.headers.has('access-token')) { - // updateAccessToken(response.headers.get('access-token')) - // } - // let json = await response.json() - // - // onSuccess(json) - // - // return response.json().catch(err => { - // return {}; - // }) - // }) - // .then(data => { - // onSuccess(data) - // }) - // .catch(error => { - // onError(error) - // }) + // .then(response => { + // if (response.headers.has('access-token')) { + // updateAccessToken(response.headers.get('access-token')) + // } + // let json = await response.json() + // + // onSuccess(json) + // + // return response.json().catch(err => { + // return {}; + // }) + // }) + // .then(data => { + // onSuccess(data) + // }) + // .catch(error => { + // onError(error) + // }) } export const deleteRequest = (url, onSuccess, onError) => { fetch((`${apiUrl}${url}`), { - method : 'DELETE', - headers : fetchHeaders() + method: 'DELETE', + headers: fetchHeaders() }) .then(response => { if (response.headers.has('access-token')) { @@ -141,8 +142,8 @@ export const putRequest = (url, payload, onSuccess, onError) => { } fetch((`${apiUrl}${url}`), { - method : 'PUT', - headers : newHeaders, + method: 'PUT', + headers: newHeaders, body: payload instanceof FormData ? payload : JSON.stringify(payload) }) .then(response => { @@ -171,8 +172,8 @@ export const postRequest = (url, payload, onSuccess, onError) => { } fetch((`${apiUrl}${url}`), { - method : 'POST', - headers : newHeaders, + method: 'POST', + headers: newHeaders, body: payload instanceof FormData ? payload : JSON.stringify(payload) }) .then(response => { @@ -191,9 +192,9 @@ export const postRequest = (url, payload, onSuccess, onError) => { }) } -export async function fetchAllRequest (urls, onSuccess, onError) { - let responses = await Promise.all( urls.map( url => fetch(`${apiUrl}${url}`, { - headers : fetchHeaders() +export async function fetchAllRequest(urls, onSuccess, onError) { + let responses = await Promise.all(urls.map(url => fetch(`${apiUrl}${url}`, { + headers: fetchHeaders() }))) console.log(responses) @@ -236,8 +237,8 @@ export const validateGoogleLoginToken = (url, config, onSuccess, onError) => { fetch((`${apiUrl}${url}`), { - method : 'GET', - headers : newHeaders + method: 'GET', + headers: newHeaders }) .then(response => { const auth_headers = { @@ -263,14 +264,14 @@ export const validateGoogleLoginToken = (url, config, onSuccess, onError) => { }) } -export async function authentication (url, payload, onSuccess, onError) { +export async function authentication(url, payload, onSuccess, onError) { let formData = new FormData() for (const [key, value] of Object.entries(payload)) { - formData.append(`${key}`,value); + formData.append(`${key}`, value); } let response = await fetch((`${apiUrl}${url}`), { - method : 'POST', + method: 'POST', body: formData }) if (response.ok) { @@ -293,27 +294,27 @@ export async function authentication (url, payload, onSuccess, onError) { else { onError(response.error) } - // .then(response => { - // const auth_headers = { - // client: response.headers.get('client'), - // "access-token": response.headers.get('access-token'), - // uid: response.headers.get('uid'), - // expiry: response.headers.get('expiry'), - // "token-type": "Bearer" - // } - // - // sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) - // - // return response.json().catch(err => { - // return {}; - // }) - // }) - // .then(data => { - // console.log(data) - // onSuccess(data) - // }) - // .catch(error => { - // onError(error) - // }) + // .then(response => { + // const auth_headers = { + // client: response.headers.get('client'), + // "access-token": response.headers.get('access-token'), + // uid: response.headers.get('uid'), + // expiry: response.headers.get('expiry'), + // "token-type": "Bearer" + // } + // + // sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers)) + // + // return response.json().catch(err => { + // return {}; + // }) + // }) + // .then(data => { + // console.log(data) + // onSuccess(data) + // }) + // .catch(error => { + // onError(error) + // }) } diff --git a/src/Components/ItemCard.js b/src/Components/ItemCard.js index f181cb9bb9e7335d03ac04e0c02d972b9fc2a50a..39943f03576fda6cd9ff43b66517e925f3eb8d0a 100644 --- a/src/Components/ItemCard.js +++ b/src/Components/ItemCard.js @@ -21,6 +21,7 @@ import Grid from '@material-ui/core/Grid'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import ItemCardAction from './ItemCardAction.js'; +import Rubi from '../img/gamification/gem.svg'; import { apiDomain } from '../env' const ItemImage = styled.img` @@ -48,6 +49,27 @@ const ItemDescription = styled.p` font-size: 0.5em; color: #666666; ` +const ItemPrice = styled.p` + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + font-size: 0.6em; + font-weight: bold; + color: #666666; +` + +const CoinsSpan = styled.span` + color: red; + font-size: 16px; + margin-left: 3px; +`; + +const GemImg = styled.img` + height: 23px; + vertical-align : middle; + margin-bottom : 6px; +`; export default function ItemCard(props) { @@ -58,7 +80,19 @@ export default function ItemCard(props) { <ItemImage src={apiDomain + props.src} /> <ItemName>{props.name}</ItemName> <ItemDescription>{props.description}</ItemDescription> - <ItemCardAction operation={props.action} /> + <ItemPrice> + Preço: {props.price} - + <span> {props.discount} = </span> + <GemImg src={Rubi} /> + <CoinsSpan>{props.price - props.discount} </CoinsSpan> + </ItemPrice> + <ItemCardAction + operation={props.action} + itemId={props.itemId} + name={props.name} + totalPrice={props.price - props.discount} + myQntOfPoints={props.myQntOfPoints} + /> </CardContent> </Card> </Grid> diff --git a/src/Components/ItemCardAction.js b/src/Components/ItemCardAction.js index ed1cc7dde66752bb622375c25b65172ab3d42e92..474ac5e2e1bdfe18dd1d80435385b6b831a4edd2 100644 --- a/src/Components/ItemCardAction.js +++ b/src/Components/ItemCardAction.js @@ -15,7 +15,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>.*/ -import React, {useState} from 'react'; +import React, { useState, useContext } from 'react'; import styled from 'styled-components'; import Snackbar from '@material-ui/core/Snackbar'; import MuiAlert from '@material-ui/lab/Alert'; @@ -26,11 +26,11 @@ import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import DialogContentText from '@material-ui/core/DialogContentText'; import DialogTitle from '@material-ui/core/DialogTitle'; -import axios from 'axios' -import {apiUrl} from '../env'; +import { Store } from '../Store' +import { postRequest } from './HelperFunctions/getAxiosConfig' function Alert(props) { - return <MuiAlert elevation={6} variant="filled" {...props} />; + return <MuiAlert elevation={6} variant="filled" {...props} />; } const actionStyle = (operation) => { @@ -50,61 +50,50 @@ const GemImg = styled.img` position: relative; top: 8px; padding-right: 5px; + padding-left: 5px; + padding-bottom: 4px; ` const GemSpan = styled.span` color: red; ` -export default function ItemCardAction (props) { - const [success, setSuccess] = useState(false); - const [failure, setFailure] = useState(false); - const [message, setMessage] = useState(""); - const [info, setInfo] = useState(false); - // eslint-disable-next-line - const [item_id, setItemID] = useState(0); - const [last_operation, setLastOperation] = useState(); +export default function ItemCardAction(props) { + const { state } = useContext(Store) const [open_dialog, setOpenDialog] = useState(false); - - - const revertLastOperation = () => { - manageItemAndShowSnackbar(last_operation === 'equip' ? 'unequip' : 'equip', - setInfo, - nonPurchaseMessage, - 'Erro'); - } - - const nonPurchaseMessage = <span>Item {last_operation === 'equip' ? 'retirado' : 'equipado'}. <div onClick={revertLastOperation}>Desfazer</div></span>; - - - const handleClose = (snackbar) => { - if (snackbar === 'success') - setSuccess(false); - else if (snackbar === 'info') - setInfo(false); - else - setFailure(false); + const [snack, setSnack] = useState({ + open: false, + message: "", + icon: "", + }) + + const handleSnackbar = (open, message, icon) => { + setSnack({ + open: open, + message: message, + icon: icon + }) } - const manageItemAndShowSnackbar = (operation, setSnackbar, successMessage, failureMessage) => { - axios.patch(apiUrl + '/users/' + operation + '_item?id=' + item_id).then( - response => { - if (response.status === 200) { - setSnackbar(true); - setMessage(successMessage); - } else { - setFailure(true); - setMessage(failureMessage); - } + const manageItemAndShowSnackbar = () => { + postRequest( + "/users/purchase_item", + { "item_id": props.itemId }, + (data, header) => { + if (data.error) + handleSnackbar(true, data.error, 'error') + else + handleSnackbar(true, 'Item comprado com sucesso', 'success') + }, + (error) => { + handleSnackbar(true, 'Ocorreu algum erro', 'error') } - ); - setLastOperation(operation === 'purchase' ? last_operation : (operation === 'equip' ? 'unequip' : 'equip')); + ) } - + const handleClickBuyItem = () => { - setOpenDialog(false); - manageItemAndShowSnackbar('purchase', setSuccess, <span>Item comprado.</span>, - <span>Compra falhou. Tente novamente</span>); + setOpenDialog(false); + manageItemAndShowSnackbar(); } const handleDialogClose = () => { @@ -112,65 +101,50 @@ export default function ItemCardAction (props) { } const handleClick = () => { - // this will become an axios get - if (props.operation === 'unequip') - manageItemAndShowSnackbar('unequip', setInfo, nonPurchaseMessage, 'Erro'); - else if (props.operation === 'equip') - manageItemAndShowSnackbar('equip', setInfo, nonPurchaseMessage, 'Erro'); - else if (props.operation === 'buy') { + if (state.currentUser.id) setOpenDialog(true); - } + else + handleSnackbar(true, 'Você precisa estar logado para fazer uma compra na nossa loja', 'warning') } return ( <div> - <Snackbar open={info} autoHideDuration={6000} onClose={() => handleClose('info')}> - <Alert onClose={handleClose} severity="info"> - {message} - </Alert> - </Snackbar> - <Snackbar open={success} autoHideDuration={6000} onClose={() => handleClose('success')}> - <Alert onClose={handleClose} severity="success"> - {message} - </Alert> - </Snackbar> - <Snackbar open={failure} autoHideDuration={6000} onClose={() => handleClose('failure')}> - <Alert onClose={handleClose} severity="error"> - {message} - </Alert> - </Snackbar> + <Snackbar open={snack.open} autoHideDuration={6000} onClose={handleSnackbar.bind(null, false, '', '')}> + <Alert onClose={handleSnackbar.bind(null, false, '', '')} severity={snack.icon}> + {snack.message} + </Alert> + </Snackbar> <span style={actionStyle(props.operation)} onClick={handleClick}> - {props.operation === 'buy' ? <GemImg src={gem}/> : <span/>} - {props.operation === 'buy' ? "COMPRAR" : - props.operation === 'equip' ? "USAR" : "TIRAR"} + <GemImg src={gem} /><span /> + Comprar </span> <Dialog - open={open_dialog} - onClose={handleClose} - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - > - <DialogTitle id="alert-dialog-title">{"Deseja realmente comprar este item?"}</DialogTitle> - <DialogContent> - <DialogContentText id="alert-dialog-description"> + open={open_dialog} + onClose={handleDialogClose} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + <DialogTitle id="alert-dialog-title">{"Deseja realmente comprar este item?"}</DialogTitle> + <DialogContent> + <DialogContentText id="alert-dialog-description"> <strong>Esta compra não envolve nenhum dinheiro real.</strong> - <br/><br/>O item que você deseja comprar, <strong>NOME DO ITEM</strong>, custa - <GemImg src={gem}/><GemSpan>PREÇO</GemSpan> gemas. Você possui - <GemImg src={gem}/><GemSpan><strong>GEMAS</strong></GemSpan> gemas. + <br /><br />O item que você deseja comprar, <strong>{props.name}</strong>, custa + <GemImg src={gem} /><GemSpan>{props.totalPrice}</GemSpan> gemas. Você possui + <GemImg src={gem} /><GemSpan><strong>{props.myQntOfPoints}</strong></GemSpan> gemas. - <br/><br/>Comprar este item lhe deixará com <GemImg src={gem}/><GemSpan><strong>TANTAS</strong></GemSpan> gemas. + <br /><br />Comprar este item lhe deixará com <GemImg src={gem} /><GemSpan><strong>{props.myQntOfPoints - props.totalPrice}</strong></GemSpan> gemas. </DialogContentText> - </DialogContent> - <DialogActions> - <Button onClick={handleDialogClose} color="primary"> - Cancelar + </DialogContent> + <DialogActions> + <Button onClick={handleDialogClose} color="primary"> + Cancelar </Button> - <Button onClick={handleClickBuyItem} color="primary" autoFocus> - Comprar + <Button onClick={handleClickBuyItem} color="primary" autoFocus> + Comprar </Button> - </DialogActions> - </Dialog> + </DialogActions> + </Dialog> </div> ) } diff --git a/src/Components/ItemCarousel.js b/src/Components/ItemCarousel.js index 625966e9fb317b9859d753f03e93b1dad0293efc..be2f7e667c872933ede3c1391fb51f33dc9fa82b 100644 --- a/src/Components/ItemCarousel.js +++ b/src/Components/ItemCarousel.js @@ -49,7 +49,8 @@ export default function ItemCarousel(props) { const goRight = () => { if (right === props.items.length - 2) - props.setCurrPage() + if (!props.stop) + props.setCurrPage() setRight(right === props.items.length - 1 ? 0 : right + 1); setLeft(left === props.items.length - 1 ? 0 : left + 1); } @@ -70,10 +71,17 @@ export default function ItemCarousel(props) { : props.items.slice(left, right) ).map((i) => { return <ItemCard + key={new Date().toISOString + i.id} + itemId={i.id} src={i.image} action={i.action} name={i.name} - description={i.description} /> + description={i.description} + price={i.price} + discount={i.discount} + myQntOfPoints={props.myQntOfPoints} + action={'buy'} + /> })} <IconButton onClick={goRight} disabled={props.disabled}> <ArrowForwardIcon /> diff --git a/src/Pages/ItemStore.js b/src/Pages/ItemStore.js index 8c4d91200967b3942368ccaa36b82592092533ed..caea1641caa91f50ae97eb48c029d5fa1289f590 100644 --- a/src/Pages/ItemStore.js +++ b/src/Pages/ItemStore.js @@ -34,6 +34,11 @@ const SectionTitle = styled.h3` margin-bottom: 0; ` +const ErrorTextCenter = styled.h3` + font-weight: 100; + margin-bottom: 0; +` + const StoreDivider = styled.hr` width: 50px; margin-left: 0; @@ -48,11 +53,30 @@ const StoreSection = styled.div` export default function ItemStoreContainer(props) { const { state } = useContext(Store); + const [badges, setBadges] = useState([]); const [avatar_frames, setAvatarFrames] = useState([]); const [card_frames, setCardFrames] = useState([]); const [cover_frames, setCoverFrames] = useState([]); - const [badges, setBadges] = useState([]); - const [disabled, setDisabled] = useState(false) + + const [totalBadges, setTotalBadges] = useState(0) + const [totalAvatarFrame, setTotalAvatarFrame] = useState(0) + const [totalCoverFrame, setTotalCoverFrame] = useState(0) + const [totalCardFrame, setTotalCardFrame] = useState(0) + + const [errInBadge, setErrInBadge] = useState(false) + const [errInAvatarFrame, setErrInAvatarFrame] = useState(false) + const [errInCoverFrame, setErrInCoverFrame] = useState(false) + const [errInCardFrame, setErrInCardFrame] = useState(false) + + const [disabledBadges, setDisabledBadges] = useState(false) + const [disabledAvatarFrame, setDisabledAvatarFrame] = useState(false) + const [disabledCoverFrame, setDisabledCoverFrame] = useState(false) + const [disabledCardFrame, setDisabledCardFrame] = useState(false) + + const [stopLoadingBadges, setStopLoadingBadges] = useState(false) + const [stopLoadingAvatarFrame, setStopLoadingAvatarFrame] = useState(false) + const [stopLoadingCoverFrame, setStopLoadingCoverFrame] = useState(false) + const [stopLoadingCardFrame, setStopLoadingCardFrame] = useState(false) const [currUser, setCurrUser] = useState({}); const [isLoading, setIsLoading] = useState(true); @@ -62,7 +86,7 @@ export default function ItemStoreContainer(props) { const [currCardFramePage, setCurrCardFramePage] = useState(0) const buildUrl = (objType, page) => { - return `/items?item_type=${objType}&page=${page}&range=[0,9]&results_per_page=10&sort=["id","DESC"]` + return `/items?filter={"state" : "active"}&item_type=${objType}&unlock_rule=purchase&page=${page}&range=[0,9]&results_per_page=10&sort=["id","DESC"]` } useEffect(() => { @@ -79,55 +103,73 @@ export default function ItemStoreContainer(props) { }, [state.currentUser.id]) useEffect(() => { - setDisabled(true) + setDisabledBadges(true) getRequest( buildUrl("badge", currBadgePage), (data, header) => { + if (data.length === 0) + setStopLoadingBadges(true) + if (header.has('X-Total-Count')) + setTotalBadges(header.get('X-Total-Count')) setBadges((previous) => previous.concat(data)) - setDisabled(false) + setDisabledBadges(false) }, (error) => { - + setErrInBadge(true) } ) }, [currBadgePage]) useEffect(() => { - setDisabled(true) + setDisabledAvatarFrame(true) getRequest( - buildUrl("avatar_frame", currBadgePage), + buildUrl("avatar_frame", currAvatarFramePage), (data, header) => { + if (data.length === 0) + setStopLoadingAvatarFrame(true) + if (header.has('X-Total-Count')) + setTotalAvatarFrame(header.get('X-Total-Count')) setAvatarFrames((previous) => previous.concat(data)) - setDisabled(false) + setDisabledAvatarFrame(false) }, (error) => { - + setErrInAvatarFrame(true) } ) }, [currAvatarFramePage]) useEffect(() => { - setDisabled(true) + setDisabledCoverFrame(true) getRequest( - buildUrl("cover_frame", currBadgePage), + buildUrl("cover_frame", currCoverFramePage), (data, header) => { + if (data.length === 0) + setStopLoadingCoverFrame(true) + if (header.has('X-Total-Count')) + setTotalCoverFrame(header.get('X-Total-Count')) setCoverFrames((previous) => previous.concat(data)) - setDisabled(false) + setDisabledCoverFrame(false) }, (error) => { + setErrInCoverFrame(true) } ) }, [currCoverFramePage]) useEffect(() => { - setDisabled(true) + setDisabledCardFrame(true) getRequest( - buildUrl("card_frame", currBadgePage), + buildUrl("card_frame", currCardFramePage), (data, header) => { + if (data.length === 0) + setStopLoadingCardFrame(true) + if (header.has('X-Total-Count')) + setTotalCardFrame(header.get('X-Total-Count')) setCardFrames((previous) => previous.concat(data)) - setDisabled(false) + setDisabledCardFrame(false) }, (error) => { + setErrInCardFrame(true) } ) }, [currCardFramePage]) @@ -162,45 +204,81 @@ export default function ItemStoreContainer(props) { <StoreGuide /> </Grid> - <StoreSection> - <SectionTitle>Insígnias</SectionTitle> - <StoreDivider /> - <ItemCarousel - items={badges} - setCurrPage={() => { setCurrBadgePage(currBadgePage + 1) }} - disabled={disabled} - /> - </StoreSection> - - <StoreSection> - <SectionTitle>Moldura de card de usuário</SectionTitle> - <StoreDivider /> - <ItemCarousel - items={card_frames} - setCurrPage={() => { setCurrCardFramePage(currCardFramePage + 1) }} - disabled={disabled} - /> - </StoreSection> - - <StoreSection> - <SectionTitle>Moldura de avatar</SectionTitle> - <StoreDivider /> - <ItemCarousel - items={avatar_frames} - setCurrPage={() => { setCurrAvatarFramePage(currAvatarFramePage + 1) }} - disabled={disabled} - /> - </StoreSection> - - <StoreSection> - <SectionTitle>Moldura de capa</SectionTitle> - <StoreDivider /> - <ItemCarousel - items={cover_frames} - setCurrPage={() => { setCurrCoverFramePage(currCoverFramePage + 1) }} - disabled={disabled} - /> - </StoreSection> + { + errInBadge ? + <ErrorTextCenter> + Erro ao carregar as insígnias + </ErrorTextCenter> + : + <StoreSection> + <SectionTitle>Insígnias ({totalBadges})</SectionTitle> + <StoreDivider /> + <ItemCarousel + items={badges} + setCurrPage={() => { setCurrBadgePage(currBadgePage + 1) }} + disabled={disabledBadges} + stop={stopLoadingBadges} + myQntOfPoints={currUser.points} + /> + </StoreSection> + } + + { + errInCardFrame ? + <ErrorTextCenter> + Erro ao carregar as Molduras de card de usuário + </ErrorTextCenter> + : + <StoreSection> + <SectionTitle>Molduras de card de usuário ({totalCardFrame})</SectionTitle> + <StoreDivider /> + <ItemCarousel + items={card_frames} + setCurrPage={() => { setCurrCardFramePage(currCardFramePage + 1) }} + disabled={disabledCardFrame} + stop={stopLoadingCardFrame} + myQntOfPoints={currUser.points} + /> + </StoreSection> + } + + { + errInAvatarFrame ? + <ErrorTextCenter> + Erro ao carregar as Molduras de avatar + </ErrorTextCenter> + : + <StoreSection> + <SectionTitle>Molduras de avatar ({totalAvatarFrame})</SectionTitle> + <StoreDivider /> + <ItemCarousel + items={avatar_frames} + setCurrPage={() => { setCurrAvatarFramePage(currAvatarFramePage + 1) }} + disabled={disabledAvatarFrame} + stop={stopLoadingAvatarFrame} + myQntOfPoints={currUser.points} + /> + </StoreSection> + } + + { + errInCoverFrame ? + <ErrorTextCenter> + Erro ao carregar as Molduras de capa + </ErrorTextCenter> + : + <StoreSection> + <SectionTitle>Molduras de capa ({totalCoverFrame})</SectionTitle> + <StoreDivider /> + <ItemCarousel + items={cover_frames} + setCurrPage={() => { setCurrCoverFramePage(currCoverFramePage + 1) }} + disabled={disabledCoverFrame} + stop={stopLoadingCoverFrame} + myQntOfPoints={currUser.points} + /> + </StoreSection> + } </Container> )