diff --git a/src/components/Card/CardWithoutPicture.jsx b/src/components/Card/CardWithoutPicture.jsx index abc4ecb0..13048494 100644 --- a/src/components/Card/CardWithoutPicture.jsx +++ b/src/components/Card/CardWithoutPicture.jsx @@ -161,14 +161,18 @@ export default function CardWithoutPicture({ tutorial }) { - + {tutorial?.tut_tags && + tutorial?.tut_tags.map((tag, index) => ( + + ))} ) : ( diff --git a/src/components/HomePage/index.jsx b/src/components/HomePage/index.jsx index e8190e6b..e716f6ca 100644 --- a/src/components/HomePage/index.jsx +++ b/src/components/HomePage/index.jsx @@ -37,13 +37,17 @@ import { getTutorialFeedData, getTutorialFeedIdArray } from "../../store/actions/tutorialPageActions"; +import { getTutorialsByTopTags } from "../../store/actions"; function HomePage({ background = "white", textColor = "black" }) { const classes = useStyles(); const dispatch = useDispatch(); const firebase = useFirebase(); const firestore = useFirestore(); - const [value, setValue] = useState(2); + const tutorialFeedArray = useSelector( + ({ tutorialPage }) => tutorialPage.feed.homepageFeedArray + ); + const [tutorials, setTutorials] = useState(tutorialFeedArray); const [selectedTab, setSelectedTab] = useState("1"); const [visibleModal, setVisibleModal] = useState(false); const [footerContent, setFooterContent] = useState([ @@ -57,7 +61,7 @@ function HomePage({ background = "white", textColor = "black" }) { link: "https://dev.codelabz.io/" } ]); - + let tutorialIdArray; const windowSize = useWindowSize(); const [openMenu, setOpen] = useState(false); const toggleSlider = () => { @@ -167,7 +171,7 @@ function HomePage({ background = "white", textColor = "black" }) { const profileData = useSelector(({ firebase: { profile } }) => profile); useEffect(() => { const getFeed = async () => { - const tutorialIdArray = await getTutorialFeedIdArray(profileData.uid)( + tutorialIdArray = await getTutorialFeedIdArray(profileData.uid)( firebase, firestore, dispatch @@ -176,18 +180,46 @@ function HomePage({ background = "white", textColor = "black" }) { }; getFeed(); }, []); - const tutorials = useSelector( - ({ - tutorialPage: { - feed: { homepageFeedArray } - } - }) => homepageFeedArray - ); const notification = () => {}; - const handleChange = (event, newValue) => { - setValue(newValue); + + const convertToDate = timestamp => { + return new Date(timestamp.seconds * 1000); }; + + const handleFeedChange = async filterType => { + let filteredTutorials; + switch (filterType) { + case "Featured": + filteredTutorials = await getTutorialsByTopTags()( + firebase, + firestore, + dispatch + ); + break; + case "New": + await fetchNewTutorials(); + filteredTutorials = [...tutorialFeedArray].sort( + (a, b) => convertToDate(b.createdAt) - convertToDate(a.createdAt) + ); + break; + case "Top": + await fetchNewTutorials(); + filteredTutorials = [...tutorialFeedArray].sort( + (a, b) => b.upVotes - a.upVotes + ); + break; + default: + filteredTutorials = tutorials; + } + + setTutorials(filteredTutorials); + }; + + const fetchNewTutorials = async () => { + await getTutorialFeedData(tutorialIdArray)(firebase, firestore, dispatch); + }; + const handleTabChange = (event, newValue) => { setSelectedTab(newValue); }; @@ -234,7 +266,7 @@ function HomePage({ background = "white", textColor = "black" }) { onSidebarClick={e => closeModal(e)} /> - + diff --git a/src/components/MyFeed/DiscoverCodelabz/CodelabzCarousel.jsx b/src/components/MyFeed/DiscoverCodelabz/CodelabzCarousel.jsx index 67fe28c7..d53c428d 100644 --- a/src/components/MyFeed/DiscoverCodelabz/CodelabzCarousel.jsx +++ b/src/components/MyFeed/DiscoverCodelabz/CodelabzCarousel.jsx @@ -20,7 +20,7 @@ import { useDispatch, useSelector } from "react-redux"; import { useFirestore, useFirebase } from "react-redux-firebase"; import Default from "../../../assets/images/logo.jpeg"; import { Link } from "react-router-dom"; -import { clearOrgData, getLaunchedOrgsData } from "../../../store/actions"; +import { getTutorialsByTopTags } from "../../../store/actions"; import { getTutorialFeedIdArray, getTutorialFeedData @@ -52,10 +52,10 @@ const useStyles = makeStyles(theme => ({ const CodelabzCarousel = ({ sortBy }) => { const classes = useStyles(); - - const tutorials = useSelector( + const tutorialFeedArray = useSelector( ({ tutorialPage }) => tutorialPage.feed.homepageFeedArray - ) || [0, 0, 0, 0, 0, 0]; + ); + const [tutorials, setTutorials] = useState(tutorialFeedArray); const profileData = useSelector(({ firebase: { profile } }) => profile); const dispatch = useDispatch(); const firestore = useFirestore(); @@ -74,23 +74,51 @@ const CodelabzCarousel = ({ sortBy }) => { return () => {}; }, [firestore, dispatch]); - console.log(tutorials); + useEffect(() => { + handleFeedChange(sortBy); + }, [sortBy, tutorialFeedArray]); + + const convertToDate = createdAt => { + return new Date(createdAt.seconds * 1000); + }; + + const handleFeedChange = async filterType => { + let filteredTutorials; + const oneMonthAgo = new Date().setMonth(new Date().getMonth() - 1); + const twoWeeksAgo = new Date().setDate(new Date().getDate() - 14); - const getTitle = () => { - switch (sortBy) { + switch (filterType) { case "trending": - return "Trending Now"; - case "featured": - return "Featured on Codelabz"; + filteredTutorials = [...tutorials] + .filter(tutorial => convertToDate(tutorial.createdAt) > twoWeeksAgo) + .sort((a, b) => b.upVotes - a.upVotes); + break; case "best": - return "Best of this month"; + filteredTutorials = [...tutorials] + .filter(tutorial => convertToDate(tutorial.createdAt) > oneMonthAgo) + .sort((a, b) => b.upVotes - a.upVotes); + break; + case "Featured": + filteredTutorials = await getTutorialsByTopTags()( + firebase, + firestore, + dispatch + ); + break; + default: + filteredTutorials = tutorials; } + + setTutorials(filteredTutorials); }; + return ( <> - {getTitle()} + {sortBy === "trending" && "Trending Now"} + {sortBy === "best" && "Best of the Month"} + {sortBy === "featured" && "Featured on Codelabz"} { spaceBetween={20} style={{ padding: "20px 20px" }} > - {tutorials.map((tutorial, i) => { - return tutorial == 0 ? ( - + {tutorials.map((tutorial, i) => ( + + {!tutorial ? ( { - - ) : ( - + ) : ( @@ -152,9 +178,9 @@ const CodelabzCarousel = ({ sortBy }) => { - - ); - })} + )} + + ))} diff --git a/src/components/Topbar/Activity/ActivityList.jsx b/src/components/Topbar/Activity/ActivityList.jsx index 742aefca..562126ad 100644 --- a/src/components/Topbar/Activity/ActivityList.jsx +++ b/src/components/Topbar/Activity/ActivityList.jsx @@ -28,7 +28,7 @@ const useStyles = makeStyles(theme => ({ } })); -function ActivityList({ value, toggle, acitvitylist, classname }) { +function ActivityList({ value, toggle, activityList, classname }) { const classes = useStyles(); return ( @@ -36,7 +36,7 @@ function ActivityList({ value, toggle, acitvitylist, classname }) { - {acitvitylist.map((item, index) => ( + {activityList.map((item, index) => ( - + */} { > More From Codelabz - - - + {tutorials.length > 0 && + tutorials.map((tutorial, index) => ( + + ))} -
+ {/*
@@ -61,7 +88,7 @@ const SideBar = () => { - + */} ); diff --git a/src/components/TutorialPage/index.jsx b/src/components/TutorialPage/index.jsx index dd7895c2..4a0e4a98 100644 --- a/src/components/TutorialPage/index.jsx +++ b/src/components/TutorialPage/index.jsx @@ -51,13 +51,14 @@ function TutorialPage({ background = "white", textColor = "black" }) { ); const postDetails = { + id: tutorial?.tutorial_id, title: tutorial?.title, org: tutorial?.owner, user: tutorial?.created_by, upVote: tutorial?.upVotes, downVote: tutorial?.downVotes, published_on: tutorial?.createdAt, - tag: tutorial?.tut_tags + tags: tutorial?.tut_tags }; const steps = useSelector( @@ -121,7 +122,7 @@ function TutorialPage({ background = "white", textColor = "black" }) { xs={3} data-testId="tutorialpageSideBar" > - + diff --git a/src/components/Tutorials/NewTutorial/index.jsx b/src/components/Tutorials/NewTutorial/index.jsx index ac826889..3e5754ee 100644 --- a/src/components/Tutorials/NewTutorial/index.jsx +++ b/src/components/Tutorials/NewTutorial/index.jsx @@ -5,7 +5,7 @@ import { createTutorial } from "../../../store/actions"; import { useFirebase, useFirestore } from "react-redux-firebase"; import { useHistory } from "react-router-dom"; import Button from "@mui/material/Button"; -import { Alert, Box } from "@mui/material"; +import { Alert, Box, Chip } from "@mui/material"; import TextField from "@mui/material/TextField"; import Divider from "@mui/material/Divider"; import { IconButton } from "@mui/material"; @@ -19,6 +19,7 @@ import DescriptionIcon from "@mui/icons-material/Description"; import MovieIcon from "@mui/icons-material/Movie"; import Select from "react-select"; import { common } from "@mui/material/colors"; +import CloseIcon from "@mui/icons-material/Close"; const useStyles = makeStyles(theme => ({ root: { @@ -32,6 +33,19 @@ const useStyles = makeStyles(theme => ({ purple: { color: deepPurple[700], backgroundColor: deepPurple[500] + }, + tagsContainer: { + display: "flex", + flexWrap: "wrap", + marginTop: "1rem", + marginBottom: "1rem" + }, + chip: { + margin: theme.spacing(0.5) + }, + button: { + marginLeft: theme.spacing(1), + padding: "0.4rem 0.4rem" } })); @@ -43,10 +57,13 @@ const NewTutorial = ({ viewModal, onSidebarClick, viewCallback, active }) => { const [visible, setVisible] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); + const [tags, setTags] = useState([]); + const [newTag, setNewTag] = useState(""); const [formValue, setformValue] = useState({ title: "", summary: "", - owner: "" + owner: "", + tags: [] }); const loadingProp = useSelector( @@ -72,6 +89,13 @@ const NewTutorial = ({ viewModal, onSidebarClick, viewCallback, active }) => { setError(errorProp); }, [errorProp]); + useEffect(() => { + setformValue(prev => ({ + ...prev, + tags: tags + })); + }, [tags]); + const organizations = useSelector( ({ profile: { @@ -114,6 +138,14 @@ const NewTutorial = ({ viewModal, onSidebarClick, viewCallback, active }) => { : null; useEffect(() => { + setTags([]); + setNewTag(""); + setformValue({ + title: "", + summary: "", + owner: "", + tags: [] + }); setVisible(viewModal); }, [viewModal]); @@ -145,6 +177,24 @@ const NewTutorial = ({ viewModal, onSidebarClick, viewCallback, active }) => { })); }; + const handleAddTag = () => { + if (newTag.trim() !== "") { + setTags([...tags, newTag.trim()]); + setNewTag(""); + } + }; + + const handleDeleteTag = tagToDelete => { + setTags(tags.filter(tag => tag !== tagToDelete)); + }; + + const handleKeyDown = e => { + if (e.key === "Enter") { + e.preventDefault(); + handleAddTag(); + } + }; + const classes = useStyles(); return ( { background: "white", padding: "2rem", paddingTop: "1rem", - maxWidth: "80%" + maxWidth: "40%" }} > {error && ( - description={"Tutorial Creation Failed"}/ + description={"Tutorial Creation Failed"} )} Create a Tutorial @@ -226,6 +276,35 @@ const NewTutorial = ({ viewModal, onSidebarClick, viewCallback, active }) => { style={{ marginBottom: "2rem" }} /> + setNewTag(e.target.value)} + onKeyDown={handleKeyDown} + /> + + +
+ {tags.map((tag, index) => ( + handleDeleteTag(tag)} + className={classes.chip} + deleteIcon={} + /> + ))} +
+ @@ -240,7 +319,17 @@ const NewTutorial = ({ viewModal, onSidebarClick, viewCallback, active }) => {