From a43de3b45b5d75f29ed5edacba25a2bec1ea6be1 Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Thu, 20 Jul 2023 21:41:20 -0300 Subject: [PATCH 01/11] :construction: Feat: criando layout carrinho --- src/App.js | 5 ++ src/components/layout/Cart/CardGameResume.jsx | 54 +++++++++++++++++++ src/components/layout/Navbar/Navbar.jsx | 11 ++-- src/components/view/Cart.jsx | 20 +++++++ 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 src/components/layout/Cart/CardGameResume.jsx create mode 100644 src/components/view/Cart.jsx diff --git a/src/App.js b/src/App.js index 42e8d3d..e4e33bf 100644 --- a/src/App.js +++ b/src/App.js @@ -5,6 +5,7 @@ import Home from './components/view/Home'; import Navegar from './components/view/Navegar'; import Game from './components/view/Game'; import NoContent from './components/view/NoContent'; +import Cart from './components/view/Cart'; function App() { @@ -21,6 +22,10 @@ function App() { { path: "/game/:id", element: + }, + { + path: "/carrinho", + element: } ]); diff --git a/src/components/layout/Cart/CardGameResume.jsx b/src/components/layout/Cart/CardGameResume.jsx new file mode 100644 index 0000000..87b8413 --- /dev/null +++ b/src/components/layout/Cart/CardGameResume.jsx @@ -0,0 +1,54 @@ + +function CardGameResume() { + + const game = { + "id": 1, + "attributes": { + "name": "Far Cry 6", + "createdAt": "2023-06-10T23:21:03.119Z", + "updatedAt": "2023-07-16T14:06:17.663Z", + "publishedAt": "2023-06-10T23:21:12.730Z", + "description": "Far Cry 6 é um jogo de tiro em primeira pessoa de mundo aberto desenvolvido pela Ubisoft. Situado em uma ilha fictícia chamada Yara, inspirada na cultura e história de Cuba, o jogo transporta os jogadores para um cenário de revolução e resistência contra um regime ditatorial.", + "current_price": 225.24, + "last_price": 375.4, + "image_url": "https://cdn1.epicgames.com/b4565296c22549e4830c13bc7506642d/offer/TETRA_PREORDER_STANDARD%20EDITION_EPIC_Store_Portrait_1200x1600-1200x1600-ca8b802ff13813c37a44ebf68d0946a2.png", + "developer": " Ubisoft", + "publisher": "Ubisoft Entertainment", + "size": 60, + "launch_date": "2021-10-07", + "metacritic_score": 74, + "measurement": "GB", + "edition": "Standard edition", + "classification": 18, + "thumb": "https://image.api.playstation.com/vulcan/ap/rnd/202012/1522/MEtJOQHXbVy0ux0Emo9HInke.jpg", + "short_description": null, + "highlighted": false, + "popularity": 0.05, + "platform": "Windows" + } + }; + + return ( +
+ game +
+

{ game.attributes.name }

+

{ game.attributes.edition }

+

{ game.attributes.platform }

+
+
+ Remover +
+
+

R${ game.attributes.last_price }

+

R${ game.attributes.current_price }

+
+ -30% +
+
+
+ ); +} + +export default CardGameResume; \ No newline at end of file diff --git a/src/components/layout/Navbar/Navbar.jsx b/src/components/layout/Navbar/Navbar.jsx index 84c0806..cf60ec3 100644 --- a/src/components/layout/Navbar/Navbar.jsx +++ b/src/components/layout/Navbar/Navbar.jsx @@ -3,9 +3,9 @@ import SearchBar from "./SearchBar"; function Navbar() { return ( -
+
logo @@ -20,6 +20,11 @@ function Navbar() {
+
+ Carrinho +
diff --git a/src/components/view/Cart.jsx b/src/components/view/Cart.jsx new file mode 100644 index 0000000..a1127f9 --- /dev/null +++ b/src/components/view/Cart.jsx @@ -0,0 +1,20 @@ +import CardGameResume from "../layout/Cart/CardGameResume"; +import Footer from "../layout/Footer/Footer"; +import Navbar from "../layout/Navbar/Navbar"; + +function Cart() { + return ( + <> + +
+ +
+ +
+
+
+ + ); +} + +export default Cart; \ No newline at end of file From ceb9498b1da4bd85866ef07a3d7c6390720dbc97 Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Fri, 28 Jul 2023 19:29:46 -0300 Subject: [PATCH 02/11] :construction: Feat: implementando layout carrinho --- src/components/layout/Cart/CardGameResume.jsx | 2 +- src/components/layout/Navbar/Navbar.jsx | 2 +- src/components/view/Cart.jsx | 21 +++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/layout/Cart/CardGameResume.jsx b/src/components/layout/Cart/CardGameResume.jsx index 87b8413..e9410d2 100644 --- a/src/components/layout/Cart/CardGameResume.jsx +++ b/src/components/layout/Cart/CardGameResume.jsx @@ -29,7 +29,7 @@ function CardGameResume() { }; return ( -
+
game

{ game.attributes.name }

diff --git a/src/components/layout/Navbar/Navbar.jsx b/src/components/layout/Navbar/Navbar.jsx index cf60ec3..868baef 100644 --- a/src/components/layout/Navbar/Navbar.jsx +++ b/src/components/layout/Navbar/Navbar.jsx @@ -23,7 +23,7 @@ function Navbar() {
Carrinho + hover:bg-stone-600" href={ `${process.env.REACT_APP_URL}/carrinho` }>Carrinho
- -
- +
+

Meu carrinho

+
+
+ + + +
+
+

Resumo do pedido

+
+

Itens: R$750,80

+

Descontos: -R$300,32

+

Total: R$450,48

+ +
+
From 006488e974b6aaaff0af6cdc62234d506afdb1a5 Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Fri, 28 Jul 2023 22:53:59 -0300 Subject: [PATCH 03/11] :construction: Feat: implementando carrinho --- src/components/layout/Cart/CardGameResume.jsx | 74 +++++------ src/components/view/Cart.jsx | 119 +++++++++++++++--- src/components/view/Game.jsx | 83 ++++++++++-- 3 files changed, 206 insertions(+), 70 deletions(-) diff --git a/src/components/layout/Cart/CardGameResume.jsx b/src/components/layout/Cart/CardGameResume.jsx index e9410d2..c6ef5af 100644 --- a/src/components/layout/Cart/CardGameResume.jsx +++ b/src/components/layout/Cart/CardGameResume.jsx @@ -1,53 +1,41 @@ +import Utils from "../../../scripts/Utils"; -function CardGameResume() { +function CardGameResume({game, removeItemCart}) { - const game = { - "id": 1, - "attributes": { - "name": "Far Cry 6", - "createdAt": "2023-06-10T23:21:03.119Z", - "updatedAt": "2023-07-16T14:06:17.663Z", - "publishedAt": "2023-06-10T23:21:12.730Z", - "description": "Far Cry 6 é um jogo de tiro em primeira pessoa de mundo aberto desenvolvido pela Ubisoft. Situado em uma ilha fictícia chamada Yara, inspirada na cultura e história de Cuba, o jogo transporta os jogadores para um cenário de revolução e resistência contra um regime ditatorial.", - "current_price": 225.24, - "last_price": 375.4, - "image_url": "https://cdn1.epicgames.com/b4565296c22549e4830c13bc7506642d/offer/TETRA_PREORDER_STANDARD%20EDITION_EPIC_Store_Portrait_1200x1600-1200x1600-ca8b802ff13813c37a44ebf68d0946a2.png", - "developer": " Ubisoft", - "publisher": "Ubisoft Entertainment", - "size": 60, - "launch_date": "2021-10-07", - "metacritic_score": 74, - "measurement": "GB", - "edition": "Standard edition", - "classification": 18, - "thumb": "https://image.api.playstation.com/vulcan/ap/rnd/202012/1522/MEtJOQHXbVy0ux0Emo9HInke.jpg", - "short_description": null, - "highlighted": false, - "popularity": 0.05, - "platform": "Windows" - } - }; + const utils = new Utils(); return ( -
- game -
-

{ game.attributes.name }

-

{ game.attributes.edition }

-

{ game.attributes.platform }

-
-
- Remover -
-
-

R${ game.attributes.last_price }

-

R${ game.attributes.current_price }

+ game && ( +
+ game +
+

{ game.attributes.name }

+ { + game.attributes.edition && ( +

{ game.attributes.edition }

+ ) + } +

{ game.attributes.platform }

+
+
+ removeItemCart(game.id)} href="#" className="text-stone-400 font-semibold text-end">Remover +
+
+

{ `${utils.getMonetaryFormat(game.attributes.last_price)}` }

+

{ `${utils.getMonetaryFormat(game.attributes.current_price)}` }

+
+ { + utils.getDiscount(game.attributes.current_price, game.attributes.last_price) > 0 && ( + + { `-${utils.getDiscount(game.attributes.current_price, game.attributes.last_price)}%` } + + ) + }
- -30%
-
+ ) ); } diff --git a/src/components/view/Cart.jsx b/src/components/view/Cart.jsx index b047b24..7dd5e29 100644 --- a/src/components/view/Cart.jsx +++ b/src/components/view/Cart.jsx @@ -1,29 +1,118 @@ +import { useEffect, useState } from "react"; import CardGameResume from "../layout/Cart/CardGameResume"; import Footer from "../layout/Footer/Footer"; import Navbar from "../layout/Navbar/Navbar"; +import axios from "axios"; +import Utils from "../../scripts/Utils"; function Cart() { + + const [cartItems, setCartItems] = useState(null); + const [checkout, setCheckout] = useState(null); + const utils = new Utils(); + + useEffect(() => { + if (!cartItems) { + getCartItems(); + } + calculateCheckout(); + }, [cartItems]); + + function getCartItems() { + let sessionCart = sessionStorage.getItem("cart"); + if (sessionCart) { + let cart = JSON.parse(sessionCart); + if (cart.length) { + let url = `${process.env.REACT_APP_API_URL}/api/games?`; + let index = 0; + cart.forEach(function (cartItem) { + url = url.concat(index ? "&":"", `filters[id][$eq][${index}]=${cartItem.id}`) + index++; + }) + + axios.get(url) + .then(response => { + setCartItems(response.data.data); + calculateCheckout(); + }) + .catch(error => { + console.log(error) + }) + } + } + } + + function calculateCheckout() { + let items = 0; + let discounts = 0; + let subtotal = 0; + + if (cartItems) { + cartItems.forEach(function(item) { + items += item.attributes.last_price; + discounts += item.attributes.current_price - item.attributes.last_price; + subtotal += item.attributes.current_price; + }); + + setCheckout({ + items: items, + discounts: discounts, + subtotal: subtotal + }); + } else { + setCheckout(null); + } + } + + const removeItemCart = (id) => { + if (cartItems) { + let updatedCartItems = cartItems.filter(function(item) { + return item.id != id; + }); + let sessionCart = sessionStorage.getItem("cart"); + if (sessionCart) { + let cart = JSON.parse(sessionCart); + if (sessionCart.length) { + let updatedSessionCart = cart.filter(function(item) { + return item.id != id; + }) + sessionStorage.setItem("cart", JSON.stringify(updatedSessionCart)); + } + } + setCartItems(updatedCartItems); + calculateCheckout(); + } + } + return ( <>

Meu carrinho

-
-
- - - -
-
-

Resumo do pedido

-
-

Itens: R$750,80

-

Descontos: -R$300,32

-

Total: R$450,48

- + { + cartItems && checkout && ( +
+
+ { + cartItems.map(item => { + return ( + + ) + }) + } +
+
+

Resumo do pedido

+
+

Itens: { utils.getMonetaryFormat(checkout.items) }

+

Descontos: { utils.getMonetaryFormat(checkout.discounts) }

+

Subtotal: { utils.getMonetaryFormat(checkout.subtotal) }

+ +
+
-
-
+ ) + }
diff --git a/src/components/view/Game.jsx b/src/components/view/Game.jsx index 78b85ec..a7afd3f 100644 --- a/src/components/view/Game.jsx +++ b/src/components/view/Game.jsx @@ -8,7 +8,7 @@ import Classification from "../layout/Game/Classification"; import Media from "../layout/Game/Media"; import Specs from "../layout/Game/Specs"; import SimilarGames from "../layout/Game/SimilarGames"; -import { IoAddCircle } from "react-icons/io5"; +import { MdAddShoppingCart, MdCheckCircle } from "react-icons/md"; function Game() { @@ -18,10 +18,12 @@ function Game() { const [genres, setGenres] = useState(null); const [minimumSpec, setMinimumSpec] = useState(null); const [recommendedSpec, setRecommendedSpec] = useState(null); + const [itemOnCart, setItemOnCart] = useState(false); + const [cart, setCart] = useState([]); const utils = new Utils(); useEffect(() => { - if (params) { + if (params && !game) { axios.get(`${process.env.REACT_APP_API_URL}/api/games/${params.id}?populate=*`) .then(response => { setGame(response.data.data); @@ -33,9 +35,52 @@ function Game() { .catch(error => { console.log(error); }) + getCart(); } }, []); + useEffect(() => { + checkItemOnCart(); + }, [game]); + + function getCart() { + let sessionCart = sessionStorage.getItem("cart"); + if (sessionCart) { + setCart(JSON.parse(sessionCart)); + } + } + + function checkItemOnCart() { + if (cart.length && game) { + cart.forEach(function (cartItem) { + if (cartItem.id === game.id) { + setItemOnCart(true); + } + }); + } + } + + function addToCart() { + if (cart.length) { + let newItem = { + id: game.id, + item: game.attributes.name + }; + cart.push(newItem); + setItemOnCart(true); + sessionStorage.setItem("cart", JSON.stringify(cart)); + } else { + let newCart = [ + { + id: game.id, + item: game.attributes.name + } + ]; + setItemOnCart(true); + sessionStorage.setItem("cart", JSON.stringify(newCart)); + } + } + return (
@@ -75,19 +120,33 @@ function Game() { ) } - - + COMPRAR + + + + ) + } + { + itemOnCart && ( +

+ + Adicionado ao carrinho +

+ ) + }
From d32ef83feffde028b72d1c915805ebef9a80a58c Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sat, 29 Jul 2023 15:44:12 -0300 Subject: [PATCH 04/11] :construction: Feat: implementando carrinho --- src/components/layout/Cart/CardGameResume.jsx | 6 ++- src/components/layout/Catalog/CardV.jsx | 2 +- src/components/layout/Navbar/Navbar.jsx | 43 ++++++++++++++----- src/components/view/Cart.jsx | 35 +++++++++------ src/components/view/Game.jsx | 29 ++++--------- 5 files changed, 70 insertions(+), 45 deletions(-) diff --git a/src/components/layout/Cart/CardGameResume.jsx b/src/components/layout/Cart/CardGameResume.jsx index c6ef5af..0dae309 100644 --- a/src/components/layout/Cart/CardGameResume.jsx +++ b/src/components/layout/Cart/CardGameResume.jsx @@ -21,7 +21,11 @@ function CardGameResume({game, removeItemCart}) { removeItemCart(game.id)} href="#" className="text-stone-400 font-semibold text-end">Remover
-

{ `${utils.getMonetaryFormat(game.attributes.last_price)}` }

+ { + game.attributes.last_price > game.attributes.current_price && ( +

{ `${utils.getMonetaryFormat(game.attributes.last_price)}` }

+ ) + }

{ `${utils.getMonetaryFormat(game.attributes.current_price)}` }

{ diff --git a/src/components/layout/Catalog/CardV.jsx b/src/components/layout/Catalog/CardV.jsx index da2b3da..a640dd2 100644 --- a/src/components/layout/Catalog/CardV.jsx +++ b/src/components/layout/Catalog/CardV.jsx @@ -24,7 +24,7 @@ function CardV({game}) {
{ - game.attributes.last_price && ( + game.attributes.last_price > game.attributes.current_price && (

{ utils.getMonetaryFormat(game.attributes.last_price) }

) } diff --git a/src/components/layout/Navbar/Navbar.jsx b/src/components/layout/Navbar/Navbar.jsx index 868baef..c91dd9e 100644 --- a/src/components/layout/Navbar/Navbar.jsx +++ b/src/components/layout/Navbar/Navbar.jsx @@ -1,7 +1,29 @@ import { IoPersonCircleSharp } from "react-icons/io5"; import SearchBar from "./SearchBar"; +import { useEffect, useState } from "react"; + +function Navbar({itemsOnCart}) { + + const [qtdItemsCart, setQtdItemsCart] = useState(0); + + useEffect(() => { + if (!itemsOnCart) { + console.log("sem itens"); + getCartItems(); + } else { + console.log("com items"); + setQtdItemsCart(itemsOnCart); + } + }, [itemsOnCart]); + + function getCartItems() { + let cart = sessionStorage.getItem("cart"); + if (cart) { + let sessionCart = JSON.parse(cart); + setQtdItemsCart(sessionCart.length); + } + } -function Navbar() { return (
- Descobrir - Navegar + Descobrir + Navegar
{ - if (!cartItems) { + if (!cartItems.length) { getCartItems(); } calculateCheckout(); @@ -33,7 +33,6 @@ function Cart() { axios.get(url) .then(response => { setCartItems(response.data.data); - calculateCheckout(); }) .catch(error => { console.log(error) @@ -44,19 +43,17 @@ function Cart() { function calculateCheckout() { let items = 0; - let discounts = 0; let subtotal = 0; - if (cartItems) { + if (cartItems.length) { cartItems.forEach(function(item) { - items += item.attributes.last_price; - discounts += item.attributes.current_price - item.attributes.last_price; + items += item.attributes.last_price > item.attributes.current_price ? item.attributes.last_price : item.attributes.current_price; subtotal += item.attributes.current_price; }); setCheckout({ items: items, - discounts: discounts, + discounts: subtotal - items, subtotal: subtotal }); } else { @@ -65,14 +62,14 @@ function Cart() { } const removeItemCart = (id) => { - if (cartItems) { + if (cartItems.length) { let updatedCartItems = cartItems.filter(function(item) { return item.id != id; }); let sessionCart = sessionStorage.getItem("cart"); if (sessionCart) { let cart = JSON.parse(sessionCart); - if (sessionCart.length) { + if (cart.length) { let updatedSessionCart = cart.filter(function(item) { return item.id != id; }) @@ -86,11 +83,11 @@ function Cart() { return ( <> - +

Meu carrinho

{ - cartItems && checkout && ( + checkout && cartItems.length && (
{ @@ -105,7 +102,11 @@ function Cart() {

Resumo do pedido

Itens: { utils.getMonetaryFormat(checkout.items) }

-

Descontos: { utils.getMonetaryFormat(checkout.discounts) }

+ { + checkout.discounts < 0 && ( +

Descontos: { utils.getMonetaryFormat(checkout.discounts) }

+ ) + }

Subtotal: { utils.getMonetaryFormat(checkout.subtotal) }

@@ -113,6 +114,14 @@ function Cart() {
) } + { + !checkout && ( +
+

{ "Seu carrinho está vazio :(" }

+ Continuar comprando +
+ ) + }
diff --git a/src/components/view/Game.jsx b/src/components/view/Game.jsx index a7afd3f..00e6bc7 100644 --- a/src/components/view/Game.jsx +++ b/src/components/view/Game.jsx @@ -37,7 +37,7 @@ function Game() { }) getCart(); } - }, []); + }, [cart]); useEffect(() => { checkItemOnCart(); @@ -61,29 +61,18 @@ function Game() { } function addToCart() { - if (cart.length) { - let newItem = { - id: game.id, - item: game.attributes.name - }; - cart.push(newItem); - setItemOnCart(true); - sessionStorage.setItem("cart", JSON.stringify(cart)); - } else { - let newCart = [ - { - id: game.id, - item: game.attributes.name - } - ]; - setItemOnCart(true); - sessionStorage.setItem("cart", JSON.stringify(newCart)); - } + let newItem = { + id: game.id, + item: game.attributes.name + }; + cart.push(newItem); + setItemOnCart(true); + sessionStorage.setItem("cart", JSON.stringify(cart)); } return (
- + { game && (
From d6c816fcb1be4c96caa77c15a5d7c7f8459c009c Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sat, 12 Aug 2023 16:03:51 -0300 Subject: [PATCH 05/11] =?UTF-8?q?:construction:=20Feat:=20implementando=20?= =?UTF-8?q?adapta=C3=A7=C3=B5es=20para=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 5 ++ src/components/layout/Catalog/CardV.jsx | 18 +++--- src/components/layout/Game/Media.jsx | 10 +-- src/components/layout/Game/SimilarGames.jsx | 34 +++++----- src/components/layout/Game/Specs.jsx | 8 +-- src/components/layout/Homepage/Carousel.jsx | 27 ++++---- src/components/layout/Homepage/Highlights.jsx | 15 +++-- .../layout/Homepage/PopularGames.jsx | 25 +++++--- src/components/layout/Homepage/Promotions.jsx | 7 +- .../layout/NavPage/ListGamesFromGenre.jsx | 37 ++++++----- src/components/view/Game.jsx | 64 ++++++++++--------- src/components/view/Navegar.jsx | 27 ++++---- src/components/view/SessionDetails.jsx | 60 +++++++++++++++++ 13 files changed, 217 insertions(+), 120 deletions(-) create mode 100644 src/components/view/SessionDetails.jsx diff --git a/src/App.js b/src/App.js index 42e8d3d..8f5c28c 100644 --- a/src/App.js +++ b/src/App.js @@ -5,6 +5,7 @@ import Home from './components/view/Home'; import Navegar from './components/view/Navegar'; import Game from './components/view/Game'; import NoContent from './components/view/NoContent'; +import SessionDetails from './components/view/SessionDetails'; function App() { @@ -21,6 +22,10 @@ function App() { { path: "/game/:id", element: + }, + { + path: "/promocoes", + element: } ]); diff --git a/src/components/layout/Catalog/CardV.jsx b/src/components/layout/Catalog/CardV.jsx index da2b3da..def394a 100644 --- a/src/components/layout/Catalog/CardV.jsx +++ b/src/components/layout/Catalog/CardV.jsx @@ -10,32 +10,32 @@ function CardV({game}) {
- {game.attributes.name} + {game.name}
-
{ game.attributes.name }
+
{ game.name }
{ - game.attributes.edition && ( + game.edition && ( - { game.attributes.edition } + { game.edition } ) }
{ - game.attributes.last_price && ( -

{ utils.getMonetaryFormat(game.attributes.last_price) }

+ game.last_price && ( +

{ utils.getMonetaryFormat(game.last_price) }

) } -

{ utils.getMonetaryFormat(game.attributes.current_price) }

+

{ utils.getMonetaryFormat(game.current_price) }

{ - utils.getDiscount(game.attributes.current_price, game.attributes.last_price) > 0 && ( + utils.getDiscount(game.current_price, game.last_price) > 0 && ( - { `-${utils.getDiscount(game.attributes.current_price, game.attributes.last_price)}%` } + { `-${utils.getDiscount(game.current_price, game.last_price)}%` } ) } diff --git a/src/components/layout/Game/Media.jsx b/src/components/layout/Game/Media.jsx index bc7e9bc..9cd97cd 100644 --- a/src/components/layout/Game/Media.jsx +++ b/src/components/layout/Game/Media.jsx @@ -6,7 +6,7 @@ function Media({medias}) { const [index, setIndex] = useState(1); function next() { - if (index < medias.data.length) + if (index < medias.length) setIndex(index + 1); else setIndex(1); @@ -16,7 +16,7 @@ function Media({medias}) { if (index > 1) setIndex(index - 1); else - setIndex(medias.data.length); + setIndex(medias.length); } return ( @@ -29,9 +29,9 @@ function Media({medias}) { { - medias.data.map(function (media, id = 0) { + medias.map(function (media, id = 0) { return ( - {media.attributes.description} + {media.description} ); }) } @@ -44,7 +44,7 @@ function Media({medias}) {
{ - medias.data.map(function (media, id = 0) { + medias.map(function (media, id = 0) { return ( setIndex(id)} className={++id === index ? "block w-3 h-3 mr-1 ml-1 rounded-full cursor-pointer bg-stone-300" : "block w-3 h-3 mr-1 ml-1 rounded-full cursor-pointer bg-stone-600"}> ); diff --git a/src/components/layout/Game/SimilarGames.jsx b/src/components/layout/Game/SimilarGames.jsx index c811531..844ac4e 100644 --- a/src/components/layout/Game/SimilarGames.jsx +++ b/src/components/layout/Game/SimilarGames.jsx @@ -5,42 +5,44 @@ import axios from "axios"; function SimilarGames({genres, gameId}) { - const [games, setGames] = useState([]); + const [similarGames, setSimilarGames] = useState([]); + var request = false; useEffect(() => { - if (gameId && genres.length) { + if (gameId && genres.length && !request) { getGamesByGenre(); } }, []); - function getGamesByGenre() { - - let url = `${process.env.REACT_APP_API_URL}/api/games?filters[id][$ne]=${gameId}`; - let index = genres.length; - - genres.forEach(function (genre) { - url = url.concat("&", `filters[game_genres][id][$in][${genres.length - index}]=${genre.id}`); - index--; + async function getGamesByGenre() { + let genreIds = ""; + request = true; + await genres.forEach(genre => { + genreIds = genreIds.concat(`${genre.id}+`); }); + const url = `${process.env.REACT_APP_API_URL}/api/v1/games/similar-games/${gameId}?genres=${genreIds}`; axios.get(url) - .then(response => { - setGames(response.data.data); + .then((response) => { + setSimilarGames(response.data.data); }) - .catch(error => { + .catch((error) => { console.log(error); - }); + }) + .finally(() => { + request = false; + }) } return ( - games.length > 0 && ( + similarGames.length > 0 && ( <>

Você pode se interessar por

{ - games.map(game => { + similarGames.map(game => { return ( ); diff --git a/src/components/layout/Game/Specs.jsx b/src/components/layout/Game/Specs.jsx index 0a6f468..2a479ef 100644 --- a/src/components/layout/Game/Specs.jsx +++ b/src/components/layout/Game/Specs.jsx @@ -7,19 +7,19 @@ function Specs({specs, nvl}) {
  • Sistema operacional: - { specs.attributes.so } + { specs.so }
  • Processador: - { specs.attributes.processor } + { specs.processor }
  • Memória: - { specs.attributes.memory } + { specs.memory }
  • Placa de vídeo: - { specs.attributes.graphics } + { specs.graphics }
diff --git a/src/components/layout/Homepage/Carousel.jsx b/src/components/layout/Homepage/Carousel.jsx index 6795ef6..d886016 100644 --- a/src/components/layout/Homepage/Carousel.jsx +++ b/src/components/layout/Homepage/Carousel.jsx @@ -5,21 +5,26 @@ function Carousel() { const [index, setIndex] = useState(1); const [carousel, setCarousel] = useState(null); + var request = false; useEffect(() => { - getCarousel(); + if (!request) { + getCarousel(); + } }, []); - async function getCarousel() { - if (!carousel) { - await axios.get(`${process.env.REACT_APP_API_URL}/api/game-carousels/1?populate=*`) - .then(response => { - setCarousel(response.data.data.attributes.games.data); - }) - .catch(error => { - console.log(error); - }) - } + function getCarousel() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/game-carousels/1?populate=*`) + .then((response) => { + setCarousel(response.data.data.attributes.games.data); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) } function sideTo(index) { diff --git a/src/components/layout/Homepage/Highlights.jsx b/src/components/layout/Homepage/Highlights.jsx index 3324a45..2311e30 100644 --- a/src/components/layout/Homepage/Highlights.jsx +++ b/src/components/layout/Homepage/Highlights.jsx @@ -5,21 +5,26 @@ import CardH from "./CardH"; function Highlights() { const [games, setGames] = useState([]); + var request = false; useEffect(() => { - if (!games.length) { + if (!request) { getHighlightsGames(); } }, []); - async function getHighlightsGames() { - await axios.get(`${process.env.REACT_APP_API_URL}/api/games?filters[highlighted][$eq]=true`) - .then(response => { + function getHighlightsGames() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/games?filters[highlighted][$eq]=true`) + .then((response) => { setGames(response.data.data); }) - .catch(error => { + .catch((error) => { console.log(error); }) + .finally(() => { + request = false; + }) } return ( diff --git a/src/components/layout/Homepage/PopularGames.jsx b/src/components/layout/Homepage/PopularGames.jsx index 1a898f0..a2025a6 100644 --- a/src/components/layout/Homepage/PopularGames.jsx +++ b/src/components/layout/Homepage/PopularGames.jsx @@ -6,19 +6,28 @@ import { IoChevronForwardOutline } from "react-icons/io5"; function PopularGames() { const [games, setGames] = useState([]); + var request = false; useEffect(() => { - if (!games.length) { - axios.get(`${process.env.REACT_APP_API_URL}/api/games?sort=popularity%3Adesc`) - .then(response => { - setGames(response.data.data); - }) - .catch(error => { - console.log(error); - }) + if (!request) { + getGames(); } }, []); + function getGames() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/games/popular-games`) + .then((response) => { + setGames(response.data.data); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) + } + return ( games.length > 0 && ( <> diff --git a/src/components/layout/Homepage/Promotions.jsx b/src/components/layout/Homepage/Promotions.jsx index 66a7fa1..01fedaa 100644 --- a/src/components/layout/Homepage/Promotions.jsx +++ b/src/components/layout/Homepage/Promotions.jsx @@ -6,13 +6,16 @@ import { IoChevronForwardOutline } from "react-icons/io5"; function Promotions() { const [games, setGames] = useState([]); + var request = false; useEffect(() => { - getPromotionsGames(); + if (!request) { + getPromotionsGames(); + } }, []); function getPromotionsGames() { - axios.get(`${process.env.REACT_APP_API_URL}/api/games?pagination[pageSize]=10`) + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/games/promotions?size=10`) .then(response => { setGames(response.data.data); }) diff --git a/src/components/layout/NavPage/ListGamesFromGenre.jsx b/src/components/layout/NavPage/ListGamesFromGenre.jsx index 428d4a4..61db3f0 100644 --- a/src/components/layout/NavPage/ListGamesFromGenre.jsx +++ b/src/components/layout/NavPage/ListGamesFromGenre.jsx @@ -6,37 +6,40 @@ import CardV from "../Catalog/CardV"; function ListGamesFromGenre({selectedGenre}) { const [games, setGames] = useState([]); + var request = false; useEffect(() => { - if (selectedGenre) { + if (selectedGenre && !request) { getGamesByGenre(); } }, [selectedGenre]); - async function getGamesByGenre() { - axios.get(`${process.env.REACT_APP_API_URL}/api/game-genres/${selectedGenre.id}?populate=*`) - .then(response => { - setGames(response.data.data.attributes.games.data); + function getGamesByGenre() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/genre/${selectedGenre.id}/games`) + .then((response) => { + setGames(response.data.data.games); }) - .catch(error => { + .catch((error) => { console.log(error); - }); + }) + .finally(() => { + request = false; + }) } function component() { - if (games.length > 0) { + if (games && games.length > 0) { return ( <> -

{ selectedGenre.attributes.genre }

+

{ selectedGenre.genre }

{ - games && ( - games.map(game => { - return ( - - ) - }) - ) + games.map(game => { + return ( + + ) + }) }
@@ -46,7 +49,7 @@ function ListGamesFromGenre({selectedGenre}) { if (selectedGenre) { return ( <> -

{ selectedGenre.attributes.genre }

+

{ selectedGenre.genre }

Nenhum jogo encontrado.

); diff --git a/src/components/view/Game.jsx b/src/components/view/Game.jsx index 78b85ec..721bac2 100644 --- a/src/components/view/Game.jsx +++ b/src/components/view/Game.jsx @@ -22,13 +22,13 @@ function Game() { useEffect(() => { if (params) { - axios.get(`${process.env.REACT_APP_API_URL}/api/games/${params.id}?populate=*`) + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/game/${params.id}`) .then(response => { - setGame(response.data.data); - setMedias(response.data.data.attributes.game_medias); - setGenres(response.data.data.attributes.game_genres); - setMinimumSpec(response.data.data.attributes.game_minimum_spec.data); - setRecommendedSpec(response.data.data.attributes.game_recommended_spec.data); + setGame(response.data); + setMedias(response.data.game_medias); + setGenres(response.data.game_genres); + setMinimumSpec(response.data.game_minimum_spec); + setRecommendedSpec(response.data.game_recommended_spec); }) .catch(error => { console.log(error); @@ -42,36 +42,36 @@ function Game() { { game && (
-

{ game.attributes.name }

+

{ game.name }

- far-cry-6 + far-cry-6
{ - game.attributes.last_price && ( -
{ utils.getMonetaryFormat(game.attributes.last_price) }
+ game.last_price && ( +
{ utils.getMonetaryFormat(game.last_price) }
) } -

{ utils.getMonetaryFormat(game.attributes.current_price) }

+

{ utils.getMonetaryFormat(game.current_price) }

{ - utils.getDiscount(game.attributes.current_price, game.attributes.last_price) > 0 && ( + utils.getDiscount(game.current_price, game.last_price) > 0 && ( - { `-${utils.getDiscount(game.attributes.current_price, game.attributes.last_price)}%` } + { `-${utils.getDiscount(game.current_price, game.last_price)}%` } ) }
{ - game.attributes.edition && ( + game.edition && ( - { game.attributes.edition } + { game.edition } ) } @@ -94,39 +94,41 @@ function Game() {
Sobre o jogo:
-

{ game.attributes.description }

+

{ game.description }

- +

Gêneros:

{ - genres.data.map(genre => { - return ( -

{ genre.attributes.genre }

- ); - }) + genres && ( + genres.map(genre => { + return ( +

{ genre.genre }

+ ); + }) + ) }

Classificação Metacritic:

-

{ game.attributes.metacritic_score }

+

{ game.metacritic_score }

-

Desenvolvedor: { game.attributes.developer }

-

Publisher: { game.attributes.publisher }

-

Lançamento: { utils.getFormattedDate(game.attributes.launch_date) }

+

Desenvolvedor: { game.developer }

+

Publisher: { game.publisher }

+

Lançamento: { utils.getFormattedDate(game.launch_date) }

Plataforma: { game.attributes.platform } + pr-2 pb-0.5 pl-2 mr-1 mb-1 ml-1">{ game.platform }

-

Tamanho: { game.attributes.size + game.attributes.measurement }

+

Tamanho: { game.size + game.measurement }

) } { recommendedSpec && ( ) }
- +
) } diff --git a/src/components/view/Navegar.jsx b/src/components/view/Navegar.jsx index f54fd01..715b01d 100644 --- a/src/components/view/Navegar.jsx +++ b/src/components/view/Navegar.jsx @@ -9,26 +9,29 @@ function Navegar() { const [genres, setGenres] = useState([]); const [selectedGenre, setSelectedGenre] = useState(null); + var request = false; useEffect(() => { - if (!genres.length) { + if (!genres.length && !request) { getGameGenres(); } else { - if (!selectedGenre) { - setSelectedGenre(genres[0]); - } + setSelectedGenre(genres[0]); } - }, [genres, selectedGenre]); + }, [genres]); - async function getGameGenres() { - axios.get(`${process.env.REACT_APP_API_URL}/api/game-genres?sort=genre`) - .then(response => { + function getGameGenres() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/genres`) + .then((response) => { setGenres(response.data.data); }) - .catch(error => { + .catch((error) => { console.log(error); - }); + }) + .finally(() => { + request = false; + }) } return ( @@ -38,7 +41,7 @@ function Navegar() {

Navegar

{ - genres && ( + genres.length > 0 && (
{ genres.map(genre => { @@ -46,7 +49,7 @@ function Navegar() { selectedGenre && ( setSelectedGenre(genre)} className={genre.id === selectedGenre.id ? "bg-stone-500 mb-3 p-2 rounded-md cursor-pointer duration-300" : "bg-stone-800 mb-3 p-2 rounded-md cursor-pointer hover:bg-stone-700 duration-300"}> - { genre.attributes.genre } + { genre.genre } ) ); diff --git a/src/components/view/SessionDetails.jsx b/src/components/view/SessionDetails.jsx new file mode 100644 index 0000000..d5f2f82 --- /dev/null +++ b/src/components/view/SessionDetails.jsx @@ -0,0 +1,60 @@ +import { useEffect, useState } from "react"; +import Footer from "../layout/Footer/Footer"; +import Navbar from "../layout/Navbar/Navbar"; +import axios from "axios"; +import CardV from "../layout/Catalog/CardV"; + + +function SessionDetails({sessionName, contentUrl}) { + + const [games, setGames] = useState(null); + var request = false; + + useEffect(() => { + if (!request) { + getGames(); + } + },[]); + + function getGames() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}${contentUrl}`) + .then((response) => { + setGames(response.data.data); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) + } + + return ( + <> + +
+
+

{ sessionName }

+
+

Filtros

+
+
+
+ { + games && ( + games.map(game => { + return ( + + ) + }) + ) + } +
+
+
+ + ); +} + +export default SessionDetails; \ No newline at end of file From 1a61590d08268790b6e864cd91476dfccc3bad39 Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sun, 13 Aug 2023 12:52:55 -0300 Subject: [PATCH 06/11] =?UTF-8?q?:construction:=20Feat:=20implementando=20?= =?UTF-8?q?filtros=20e=20p=C3=A1gina=20de=20promo=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/Homepage/Promotions.jsx | 16 ++- .../layout/NavPage/ListGamesFromGenre.jsx | 63 ---------- src/components/layout/Session/Filter.jsx | 111 ++++++++++++++++++ src/components/layout/Session/ListGames.jsx | 20 ++++ src/components/view/Navegar.jsx | 36 +++++- src/components/view/SessionDetails.jsx | 48 ++++---- 6 files changed, 200 insertions(+), 94 deletions(-) delete mode 100644 src/components/layout/NavPage/ListGamesFromGenre.jsx create mode 100644 src/components/layout/Session/Filter.jsx create mode 100644 src/components/layout/Session/ListGames.jsx diff --git a/src/components/layout/Homepage/Promotions.jsx b/src/components/layout/Homepage/Promotions.jsx index 01fedaa..d4e5fb5 100644 --- a/src/components/layout/Homepage/Promotions.jsx +++ b/src/components/layout/Homepage/Promotions.jsx @@ -10,18 +10,22 @@ function Promotions() { useEffect(() => { if (!request) { - getPromotionsGames(); + getPromotions(); } }, []); - function getPromotionsGames() { + function getPromotions() { + request = true; axios.get(`${process.env.REACT_APP_API_URL}/api/v1/games/promotions?size=10`) - .then(response => { + .then((response) => { setGames(response.data.data); }) - .catch(error => { + .catch((error) => { console.log(error); }) + .finally(() => { + request = false; + }) } return ( @@ -29,7 +33,9 @@ function Promotions() {

Promoções

- + + +
{ - if (selectedGenre && !request) { - getGamesByGenre(); - } - }, [selectedGenre]); - - function getGamesByGenre() { - request = true; - axios.get(`${process.env.REACT_APP_API_URL}/api/v1/genre/${selectedGenre.id}/games`) - .then((response) => { - setGames(response.data.data.games); - }) - .catch((error) => { - console.log(error); - }) - .finally(() => { - request = false; - }) - } - - function component() { - if (games && games.length > 0) { - return ( - <> -

{ selectedGenre.genre }

-
- { - games.map(game => { - return ( - - ) - }) - } -
- - ); - } - else { - if (selectedGenre) { - return ( - <> -

{ selectedGenre.genre }

-

Nenhum jogo encontrado.

- - ); - } - } - } - - return component(); -} - -export default ListGamesFromGenre; \ No newline at end of file diff --git a/src/components/layout/Session/Filter.jsx b/src/components/layout/Session/Filter.jsx new file mode 100644 index 0000000..4ed7ae5 --- /dev/null +++ b/src/components/layout/Session/Filter.jsx @@ -0,0 +1,111 @@ +import axios from "axios"; +import { useEffect, useRef, useState } from "react"; + + +function Filter({filteredResults, genres}) { + + const [fPrice, setFPrice] = useState(500); + const [fGenres, setFGenres] = useState([]); + const [results, setResults] = useState(null); + const refPrice = useRef(null); + var request = false; + + useEffect(() => { + if (!request) { + getGames(); + } + }, []); + + function filterPrice() { + setFPrice(refPrice.current.value); + } + + function filterGenre(genre) { + if (!fGenres.includes(genre)) { + fGenres.push(genre); + } + else { + let filteredGenres = fGenres.filter(item => { + return item !== genre; + }); + setFGenres(filteredGenres); + } + } + + function getGames() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/games/promotions`) + .then((response) => { + setResults(response.data.data); + filteredResults(response.data.data); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) + } + + async function filterResults(e) { + e.preventDefault(); + let paramPrice = `?price=${fPrice}`; + let paramGenres = ""; + + if (fGenres.length) { + paramGenres = "&genres="; + fGenres.forEach(genre => { + paramGenres = paramGenres.concat(`${genre}+`); + }); + } + + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/games/promotions${paramPrice}${paramGenres}`) + .then((response) => { + filteredResults(response.data.data); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) + } + + function clearFilters() { + setFPrice(500); + setFGenres([]); + filteredResults(results); + } + + return ( +
+

Filtros

+
+ + {filterPrice()}} className="w-full mt-2 cursor-pointer" /> +
+
+

Gêneros

+ { + genres.length > 0 && ( + genres.map(item => { + return ( +
+ filterGenre(item.genre)} title="fGenre" type="checkbox" className="cursor-pointer"/> + +
+ ); + }) + ) + } +
+
+ + +
+
+ ); +} + +export default Filter; \ No newline at end of file diff --git a/src/components/layout/Session/ListGames.jsx b/src/components/layout/Session/ListGames.jsx new file mode 100644 index 0000000..5f5f6bc --- /dev/null +++ b/src/components/layout/Session/ListGames.jsx @@ -0,0 +1,20 @@ +import CardV from "../Catalog/CardV"; + + +function ListGames({games}) { + return ( +
+ { + games.length > 0 && ( + games.map(game => { + return ( + + ) + }) + ) + } +
+ ); +} + +export default ListGames; \ No newline at end of file diff --git a/src/components/view/Navegar.jsx b/src/components/view/Navegar.jsx index 715b01d..11526fa 100644 --- a/src/components/view/Navegar.jsx +++ b/src/components/view/Navegar.jsx @@ -2,13 +2,14 @@ import axios from "axios"; import Footer from "../layout/Footer/Footer"; import Navbar from "../layout/Navbar/Navbar"; import { useEffect, useState } from "react"; -import ListGamesFromGenre from "../layout/NavPage/ListGamesFromGenre"; +import ListGames from "../layout/Session/ListGames"; function Navegar() { const [genres, setGenres] = useState([]); const [selectedGenre, setSelectedGenre] = useState(null); + const [games, setGames] = useState([]); var request = false; useEffect(() => { @@ -20,6 +21,12 @@ function Navegar() { } }, [genres]); + useEffect(() => { + if (selectedGenre && !request) { + getGamesByGenre(); + } + }, [selectedGenre]); + function getGameGenres() { request = true; axios.get(`${process.env.REACT_APP_API_URL}/api/v1/genres`) @@ -34,10 +41,24 @@ function Navegar() { }) } + function getGamesByGenre() { + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/genre/${selectedGenre.id}/games`) + .then((response) => { + setGames(response.data.data.games); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) + } + return ( <> -
+

Navegar

{ @@ -59,9 +80,14 @@ function Navegar() { ) }
-
- -
+ { + selectedGenre && ( +
+
{ selectedGenre.genre }
+ +
+ ) + }
diff --git a/src/components/view/SessionDetails.jsx b/src/components/view/SessionDetails.jsx index d5f2f82..086870b 100644 --- a/src/components/view/SessionDetails.jsx +++ b/src/components/view/SessionDetails.jsx @@ -2,25 +2,27 @@ import { useEffect, useState } from "react"; import Footer from "../layout/Footer/Footer"; import Navbar from "../layout/Navbar/Navbar"; import axios from "axios"; -import CardV from "../layout/Catalog/CardV"; +import ListGames from "../layout/Session/ListGames"; +import Filter from "../layout/Session/Filter"; function SessionDetails({sessionName, contentUrl}) { - const [games, setGames] = useState(null); + const [games, setGames] = useState([]); + const [genres, setGenres] = useState([]); var request = false; useEffect(() => { if (!request) { - getGames(); + getGameGenres(); } - },[]); + }, []); - function getGames() { + function getGameGenres() { request = true; - axios.get(`${process.env.REACT_APP_API_URL}${contentUrl}`) + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/genres`) .then((response) => { - setGames(response.data.data); + setGenres(response.data.data); }) .catch((error) => { console.log(error); @@ -30,26 +32,30 @@ function SessionDetails({sessionName, contentUrl}) { }) } + function componentListGames() { + if (games.length) { + return (); + } + else { + return ( +
+

{ `Nenhum resultado encontrado :(` }

+

Tente mudar os filtros de busca para encontrar resultados...

+
+ ) + } + } + return ( <> -
+

{ sessionName }

-
-

Filtros

-
+
-
- { - games && ( - games.map(game => { - return ( - - ) - }) - ) - } +
+ { componentListGames() }
From bf9af28d21e365b958bdbee2972d57509635d3b4 Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sun, 13 Aug 2023 13:42:54 -0300 Subject: [PATCH 07/11] :wrench: Fix: ajuste card de jogos --- src/components/layout/Catalog/CardV.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layout/Catalog/CardV.jsx b/src/components/layout/Catalog/CardV.jsx index def394a..3b2da07 100644 --- a/src/components/layout/Catalog/CardV.jsx +++ b/src/components/layout/Catalog/CardV.jsx @@ -24,7 +24,7 @@ function CardV({game}) {
{ - game.last_price && ( + game.last_price > game.current_price && (

{ utils.getMonetaryFormat(game.last_price) }

) } From 390e4a4655be8524ed931e2c5fde59db8475476b Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sat, 26 Aug 2023 22:40:59 -0300 Subject: [PATCH 08/11] :sparkles: Feat: implementando novo carrinho e melhorias gerais --- src/App.js | 48 ++++----- src/components/layout/Cart/CardGameResume.jsx | 22 ++-- src/components/layout/Catalog/CardV.jsx | 16 ++- src/components/layout/Layout.jsx | 15 +++ src/components/layout/Navbar/Navbar.jsx | 51 +++------ .../view/{Cart.jsx => CartView.jsx} | 100 ++++++++---------- .../view/{Game.jsx => GameView.jsx} | 68 ++++-------- .../view/{Home.jsx => HomeView.jsx} | 6 -- .../view/{Navegar.jsx => NavegarView.jsx} | 5 - .../view/{NoContent.jsx => NoContentView.jsx} | 0 src/scripts/Cart.js | 59 +++++++++++ 11 files changed, 190 insertions(+), 200 deletions(-) create mode 100644 src/components/layout/Layout.jsx rename src/components/view/{Cart.jsx => CartView.jsx} (55%) rename src/components/view/{Game.jsx => GameView.jsx} (75%) rename src/components/view/{Home.jsx => HomeView.jsx} (76%) rename src/components/view/{Navegar.jsx => NavegarView.jsx} (92%) rename src/components/view/{NoContent.jsx => NoContentView.jsx} (100%) create mode 100644 src/scripts/Cart.js diff --git a/src/App.js b/src/App.js index e4e33bf..04bd8ac 100644 --- a/src/App.js +++ b/src/App.js @@ -1,37 +1,33 @@ import './assets/css/App.css'; import './index.css'; -import { BrowserRouter, Route, Router, RouterProvider, Routes, createBrowserRouter } from 'react-router-dom'; -import Home from './components/view/Home'; -import Navegar from './components/view/Navegar'; -import Game from './components/view/Game'; -import NoContent from './components/view/NoContent'; -import Cart from './components/view/Cart'; +import { BrowserRouter, Route, Routes } from 'react-router-dom'; +import HomeView from './components/view/HomeView'; +import GameView from './components/view/GameView'; +import NavegarView from './components/view/NavegarView'; +import Cart from './scripts/Cart'; +import { useState } from 'react'; +import Layout from './components/layout/Layout'; +import CartView from './components/view/CartView'; function App() { - const router = createBrowserRouter([ - { - path: "/", - element: , - errorElement: - }, - { - path: "/navegar", - element: - }, - { - path: "/game/:id", - element: - }, - { - path: "/carrinho", - element: - } - ]); + const [cart, setCart] = useState(new Cart()); + const [context, setContext] = useState({ + cart: cart + }); return (
- + + + }> + }> + }> + }> + }> + + +
); } diff --git a/src/components/layout/Cart/CardGameResume.jsx b/src/components/layout/Cart/CardGameResume.jsx index 0dae309..128afc2 100644 --- a/src/components/layout/Cart/CardGameResume.jsx +++ b/src/components/layout/Cart/CardGameResume.jsx @@ -7,32 +7,32 @@ function CardGameResume({game, removeItemCart}) { return ( game && (
- game + game
-

{ game.attributes.name }

+

{ game.name }

{ - game.attributes.edition && ( -

{ game.attributes.edition }

+ game.edition && ( +

{ game.edition }

) } -

{ game.attributes.platform }

+

{ game.platform }

- removeItemCart(game.id)} href="#" className="text-stone-400 font-semibold text-end">Remover + removeItemCart(game)} href="#" className="text-stone-400 font-semibold text-end">Remover
{ - game.attributes.last_price > game.attributes.current_price && ( -

{ `${utils.getMonetaryFormat(game.attributes.last_price)}` }

+ game.last_price > game.current_price && ( +

{ `${utils.getMonetaryFormat(game.last_price)}` }

) } -

{ `${utils.getMonetaryFormat(game.attributes.current_price)}` }

+

{ `${utils.getMonetaryFormat(game.current_price)}` }

{ - utils.getDiscount(game.attributes.current_price, game.attributes.last_price) > 0 && ( + utils.getDiscount(game.current_price, game.last_price) > 0 && ( - { `-${utils.getDiscount(game.attributes.current_price, game.attributes.last_price)}%` } + { `-${utils.getDiscount(game.current_price, game.last_price)}%` } ) } diff --git a/src/components/layout/Catalog/CardV.jsx b/src/components/layout/Catalog/CardV.jsx index a640dd2..3fb9fa0 100644 --- a/src/components/layout/Catalog/CardV.jsx +++ b/src/components/layout/Catalog/CardV.jsx @@ -1,3 +1,4 @@ +import { Link } from "react-router-dom"; import Utils from "../../../scripts/Utils"; function CardV({game}) { @@ -6,17 +7,14 @@ function CardV({game}) { return ( game && ( - -
+ +
{game.attributes.name}
{ game.attributes.name }
{ game.attributes.edition && ( - + { game.attributes.edition } ) @@ -32,9 +30,7 @@ function CardV({game}) {
{ utils.getDiscount(game.attributes.current_price, game.attributes.last_price) > 0 && ( - + { `-${utils.getDiscount(game.attributes.current_price, game.attributes.last_price)}%` } ) @@ -42,7 +38,7 @@ function CardV({game}) {
- + ) ); } diff --git a/src/components/layout/Layout.jsx b/src/components/layout/Layout.jsx new file mode 100644 index 0000000..b7f4a01 --- /dev/null +++ b/src/components/layout/Layout.jsx @@ -0,0 +1,15 @@ +import { Outlet } from "react-router-dom"; +import Footer from "./Footer/Footer"; +import Navbar from "./Navbar/Navbar"; + +function Layout({context}) { + return ( + <> + + +
+ + ); +} + +export default Layout; \ No newline at end of file diff --git a/src/components/layout/Navbar/Navbar.jsx b/src/components/layout/Navbar/Navbar.jsx index c91dd9e..6976ce6 100644 --- a/src/components/layout/Navbar/Navbar.jsx +++ b/src/components/layout/Navbar/Navbar.jsx @@ -1,56 +1,31 @@ import { IoPersonCircleSharp } from "react-icons/io5"; import SearchBar from "./SearchBar"; -import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; -function Navbar({itemsOnCart}) { - - const [qtdItemsCart, setQtdItemsCart] = useState(0); - - useEffect(() => { - if (!itemsOnCart) { - console.log("sem itens"); - getCartItems(); - } else { - console.log("com items"); - setQtdItemsCart(itemsOnCart); - } - }, [itemsOnCart]); - - function getCartItems() { - let cart = sessionStorage.getItem("cart"); - if (cart) { - let sessionCart = JSON.parse(cart); - setQtdItemsCart(sessionCart.length); - } - } +function Navbar({cart}) { return ( -
+
logo
- Descobrir - Navegar + Descobrir + Navegar
- - Carrinho - { - qtdItemsCart > 0 && ( -

{ qtdItemsCart }

- ) - } -
+ Carrinho + { + cart && cart.items.length > 0 && ( +

{ cart.items.length }

+ ) + } +
-
+

Login

diff --git a/src/components/view/Cart.jsx b/src/components/view/CartView.jsx similarity index 55% rename from src/components/view/Cart.jsx rename to src/components/view/CartView.jsx index 4bad7ab..de10228 100644 --- a/src/components/view/Cart.jsx +++ b/src/components/view/CartView.jsx @@ -1,54 +1,63 @@ import { useEffect, useState } from "react"; import CardGameResume from "../layout/Cart/CardGameResume"; -import Footer from "../layout/Footer/Footer"; -import Navbar from "../layout/Navbar/Navbar"; import axios from "axios"; import Utils from "../../scripts/Utils"; +import { Link } from "react-router-dom"; -function Cart() { +function CartView({cart}) { const [cartItems, setCartItems] = useState([]); const [checkout, setCheckout] = useState(null); + const [games, setGames] = useState([]); const utils = new Utils(); - + var request = false; + useEffect(() => { - if (!cartItems.length) { - getCartItems(); + if (cart && !cartItems.length && !request) { + setCartItems(cart.getCart.items); } calculateCheckout(); + console.log("mundaça em games"); + }, [games]); + + useEffect(() => { + getGames(); }, [cartItems]); - function getCartItems() { - let sessionCart = sessionStorage.getItem("cart"); - if (sessionCart) { - let cart = JSON.parse(sessionCart); - if (cart.length) { - let url = `${process.env.REACT_APP_API_URL}/api/games?`; - let index = 0; - cart.forEach(function (cartItem) { - url = url.concat(index ? "&":"", `filters[id][$eq][${index}]=${cartItem.id}`) - index++; - }) + async function getGames() { + if (cartItems.length) { + let paramGames = "?games="; + cartItems.forEach((game) => { + paramGames = paramGames.concat(`${game.id}+`); + }); - axios.get(url) - .then(response => { - setCartItems(response.data.data); - }) - .catch(error => { - console.log(error) - }) - } + request = true; + axios.get(`${process.env.REACT_APP_API_URL}/api/v1/games${paramGames}`) + .then((response) => { + setGames(response.data.data); + }) + .catch((error) => { + console.log(error); + }) + .finally(() => { + request = false; + }) + } + else { + setGames([]); } + // calculateCheckout(); } function calculateCheckout() { + console.log("calculando checkout"); let items = 0; let subtotal = 0; - if (cartItems.length) { - cartItems.forEach(function(item) { - items += item.attributes.last_price > item.attributes.current_price ? item.attributes.last_price : item.attributes.current_price; - subtotal += item.attributes.current_price; + if (games.length) { + games.forEach((game) => { + items += game.last_price > game.current_price ? game.last_price : game.current_price; + subtotal += game.current_price; }); setCheckout({ @@ -61,39 +70,23 @@ function Cart() { } } - const removeItemCart = (id) => { - if (cartItems.length) { - let updatedCartItems = cartItems.filter(function(item) { - return item.id != id; - }); - let sessionCart = sessionStorage.getItem("cart"); - if (sessionCart) { - let cart = JSON.parse(sessionCart); - if (cart.length) { - let updatedSessionCart = cart.filter(function(item) { - return item.id != id; - }) - sessionStorage.setItem("cart", JSON.stringify(updatedSessionCart)); - } - } - setCartItems(updatedCartItems); - calculateCheckout(); - } + async function removeItemCart(item) { + await cart.removeItemOnCart(item); + setCartItems(await cart.getCart.items); } return ( <> -

Meu carrinho

{ - checkout && cartItems.length && ( + checkout && games.length > 0 && (
{ - cartItems.map(item => { + games.map(game => { return ( - + ) }) } @@ -118,14 +111,13 @@ function Cart() { !checkout && (

{ "Seu carrinho está vazio :(" }

- Continuar comprando + Continuar comprando
) }
-
); } -export default Cart; \ No newline at end of file +export default CartView; \ No newline at end of file diff --git a/src/components/view/Game.jsx b/src/components/view/GameView.jsx similarity index 75% rename from src/components/view/Game.jsx rename to src/components/view/GameView.jsx index 00e6bc7..9ecac42 100644 --- a/src/components/view/Game.jsx +++ b/src/components/view/GameView.jsx @@ -1,6 +1,4 @@ import { useParams } from "react-router-dom"; -import Footer from "../layout/Footer/Footer"; -import Navbar from "../layout/Navbar/Navbar"; import { useEffect, useState } from "react"; import axios from "axios"; import Utils from "../../scripts/Utils"; @@ -10,7 +8,7 @@ import Specs from "../layout/Game/Specs"; import SimilarGames from "../layout/Game/SimilarGames"; import { MdAddShoppingCart, MdCheckCircle } from "react-icons/md"; -function Game() { +function Game({context}) { const params = useParams(); const [game, setGame] = useState(null); @@ -19,7 +17,6 @@ function Game() { const [minimumSpec, setMinimumSpec] = useState(null); const [recommendedSpec, setRecommendedSpec] = useState(null); const [itemOnCart, setItemOnCart] = useState(false); - const [cart, setCart] = useState([]); const utils = new Utils(); useEffect(() => { @@ -35,44 +32,26 @@ function Game() { .catch(error => { console.log(error); }) - getCart(); } - }, [cart]); + }, []); useEffect(() => { checkItemOnCart(); }, [game]); - - function getCart() { - let sessionCart = sessionStorage.getItem("cart"); - if (sessionCart) { - setCart(JSON.parse(sessionCart)); - } - } - function checkItemOnCart() { - if (cart.length && game) { - cart.forEach(function (cartItem) { - if (cartItem.id === game.id) { - setItemOnCart(true); - } - }); + async function checkItemOnCart() { + if (context.cart && game) { + setItemOnCart(await context.cart.checkItemOnCart(game)); } } function addToCart() { - let newItem = { - id: game.id, - item: game.attributes.name - }; - cart.push(newItem); + context.cart.addToCart(game); setItemOnCart(true); - sessionStorage.setItem("cart", JSON.stringify(cart)); } return (
- { game && (
@@ -102,9 +81,7 @@ function Game() {
{ game.attributes.edition && ( - + { game.attributes.edition } ) @@ -112,16 +89,10 @@ function Game() { { !itemOnCart && ( <> - - @@ -145,16 +116,15 @@ function Game() {

{ game.attributes.description }

- +

Gêneros:

{ genres.data.map(genre => { return ( -

{ genre.attributes.genre }

+

+ { genre.attributes.genre } +

); }) } @@ -171,15 +141,14 @@ function Game() {

Publisher: { game.attributes.publisher }

Lançamento: { utils.getFormattedDate(game.attributes.launch_date) }

Plataforma: - { game.attributes.platform } + + { game.attributes.platform } +

Tamanho: { game.attributes.size + game.attributes.measurement }

-
+
{ minimumSpec && ( ) } { recommendedSpec && ( ) }
@@ -187,7 +156,6 @@ function Game() {
) } -
); } diff --git a/src/components/view/Home.jsx b/src/components/view/HomeView.jsx similarity index 76% rename from src/components/view/Home.jsx rename to src/components/view/HomeView.jsx index 391d225..3eb89f7 100644 --- a/src/components/view/Home.jsx +++ b/src/components/view/HomeView.jsx @@ -1,17 +1,12 @@ -import CardV from "../layout/Catalog/CardV"; import Carousel from "../layout/Homepage/Carousel"; -import Footer from "../layout/Footer/Footer"; -import Navbar from "../layout/Navbar/Navbar"; import PopularGames from "../layout/Homepage/PopularGames"; import Highlights from "../layout/Homepage/Highlights"; import Promotions from "../layout/Homepage/Promotions"; - function Home() { return ( <> -
@@ -20,7 +15,6 @@ function Home() {
-
); } diff --git a/src/components/view/Navegar.jsx b/src/components/view/NavegarView.jsx similarity index 92% rename from src/components/view/Navegar.jsx rename to src/components/view/NavegarView.jsx index f54fd01..915f005 100644 --- a/src/components/view/Navegar.jsx +++ b/src/components/view/NavegarView.jsx @@ -1,10 +1,7 @@ import axios from "axios"; -import Footer from "../layout/Footer/Footer"; -import Navbar from "../layout/Navbar/Navbar"; import { useEffect, useState } from "react"; import ListGamesFromGenre from "../layout/NavPage/ListGamesFromGenre"; - function Navegar() { const [genres, setGenres] = useState([]); @@ -33,7 +30,6 @@ function Navegar() { return ( <> -

Navegar

@@ -60,7 +56,6 @@ function Navegar() {
-
); } diff --git a/src/components/view/NoContent.jsx b/src/components/view/NoContentView.jsx similarity index 100% rename from src/components/view/NoContent.jsx rename to src/components/view/NoContentView.jsx diff --git a/src/scripts/Cart.js b/src/scripts/Cart.js new file mode 100644 index 0000000..5020958 --- /dev/null +++ b/src/scripts/Cart.js @@ -0,0 +1,59 @@ + +class Cart { + + constructor() { + let sessionCart = sessionStorage.getItem("cart"); + if (!sessionCart) { + // Criar um novo carrinho + this.cart = { + id: crypto.randomUUID(), + create_at: new Date(), + update_at: new Date(), + items: [] + } + } + else { + // Utilizar o carrinho encontrado no sessionStorage + let newCart = JSON.parse(sessionCart); + this.cart = newCart; + } + } + + get getCart() { + return this.cart; + } + + async addToCart(item) { + console.log(item.id); + if (item && !await this.checkItemOnCart(item)) { + let newItem = { + id: item.id, + insert_at: new Date() + } + this.cart.update_at = new Date(); + await this.cart.items.push(newItem); + sessionStorage.setItem("cart", JSON.stringify(this.cart)); + } + } + + async checkItemOnCart(item) { + let itemOnCart = false; + await this.cart.items.forEach((cartItem) => { + if (cartItem.id === item.id) { + itemOnCart = true; + } + }); + return itemOnCart; + } + + removeItemOnCart(item) { + let newCart = this.cart.items.filter((cartItem) => { + return cartItem.id !== item.id; + }); + this.cart.update_at = new Date(); + this.cart.items = newCart; + sessionStorage.setItem("cart", JSON.stringify(this.cart)); + } +} + +export default Cart; \ No newline at end of file From 43f23f2cd9d9fd386229805d71310cfa3984627c Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sun, 27 Aug 2023 11:59:17 -0300 Subject: [PATCH 09/11] =?UTF-8?q?:construction:=20Feat:=20finalizando=20im?= =?UTF-8?q?plementa=C3=A7=C3=A3o=20do=20carrinho?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 2 ++ src/components/layout/Layout.jsx | 2 +- src/components/layout/Navbar/Navbar.jsx | 15 ++++++++++++--- src/components/view/CartView.jsx | 5 +---- src/components/view/GameView.jsx | 1 - src/components/view/NoContentView.jsx | 3 ++- src/scripts/Cart.js | 3 ++- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/App.js b/src/App.js index 04bd8ac..33da850 100644 --- a/src/App.js +++ b/src/App.js @@ -4,6 +4,7 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom'; import HomeView from './components/view/HomeView'; import GameView from './components/view/GameView'; import NavegarView from './components/view/NavegarView'; +import NoContentView from './components/view/NoContentView'; import Cart from './scripts/Cart'; import { useState } from 'react'; import Layout from './components/layout/Layout'; @@ -25,6 +26,7 @@ function App() { }> }> }> + }> diff --git a/src/components/layout/Layout.jsx b/src/components/layout/Layout.jsx index b7f4a01..8781810 100644 --- a/src/components/layout/Layout.jsx +++ b/src/components/layout/Layout.jsx @@ -5,7 +5,7 @@ import Navbar from "./Navbar/Navbar"; function Layout({context}) { return ( <> - +
diff --git a/src/components/layout/Navbar/Navbar.jsx b/src/components/layout/Navbar/Navbar.jsx index 6976ce6..f7127ee 100644 --- a/src/components/layout/Navbar/Navbar.jsx +++ b/src/components/layout/Navbar/Navbar.jsx @@ -1,8 +1,17 @@ import { IoPersonCircleSharp } from "react-icons/io5"; import SearchBar from "./SearchBar"; import { Link } from "react-router-dom"; +import { useEffect, useState } from "react"; -function Navbar({cart}) { +function Navbar({context}) { + + const [qtdItems, setQtdItems] = useState(0); + + useEffect(() => { + if (context.cart) { + setQtdItems(context.cart.getCart.items.length); + } + }, []); return (
@@ -19,8 +28,8 @@ function Navbar({cart}) {
Carrinho { - cart && cart.items.length > 0 && ( -

{ cart.items.length }

+ qtdItems > 0 && ( +

{ qtdItems }

) } diff --git a/src/components/view/CartView.jsx b/src/components/view/CartView.jsx index de10228..2f93d29 100644 --- a/src/components/view/CartView.jsx +++ b/src/components/view/CartView.jsx @@ -17,7 +17,6 @@ function CartView({cart}) { setCartItems(cart.getCart.items); } calculateCheckout(); - console.log("mundaça em games"); }, [games]); useEffect(() => { @@ -46,11 +45,9 @@ function CartView({cart}) { else { setGames([]); } - // calculateCheckout(); } function calculateCheckout() { - console.log("calculando checkout"); let items = 0; let subtotal = 0; @@ -72,7 +69,7 @@ function CartView({cart}) { async function removeItemCart(item) { await cart.removeItemOnCart(item); - setCartItems(await cart.getCart.items); + // setCartItems(await cart.getCart.items); } return ( diff --git a/src/components/view/GameView.jsx b/src/components/view/GameView.jsx index 9ecac42..cee9108 100644 --- a/src/components/view/GameView.jsx +++ b/src/components/view/GameView.jsx @@ -47,7 +47,6 @@ function Game({context}) { function addToCart() { context.cart.addToCart(game); - setItemOnCart(true); } return ( diff --git a/src/components/view/NoContentView.jsx b/src/components/view/NoContentView.jsx index 550fb8c..ff3e413 100644 --- a/src/components/view/NoContentView.jsx +++ b/src/components/view/NoContentView.jsx @@ -1,3 +1,4 @@ +import { Link } from "react-router-dom"; function NoContent() { return ( @@ -7,7 +8,7 @@ function NoContent() {

{ "Não encontramos a página que você procurava :(" }

{ "404 Not Found" }

- { "Voltar a página inicial" } + Voltar a página inicial
); } diff --git a/src/scripts/Cart.js b/src/scripts/Cart.js index 5020958..41d802a 100644 --- a/src/scripts/Cart.js +++ b/src/scripts/Cart.js @@ -24,7 +24,6 @@ class Cart { } async addToCart(item) { - console.log(item.id); if (item && !await this.checkItemOnCart(item)) { let newItem = { id: item.id, @@ -33,6 +32,7 @@ class Cart { this.cart.update_at = new Date(); await this.cart.items.push(newItem); sessionStorage.setItem("cart", JSON.stringify(this.cart)); + window.location.reload(); } } @@ -53,6 +53,7 @@ class Cart { this.cart.update_at = new Date(); this.cart.items = newCart; sessionStorage.setItem("cart", JSON.stringify(this.cart)); + window.location.reload(); } } From 0e15ea09b2bac882c62dd245aefdef1aa3461f7c Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sun, 27 Aug 2023 12:05:54 -0300 Subject: [PATCH 10/11] =?UTF-8?q?:recycle:=20Refactor:=20refatora=C3=A7?= =?UTF-8?q?=C3=B5es=20de=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/Homepage/Carousel.jsx | 11 +++++------ src/components/layout/Homepage/PopularGames.jsx | 7 ++----- src/components/layout/Homepage/Promotions.jsx | 12 +++++------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/components/layout/Homepage/Carousel.jsx b/src/components/layout/Homepage/Carousel.jsx index d886016..5ebdb7b 100644 --- a/src/components/layout/Homepage/Carousel.jsx +++ b/src/components/layout/Homepage/Carousel.jsx @@ -1,5 +1,6 @@ import axios from "axios"; import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; function Carousel() { @@ -40,15 +41,14 @@ function Carousel() { { carousel.map(function (item, id = 0) { return ( - +
+ style={{backgroundImage: `url(${item.attributes.thumb})`}}>

{item.attributes.name}

-
+ ); }) } @@ -59,8 +59,7 @@ function Carousel() { carousel.map(function(item, id = 0) { return (
sideTo(id)} - > + onClick={() => sideTo(id)}>

{item.attributes.name}

); diff --git a/src/components/layout/Homepage/PopularGames.jsx b/src/components/layout/Homepage/PopularGames.jsx index a2025a6..96de2a8 100644 --- a/src/components/layout/Homepage/PopularGames.jsx +++ b/src/components/layout/Homepage/PopularGames.jsx @@ -31,14 +31,11 @@ function PopularGames() { return ( games.length > 0 && ( <> -
+

Mais populares

-
+
{ games.map(game => (( diff --git a/src/components/layout/Homepage/Promotions.jsx b/src/components/layout/Homepage/Promotions.jsx index d4e5fb5..b2f83fd 100644 --- a/src/components/layout/Homepage/Promotions.jsx +++ b/src/components/layout/Homepage/Promotions.jsx @@ -2,6 +2,7 @@ import axios from "axios"; import { useEffect, useState } from "react"; import CardV from "../Catalog/CardV"; import { IoChevronForwardOutline } from "react-icons/io5"; +import { Link } from "react-router-dom"; function Promotions() { @@ -30,16 +31,13 @@ function Promotions() { return ( <> -
+

Promoções

- + - +
-
+
{ games.map(game => { return ( From 0f7ea0385d0c046cff00f47ef4089e0a7ce44b61 Mon Sep 17 00:00:00 2001 From: Guilherme Freire Date: Sun, 27 Aug 2023 12:38:04 -0300 Subject: [PATCH 11/11] :wrench: Fix: atualizando componente SessionDetails --- src/App.js | 1 + src/components/view/SessionDetails.jsx | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/App.js b/src/App.js index 3ce0ea3..92376f6 100644 --- a/src/App.js +++ b/src/App.js @@ -27,6 +27,7 @@ function App() { }> }> }> + }> }> diff --git a/src/components/view/SessionDetails.jsx b/src/components/view/SessionDetails.jsx index 086870b..3025fb7 100644 --- a/src/components/view/SessionDetails.jsx +++ b/src/components/view/SessionDetails.jsx @@ -1,6 +1,4 @@ import { useEffect, useState } from "react"; -import Footer from "../layout/Footer/Footer"; -import Navbar from "../layout/Navbar/Navbar"; import axios from "axios"; import ListGames from "../layout/Session/ListGames"; import Filter from "../layout/Session/Filter"; @@ -47,19 +45,15 @@ function SessionDetails({sessionName, contentUrl}) { } return ( - <> - -
-
-

{ sessionName }

- -
-
- { componentListGames() } -
+
+
+

{ sessionName }

+ +
+
+ { componentListGames() }
- - +
); }