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