diff --git a/src/components/BookmarkPage/index.jsx b/src/components/BookmarkPage/index.jsx new file mode 100644 index 00000000..0a8abfe0 --- /dev/null +++ b/src/components/BookmarkPage/index.jsx @@ -0,0 +1,378 @@ +import React, { useEffect, useState } from "react"; +import Card from "@mui/material/Card"; +import CardComponent from "../CodelabCard/index"; +import Typography from "@mui/material/Typography"; +import BottomNavigation from "@mui/material/BottomNavigation"; +import BottomNavigationAction from "@mui/material/BottomNavigationAction"; +import Box from "@mui/material/Box"; +import Grid from "@mui/material/Grid"; +import Divider from "@mui/material/Divider"; +import ListItem from "@mui/material/ListItem"; +import ListItemText from "@mui/material/ListItemText"; +import List from "@mui/material/List"; +import Tabs from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import TabContext from "@mui/lab/TabContext"; +import TabPanel from "@mui/lab/TabPanel"; +import EventAvailableIcon from "@mui/icons-material/EventAvailable"; +import EventSeatIcon from "@mui/icons-material/EventSeat"; +import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; +import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; +import { userList } from "../HomePage/userList"; +import useStyles from "./styles"; +import SideBar from "../SideBar/index"; +import TagCard from "../CardTabs/Tags/index"; +import EventsCard from "../CardTabs/Events/index"; +import OrgUser from "../../assets/images/org-user.svg"; +import UserCard from "../CardTabs/Users/index"; +import NewCodelabz from "../Topbar/NewCodelabz"; +import CardWithPicture from "../Card/CardWithPicture"; +import CardWithoutPicture from "../Card/CardWithoutPicture"; +import Activity from "../Topbar/Activity"; +import useWindowSize from "../../helpers/customHooks/useWindowSize"; +import NewTutorial from "../Tutorials/NewTutorial"; +import { useDispatch, useSelector } from "react-redux"; +import { useFirebase, useFirestore } from "react-redux-firebase"; +import { + getTutorialFeedData, + getTutorialFeedIdArray +} from "../../store/actions/tutorialPageActions"; + +function HomePage({ background = "white", textColor = "black" }) { + const classes = useStyles(); + const dispatch = useDispatch(); + const firebase = useFirebase(); + const firestore = useFirestore(); + const [value, setValue] = useState(2); + const [selectedTab, setSelectedTab] = useState("1"); + const [visibleModal, setVisibleModal] = useState(false); + const [footerContent, setFooterContent] = useState([ + { name: "Help", link: "https://dev.codelabz.io/" }, + { name: "About", link: "https://dev.codelabz.io/" }, + { name: "Content Policy", link: "https://dev.codelabz.io/" }, + { name: "Terms", link: "https://dev.codelabz.io/" }, + { name: "Privacy Policy", link: "https://dev.codelabz.io/" }, + { + name: `CodeLabz @${new Date().getFullYear()}`, + link: "https://dev.codelabz.io/" + } + ]); + + const windowSize = useWindowSize(); + const [openMenu, setOpen] = useState(false); + const toggleSlider = () => { + setOpen(!openMenu); + }; + const [upcomingEvents, setUpEvents] = useState([ + { + name: "Google Summer of Code", + img: [OrgUser], + date: "25 March, 2022" + }, + { + name: "Google Summer of Code", + img: [OrgUser], + date: "25 March, 2022" + }, + { + name: "Google Summer of Code", + img: [OrgUser], + date: "25 March, 2022" + }, + { + name: "Google Summer of Code", + img: [OrgUser], + date: "25 March, 2022" + } + ]); + const [tags, setTags] = useState([ + "HTML", + "JavaScript", + "Css", + "Python", + "React", + "Java", + "HTML", + "JavaScript", + "Css", + "Python", + "React", + "HTML", + "JavaScript", + "Css", + "Python", + "React", + "Java", + "HTML", + "JavaScript", + "Css", + "Python", + "React" + ]); + + const [usersToFollow, setUsersToFollow] = useState([ + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + }, + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + }, + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + }, + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + } + ]); + + const [contributors, setContributors] = useState([ + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + }, + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + }, + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + }, + { + name: "Janvi Thakkar", + img: [OrgUser], + desg: "Software Engineer", + onClick: {} + } + ]); + + const profileData = useSelector(({ firebase: { profile } }) => profile); + useEffect(() => { + const getFeed = async () => { + const tutorialIdArray = await getTutorialFeedIdArray(profileData.uid)( + firebase, + firestore, + dispatch + ); + getTutorialFeedData(tutorialIdArray)(firebase, firestore, dispatch); + }; + getFeed(); + }, [dispatch]); + const tutorials = useSelector( + ({ + tutorialPage: { + feed: { homepageFeedArray } + } + }) => homepageFeedArray.filter(tutorial => tutorial.bookmarked === true) + ); + + + const notification = () => {}; + const handleChange = (event, newValue) => { + setValue(newValue); + }; + const handleTabChange = (event, newValue) => { + setSelectedTab(newValue); + }; + const closeModal = () => { + setVisibleModal(prev => !prev); + }; + return ( + + + + {windowSize.width > 750 && ( + + + + + + )} + + + + + + {tutorials.map(tutorial => { + return !tutorial?.featured_image ? ( + + ) : ( + + ); + })} + + + + } + value="1" + style={{ width: "25%" }} + /> + } + value="2" + style={{ width: "25%" }} + /> + } + value="3" + style={{ width: "25%" }} + /> + } + value="4" + style={{ width: "25%" }} + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export default HomePage; diff --git a/src/components/BookmarkPage/styles.jsx b/src/components/BookmarkPage/styles.jsx new file mode 100644 index 00000000..069d3bce --- /dev/null +++ b/src/components/BookmarkPage/styles.jsx @@ -0,0 +1,100 @@ +import { makeStyles } from "@mui/styles"; + +const useStyles = makeStyles(theme => ({ + wrapper: { + display: "flex", + alignItems: "top", + justifyContent: "center", + height: "100%", + background: "#f2f2f2" + }, + mainBody: { + display: "flex", + alignContent: "center", + justifyContent: "center", + height: "100%", + margin: "1rem 0 2rem 0", + flexDirection: "column" + }, + sideBody: { + display: "flex", + alignContent: "center", + justifyContent: "center", + width: "fit-content", + margin: "1rem 1rem 2rem 1rem", + height: "100%", + flexDirection: "column", + [theme.breakpoints.down(960)]: { + display: "none" + }, + maxWidth: "300px" + }, + cardBody: { + display: "flex", + justifyContent: "space-between", + width: "100%", + alignItems: "center", + direction: "column" + }, + sort: { + width: "100%", + display: "flex", + alignItems: "center", + justifyContent: "space-between", + flexDirection: "row", + margin: "0rem 0 0rem 0" + }, + sortedList: { + display: "flex", + alignItems: "center", + justifyContent: "space-around", + flexDirection: "row", + width: "auto", + [theme.breakpoints.down(750)]: { + display: "none" + } + }, + navigation: { + "&:selcted": { + border: "2px solid black" + } + }, + sideCard: { + display: "flex", + alignItems: "center", + justifyContent: "center", + flexDirection: "column", + maxHeight: "35rem", + margin: "0 0 2rem 0", + background: "white", + boxShadow: ".5px 2px 5px gray" + }, + + leftSideCard: { + display: "flex", + alignItems: "left", + justifyContent: "center", + flexDirection: "column", + maxHeight: "35rem", + margin: "0 0 2rem 0", + background: "white", + boxShadow: ".5px 2px 5px gray" + }, + + outerSideBar: { + minWidth: "100%" + }, + contentPart: { + height: "100%", + display: "flex", + flexDirection: "row", + justifyContent: "center", + maxWidth: "1400px" + }, + card: { + padding: "6px", + margin: "0 0.5rem 0 0.5rem" + } +})); + +export default useStyles; diff --git a/src/components/Card/CardWithPicture.jsx b/src/components/Card/CardWithPicture.jsx index e8cd65c2..4210289e 100644 --- a/src/components/Card/CardWithPicture.jsx +++ b/src/components/Card/CardWithPicture.jsx @@ -22,6 +22,7 @@ import { Link } from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; import { useFirebase, useFirestore } from "react-redux-firebase"; import { getUserProfileData } from "../../store/actions"; +import { toggleTutorialBookmark } from "../../store/actions/tutorialsActions"; const useStyles = makeStyles(theme => ({ root: { @@ -74,6 +75,7 @@ const useStyles = makeStyles(theme => ({ export default function CardWithPicture({ tutorial }) { const classes = useStyles(); const [alignment, setAlignment] = React.useState("left"); + const [isBookmarked, setIsBookmarked] = React.useState(tutorial?.bookmarked); const [count, setCount] = useState(1); const dispatch = useDispatch(); const firebase = useFirebase(); @@ -90,6 +92,15 @@ export default function CardWithPicture({ tutorial }) { setAlignment(newAlignment); }; + const handleBookmark = event => { + toggleTutorialBookmark(tutorial?.tutorial_id)( + firebase, + firestore, + dispatch + ); + setIsBookmarked(prev => !prev); + }; + useEffect(() => { getUserProfileData(tutorial?.created_by)(firebase, firestore, dispatch); }, [tutorial]); @@ -221,8 +232,12 @@ export default function CardWithPicture({ tutorial }) { - - + + {isBookmarked ? : } diff --git a/src/components/Card/CardWithoutPicture.jsx b/src/components/Card/CardWithoutPicture.jsx index abc4ecb0..bb118fe8 100644 --- a/src/components/Card/CardWithoutPicture.jsx +++ b/src/components/Card/CardWithoutPicture.jsx @@ -13,6 +13,7 @@ import Chip from "@mui/material/Chip"; import ShareOutlinedIcon from "@mui/icons-material/ShareOutlined"; import ChatOutlinedIcon from "@mui/icons-material/ChatOutlined"; import TurnedInNotOutlinedIcon from "@mui/icons-material/TurnedInNotOutlined"; +import TurnedInIcon from "@mui/icons-material/TurnedIn"; import MoreVertOutlinedIcon from "@mui/icons-material/MoreVertOutlined"; import ToggleButton from "@mui/lab/ToggleButton"; import ToggleButtonGroup from "@mui/lab/ToggleButtonGroup"; @@ -21,6 +22,7 @@ import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import { useDispatch, useSelector } from "react-redux"; import { useFirebase, useFirestore } from "react-redux-firebase"; import { getUserProfileData } from "../../store/actions"; +import { toggleTutorialBookmark } from "../../store/actions/tutorialsActions"; const useStyles = makeStyles(theme => ({ root: { margin: "0.5rem", @@ -68,6 +70,7 @@ const useStyles = makeStyles(theme => ({ export default function CardWithoutPicture({ tutorial }) { const classes = useStyles(); const [alignment, setAlignment] = React.useState("left"); + const [isBookmarked, setIsBookmarked] = React.useState(tutorial?.bookmarked); const [count, setCount] = useState(1); const dispatch = useDispatch(); const firebase = useFirebase(); @@ -84,6 +87,15 @@ export default function CardWithoutPicture({ tutorial }) { setAlignment(newAlignment); }; + const handleBookmark = event => { + toggleTutorialBookmark(tutorial?.tutorial_id)( + firebase, + firestore, + dispatch + ); + setIsBookmarked(prev => !prev); + }; + useEffect(() => { getUserProfileData(tutorial?.created_by)(firebase, firestore, dispatch); }, [tutorial]); @@ -210,8 +222,16 @@ export default function CardWithoutPicture({ tutorial }) { - - + + {isBookmarked ? ( + + ) : ( + + )} diff --git a/src/components/HomePage/index.jsx b/src/components/HomePage/index.jsx index e8190e6b..318aabc2 100644 --- a/src/components/HomePage/index.jsx +++ b/src/components/HomePage/index.jsx @@ -175,7 +175,7 @@ function HomePage({ background = "white", textColor = "black" }) { getTutorialFeedData(tutorialIdArray)(firebase, firestore, dispatch); }; getFeed(); - }, []); + }, [dispatch]); const tutorials = useSelector( ({ tutorialPage: { diff --git a/src/routes.jsx b/src/routes.jsx index 39493a49..0e84863a 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -13,6 +13,7 @@ import Dashboard from "./components/Dashboard"; import Editor from "./components/Editor"; import NotFound from "./components/ErrorPages/404"; import HomePage from "./components/HomePage/index"; +import BookmarkPage from "./components/BookmarkPage/index" import ManageUsers from "./components/ManageUsers"; import MyFeed from "./components/MyFeed"; import Organization from "./components/Organization"; @@ -116,6 +117,11 @@ const Routes = () => { path={"/dashboard"} component={UserIsNotAllowedUserDashboard(Dashboard)} /> + async (firebase, firestore, dispatch) => { + try { + const tutorialRef = firestore.collection("tutorials").doc(tutorial_id); + const tutorialDoc = await tutorialRef.get(); + if (tutorialDoc.exists) { + const currentBookmarkedValue = tutorialDoc.data().bookmarked; + await tutorialRef.update({ + bookmarked: !currentBookmarkedValue, + updatedAt: firestore.FieldValue.serverTimestamp() + }); + } else { + console.error("Tutorial document does not exist"); + } + } catch (error) { + console.error("TOGGLE_TUTORIAL_BOOKMARK_FAIL", error); + } + }; + \ No newline at end of file