From b8b0058e848ed24cac481734c0f9add630d1b36b Mon Sep 17 00:00:00 2001
From: Luis Felipe Risch <lfr20@inf.ufpr.br>
Date: Thu, 22 Apr 2021 12:18:50 -0300
Subject: [PATCH] building gamefication

---
 src/Components/ContactCard.js  | 118 ++++++++++++++++++++++----------
 src/Components/ItemCard.js     |  39 +++++++----
 src/Components/ItemCarousel.js |  96 +++++++++++++++-----------
 src/Pages/ItemStore.js         | 119 +++++++++++++++++++++++++++------
 4 files changed, 262 insertions(+), 110 deletions(-)

diff --git a/src/Components/ContactCard.js b/src/Components/ContactCard.js
index 2e0513cc..468fa8ec 100644
--- a/src/Components/ContactCard.js
+++ b/src/Components/ContactCard.js
@@ -27,14 +27,20 @@ import FollowButton from "./ContactButtons/FollowButton.js";
 import FollowingButton from "./ContactButtons/FollowingButton.js";
 import FollowersCountButton from "./ContactButtons/FollowersCountButton.js";
 import { Link } from "react-router-dom";
-import Badge from "./Badge.js"; 
+import Badge from "./Badge.js";
+import Rubi from '../img/gamification/gem.svg';
 
 export default function ImgMediaCard(props) {
-
   const [followedBoolean, setFollowedBoolean] = useState(props.followed);
   const toggleFollowed = () => {
     setFollowedBoolean(!followedBoolean);
   };
+
+  function isOnStore() {
+    return (window.location.href.includes("loja"))
+  }
+
+
   return (
     <StyledCard>
       <CardDiv>
@@ -84,45 +90,57 @@ export default function ImgMediaCard(props) {
                 </span>
               </Link>
 
-              <div style={{ display: "flex", justifyContent: "center" }}>
-                {
-                  followedBoolean ?
-                    (
-                      <React.Fragment>
-                        <FollowingButton
-                          followedID={props.followerID ? props.followerID : props.followedID}
-                          toggleFollowed={toggleFollowed} />
-
-                        <Options
-                          followableID={props.followerID ? props.followerID : props.followedID}
-                          followed={followedBoolean}
-                          toggleFollowed={toggleFollowed} />
-                      </React.Fragment>
-                    )
-                    :
-                    (
-                      <React.Fragment>
-                        <FollowButton
-                          followerID={props.followedID ? props.followedID : props.followerID}
-                          toggleFollowed={toggleFollowed} />
-
-                        <Options
-                          followableID={props.followedID ? props.followedID : props.followerID}
-                          followed={followedBoolean}
-                          toggleFollowed={toggleFollowed} />
-                      </React.Fragment>
-                    )
-                }
+              {
+                !isOnStore() ?
+                  <div style={{ display: "flex", justifyContent: "center" }}>
+                    {
+                      followedBoolean ?
+                        (
+                          <React.Fragment>
+                            <FollowingButton
+                              followedID={props.followerID ? props.followerID : props.followedID}
+                              toggleFollowed={toggleFollowed} />
 
-              </div>
+                            <Options
+                              followableID={props.followerID ? props.followerID : props.followedID}
+                              followed={followedBoolean}
+                              toggleFollowed={toggleFollowed} />
+                          </React.Fragment>
+                        )
+                        :
+                        (
+                          <React.Fragment>
+                            <FollowButton
+                              followerID={props.followedID ? props.followedID : props.followerID}
+                              toggleFollowed={toggleFollowed} />
+
+                            <Options
+                              followableID={props.followedID ? props.followedID : props.followerID}
+                              followed={followedBoolean}
+                              toggleFollowed={toggleFollowed} />
+                          </React.Fragment>
+                        )
+                    }
+                  </div>
+                  :
+                  <StatusInfoDiv>
+                    <CoinsInfoDiv>
+                      <GemImg src={Rubi} />
+                      <CoinsSpan>{props.points} </CoinsSpan>
+                    </CoinsInfoDiv>
+                  </StatusInfoDiv>
+              }
             </UserInfo>
           </CardContent>
         </CardAreaDiv>
       </CardDiv>
-    </StyledCard>
+    </StyledCard >
   );
 }
 
+
+
+
 /*Controls top part of Card*/
 const Header = styled.div`
   display: flex;
@@ -136,10 +154,10 @@ export const CardAreaDiv = styled(Card)`
   flex-direction: column;
   margin: 0 auto;
   background-color: red;
-  height: 95%;
-  width: 92%;
+  height: 92%;
+  width: 94%;
   margin: 8px 0;
-  align: center;
+  /* align-items: center; */
 `;
 export const CardDiv = styled.div`
   text-align: start;
@@ -229,3 +247,31 @@ const BadgesDiv = styled.div`
   flex-direction: row;
   justify-content: space-around;
 `;
+
+const StatusInfoDiv = styled.div`
+  margin-top: 0.5em;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  flex-wrap: wrap;
+`;
+
+const CoinsInfoDiv = styled.div`
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  flex: 1;
+`;
+
+const CoinsSpan = styled.span`
+  color: red;
+  font-size: 16px;
+  margin-left: 5px;
+`;
+
+const GemImg = styled.img`
+  height: 23px;
+`;
+
diff --git a/src/Components/ItemCard.js b/src/Components/ItemCard.js
index dea4bd2a..f181cb9b 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 { apiDomain } from '../env'
 
 const ItemImage = styled.img`
 	border-radius: 150;
@@ -28,28 +29,38 @@ const ItemImage = styled.img`
 `
 
 const ItemName = styled.h3`
+	display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
 	font-size: 0.8em;
 	font-weight: lighter;
 	color: #666666;
+	width: 100%;
+	word-break: break-word;
 `
 
 const ItemDescription = styled.p`
-	font-size: 0.5em;
+	display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+	font-size: 0.5em; 
 	color: #666666;
 `
 
 
-export default function ItemCard (props) {
-        return (
-					<Grid item xs={9} sm={2}>
-						<Card style={{textAlign: 'center'}}>
-							<CardContent>
-								<ItemImage src={props.src}/>
-								<ItemName>{props.name}</ItemName>
-								<ItemDescription>{props.description}</ItemDescription>
-								<ItemCardAction operation={props.action}/>
-							</CardContent>
-						</Card>
-					</Grid>
-        )
+export default function ItemCard(props) {
+	return (
+		<Grid item xs={11} sm={3} md={2} >
+			<Card style={{ textAlign: 'center' }}>
+				<CardContent>
+					<ItemImage src={apiDomain + props.src} />
+					<ItemName>{props.name}</ItemName>
+					<ItemDescription>{props.description}</ItemDescription>
+					<ItemCardAction operation={props.action} />
+				</CardContent>
+			</Card>
+		</Grid>
+	)
 }
diff --git a/src/Components/ItemCarousel.js b/src/Components/ItemCarousel.js
index a790b4f1..625966e9 100644
--- a/src/Components/ItemCarousel.js
+++ b/src/Components/ItemCarousel.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 } from 'react';
 import Grid from '@material-ui/core/Grid';
 import ItemCard from './ItemCard.js';
 import ArrowBackIcon from '@material-ui/icons/ArrowBack';
@@ -23,45 +23,61 @@ import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
 import IconButton from '@material-ui/core/IconButton';
 
 //url/user_items/index?q={"item_type": umdaqueles, "op": "none", "unlock_rule": "purchase"}
-export default function ItemCarousel (props) {
-				const [left, setLeft] = useState(0);
-				const [right, setRight] = useState(5);
+export default function ItemCarousel(props) {
+	const [left, setLeft] = useState(0);
+	const [right, setRight] = useState(objectsPerPage());
 
-				const goLeft = () => {
-					setRight(right === 0 ? props.items.length-1 : right-1);
-					setLeft(left === 0 ? props.items.length-1 : left-1);
-				}
-				
-				const goRight = () => {
-					setRight(right === props.items.length-1 ? 0 : right+1);
-					setLeft(left === props.items.length-1 ? 0 : left+1);
-				}
+	function objectsPerPage() {
+		var pageWidth = window.innerWidth
+		if (pageWidth >= 1000) {
+			return 5
+		}
+		else {
+			if (pageWidth > 766) {
+				return 3
+			}
+			else {
+				return 1
+			}
+		}
+	}
 
-        return (
-					<Grid
-						item container
-						direction="row"
-						justify="center"
-						alignItems="center"
-						xs={12}
-						spacing={3}
-					>
-						<IconButton onClick={goLeft}>
-							<ArrowBackIcon/>
-						</IconButton>
-						{(left > right ?
-								props.items.slice(left, props.items.length).concat(props.items.slice(0, right))
-								: props.items.slice(left, right)
-							).map((i) => {
-							return <ItemCard
-								src={i.src}
-								action={i.action}
-								name={i.name}
-								description={i.description}/>
-						})}
-						<IconButton onClick={goRight}>
-							<ArrowForwardIcon/>
-						</IconButton>
-					</Grid>
-        )
+	const goLeft = () => {
+		setRight(right === 0 ? props.items.length - 1 : right - 1);
+		setLeft(left === 0 ? props.items.length - 1 : left - 1);
+	}
+
+	const goRight = () => {
+		if (right === props.items.length - 2)
+			props.setCurrPage()
+		setRight(right === props.items.length - 1 ? 0 : right + 1);
+		setLeft(left === props.items.length - 1 ? 0 : left + 1);
+	}
+
+	return (
+		<Grid
+			item container
+			direction="row"
+			justify="center"
+			alignItems="center"
+			spacing={3}
+		>
+			<IconButton onClick={goLeft}>
+				<ArrowBackIcon />
+			</IconButton>
+			{(left > right ?
+				props.items.slice(left, props.items.length).concat(props.items.slice(0, right))
+				: props.items.slice(left, right)
+			).map((i) => {
+				return <ItemCard
+					src={i.image}
+					action={i.action}
+					name={i.name}
+					description={i.description} />
+			})}
+			<IconButton onClick={goRight} disabled={props.disabled}>
+				<ArrowForwardIcon />
+			</IconButton>
+		</Grid>
+	)
 }
diff --git a/src/Pages/ItemStore.js b/src/Pages/ItemStore.js
index ac2a67a9..8c4d9120 100644
--- a/src/Pages/ItemStore.js
+++ b/src/Pages/ItemStore.js
@@ -21,16 +21,16 @@ import axios from 'axios';
 import Grid from '@material-ui/core/Grid';
 import Container from '@material-ui/core/Container';
 import CircularProgress from '@material-ui/core/CircularProgress';
-
 import StoreGuide from '../Components/StoreGuide.js';
 import ItemCarousel from '../Components/ItemCarousel.js';
 import ContactCard from '../Components/ContactCard.js';
 import { apiUrl } from '../env';
 import { Store } from '../Store';
 import { apiDomain } from '../env';
+import { getRequest } from '../Components/HelperFunctions/getAxiosConfig'
 
 const SectionTitle = styled.h3`
-	font-weight: 100;
+	font-weight: 100; 
 	margin-bottom: 0;
 `
 
@@ -46,28 +46,24 @@ const StoreSection = styled.div`
 `
 
 export default function ItemStoreContainer(props) {
-	const { state, dispatch } = useContext(Store);
-	console.log(state);
+	const { state } = useContext(Store);
 
 	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 [currUser, setCurrUser] = useState({});
-	const [isLoading, setIsLoading] = useState(true); 
-
-	// useEffect(() => {
-	// 	axios.all(
-	// 		['avatar_frame', 'card_frame', 'cover_frame', 'badge'].map((r) => {
-	// 			return axios.get(apiUrl+'/' + 'user_items/index?item_type='+r+'&unlock_rule=purchase');
-	// 		})).then(axios.spread((avatar, card, cover, badge) => {
-	// 			setAvatarFrames(avatar);
-	// 			setCardFrames(card);
-	// 			setCoverFrames(cover);
-	// 			setBadges(badge);
-	// 		}));
-	// }, [])
+	const [isLoading, setIsLoading] = useState(true);
+	const [currBadgePage, setCurrBadgePage] = useState(0)
+	const [currAvatarFramePage, setCurrAvatarFramePage] = useState(0)
+	const [currCoverFramePage, setCurrCoverFramePage] = useState(0)
+	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"]`
+	}
 
 	useEffect(() => {
 		axios.get((`${apiUrl}/users/` + state.currentUser.id))
@@ -82,6 +78,60 @@ export default function ItemStoreContainer(props) {
 			)
 	}, [state.currentUser.id])
 
+	useEffect(() => {
+		setDisabled(true)
+		getRequest(
+			buildUrl("badge", currBadgePage),
+			(data, header) => {
+				setBadges((previous) => previous.concat(data))
+				setDisabled(false)
+			},
+			(error) => {
+
+			}
+		)
+	}, [currBadgePage])
+
+	useEffect(() => {
+		setDisabled(true)
+		getRequest(
+			buildUrl("avatar_frame", currBadgePage),
+			(data, header) => {
+				setAvatarFrames((previous) => previous.concat(data))
+				setDisabled(false)
+			},
+			(error) => {
+
+			}
+		)
+	}, [currAvatarFramePage])
+
+	useEffect(() => {
+		setDisabled(true)
+		getRequest(
+			buildUrl("cover_frame", currBadgePage),
+			(data, header) => {
+				setCoverFrames((previous) => previous.concat(data))
+				setDisabled(false)
+			},
+			(error) => {
+			}
+		)
+	}, [currCoverFramePage])
+
+	useEffect(() => {
+		setDisabled(true)
+		getRequest(
+			buildUrl("card_frame", currBadgePage),
+			(data, header) => {
+				setCardFrames((previous) => previous.concat(data))
+				setDisabled(false)
+			},
+			(error) => {
+			}
+		)
+	}, [currCardFramePage])
+
 
 	return (
 		<Container maxWidth="false" style={{ marginBottom: "-20px", paddingTop: "2em", backgroundColor: "#f4f4f4" }}>
@@ -103,6 +153,7 @@ export default function ItemStoreContainer(props) {
 							numCollections={currUser.collections_count}
 							numLearningObjects={currUser.learning_objects_count}
 							follow_count={currUser.follows_count}
+							points={currUser.points}
 							// followed={currUser.followed || null}
 							// followerID={currUser.follower.id}
 							href={'/usuario-publico/' + currUser.id}
@@ -114,13 +165,41 @@ export default function ItemStoreContainer(props) {
 			<StoreSection>
 				<SectionTitle>Insígnias</SectionTitle>
 				<StoreDivider />
-				<ItemCarousel items={badges} />
+				<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>Bordas de perfil</SectionTitle>
+				<SectionTitle>Moldura de capa</SectionTitle>
 				<StoreDivider />
-				<ItemCarousel items={card_frames} />
+				<ItemCarousel
+					items={cover_frames}
+					setCurrPage={() => { setCurrCoverFramePage(currCoverFramePage + 1) }}
+					disabled={disabled}
+				/>
 			</StoreSection>
 
 		</Container>
-- 
GitLab