diff --git a/src/API/UserAPI.jsx b/src/API/UserAPI.jsx index b0345839..277d06aa 100644 --- a/src/API/UserAPI.jsx +++ b/src/API/UserAPI.jsx @@ -23,6 +23,7 @@ function UserAPI(token) { const [history, setHistory] = useState([]); const [user, setUser] = useState(initialState); const [authenticated, isAuthenticated] = useState(false); + const [cart, setCart] = useState([]); useEffect(() => { if (token) { @@ -31,6 +32,7 @@ function UserAPI(token) { const res = await axios.get("/api/user/info", { headers: { Authorization: token }, }); + console.log(res.data._id) setIsLoggedIn(true); isAuthenticated(true); setUser(res.data); @@ -44,11 +46,35 @@ function UserAPI(token) { } }, [token]); + const addCart = async (product) => { + if (!isLoggedIn) return alert("Please login to continue buying"); + + const check = cart.every((item) => { + return item._id !== product._id; + }); + + if (check) { + setCart([...cart, { ...product, quantity: 1 }]); + + await axios.patch( + "/api/user/addcart", + { cart: [...cart, { ...product, quantity: 1 }] }, + { + headers: { Authorization: token }, + } + ); + } else { + alert("This product has been added to the cart"); + } + }; + return { isLoggedIn: [isLoggedIn, setIsLoggedIn], isAdmin: [isAdmin, setIsAdmin], history: [history, setHistory], user: [user, setUser], + cart: [cart, setCart], + addCart: addCart, authenticated: [authenticated, isAuthenticated], }; } diff --git a/src/Components/Article/MainContainer.jsx b/src/Components/Article/MainContainer.jsx index 2db91a48..31097350 100644 --- a/src/Components/Article/MainContainer.jsx +++ b/src/Components/Article/MainContainer.jsx @@ -1,98 +1,72 @@ import React from 'react'; import Alert from 'react-bootstrap/Alert' -import { AiFillStar, AiFillPlayCircle, AiFillTwitterCircle } from 'react-icons/ai'; -import {FaRegThumbsUp, FaRegComment, FaFacebook} from 'react-icons/fa'; -import {TiSocialLinkedinCircular} from 'react-icons/ti'; -import {MdBookmarkBorder} from 'react-icons/md'; -import {RiShareCircleFill} from 'react-icons/ri'; -import Sticky from 'react-sticky-state'; +import { AiFillStar, AiFillPlayCircle } from 'react-icons/ai'; import {JustifyContent, StyledMainContainer, PaddingContent, BlogCard, BlogPost} from '../../Layout/Container/styledArticle'; import {CircleImage, BlogDisplayImage} from '../../Layout/Image/styledImage'; import {NamePlate, WarppedDate, GrayText, DisplayItem, BlogTitle, BlogSubTitle, - BlogPhotoCredit, BlogContent, Font2} from '../../Layout/Text/styledText'; + BlogPhotoCredit, BlogContent} from '../../Layout/Text/styledText'; import {ArticleHr} from '../../Layout/Hr/styledHr'; import {AlertP} from '../../Layout/Paragraph/styledParagraph'; import {AlertLink} from '../../Layout/ATag/styledATag'; import marked from 'marked'; -import './StickyState.css'; import Newsletter from '../Subscribe/Newsletter'; import RelatedPosts from './RelatedPosts'; +import StickyFooter from '../Sticky/StickyFooter'; const MainContainer = (props) => { - const { title, subtitle, description, images, markdown } = props.detailArticle; + const { title, subtitle, description, images, markdown } = props.detailArticle; const timeFormater = props.timeFormater; const readTime = props.readTime; return ( - -
- - - You have 1 free member-only story left this month.  - Sign up for Medium and get an extra one. - - - - -
- Will Smith - - {timeFormater} -  ·  - {readTime} min read   -  ·  -   Listen - -
-
- - {title} - {subtitle} - - Photo Credit by You - -
- -
- {description} -
-
- -
- -
- - - - -   1 - - -   1 - - - - - - - - - - -
-
- -
- {/* props.handleCheck(_id)} /> */} - {/* */} -
-
-
- + +
+ + + You have 1 free member-only story left this month.  + Sign up for Medium and get an extra one. + + + + +
+ Will Smith + + {timeFormater} +  ·  + {readTime} min read   +  ·  +   Listen + +
+
+ + {title} + {subtitle} + + Photo Credit by You + +
+ +
+ {description} +
+
+ +
+ + +
+ {/* props.handleCheck(_id)} /> */} + {/* */} +
+
+
+
) } diff --git a/src/Components/Loading/Loading.css b/src/Components/Loading/Loading.css new file mode 100644 index 00000000..38c8e6c4 --- /dev/null +++ b/src/Components/Loading/Loading.css @@ -0,0 +1,28 @@ +.load-page { + background: white; + overflow: hidden; +} + +.loader { + width: 300px; + height: 300px; + margin: auto; +} + +.loader div { + width: calc(100% - 15px); + height: calc(100% - 15px); + border: 2px solid #fff; + border-top: 2px solid lavender; + border-radius: 50%; + animation: rotate 10s linear infinite alternate-reverse; +} + +@keyframes rotate { + 50% { + transform: rotate(80deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/Components/Loading/Loading.jsx b/src/Components/Loading/Loading.jsx new file mode 100644 index 00000000..2e4181ca --- /dev/null +++ b/src/Components/Loading/Loading.jsx @@ -0,0 +1,29 @@ +import React from 'react'; + +import './Loading.css'; + +const Loading = () => { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) +} + +export default Loading; diff --git a/src/Components/NavBar/NavBar.jsx b/src/Components/NavBar/NavBar.jsx index 8d42dc43..c63f8468 100755 --- a/src/Components/NavBar/NavBar.jsx +++ b/src/Components/NavBar/NavBar.jsx @@ -5,6 +5,8 @@ import { Link } from "react-router-dom"; import Logo from '../../Assets/Images/logo-min.png'; import { GlobalState } from '../../GlobalState'; import {StyledHr} from '../../Layout/Hr/styledHr'; +import axios from "axios"; +import { AiOutlineShoppingCart } from 'react-icons/ai'; const NavBar = () => { @@ -12,11 +14,47 @@ const NavBar = () => { const [isLoggedIn] = state.userAPI.isLoggedIn const [isAdmin] = state.userAPI.isAdmin const [user] = state.userAPI.user + const [cart] = state.userAPI.cart; const [isActive, toggle] = useReducer( (isActive) => !isActive, true ); + const logoutUser = async () => { + await axios.post("/api/user/logout"); + localStorage.removeItem("firstLogin"); + window.location.href = "/"; + }; + + const adminRouter = () => { + return ( + <> + Create Product + Products + {/* Admin User Management */} + Users + + )}; + + const loggedInRouter = () => { + return ( + <> + Profile + Shop + History +
+ {cart.length} + + {" "} + + {/* Shoppingcart */} + +
+ Settings + Logout + + )}; + return (
@@ -30,40 +68,45 @@ const NavBar = () => { !isLoggedIn ? HoseaCodes : -

Welcome, {user.name.split(' ')[0]}

+

Welcome, {user.name.split(' ')[0]}

} diff --git a/src/Components/NavBar/SideBar.jsx b/src/Components/NavBar/SideBar.jsx index 6bc15221..644e7afe 100644 --- a/src/Components/NavBar/SideBar.jsx +++ b/src/Components/NavBar/SideBar.jsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useContext } from "react"; import {StyledLeftContainer, JustifyContent} from '../../Layout/Container/styledArticle'; import {LogoImage} from '../../Layout/Image/styledImage'; import {StackedAlignn} from '../../Layout/Icon/styledIcons'; @@ -7,20 +7,47 @@ import {HiOutlinePencilAlt} from 'react-icons/hi'; import {BsHouseDoor, BsBell} from 'react-icons/bs'; import {MdBookmarkBorder} from 'react-icons/md'; import logo from '../../Assets/Images/newLogo.png'; +import { Link } from "react-router-dom"; +import {GlobalState} from '../../GlobalState'; const SideBar = () => { + const state = useContext(GlobalState); + + const [isAdmin] = state.userAPI.isAdmin; + + const handleUnauthorized = async e => { + e.preventDefault(); + // Pass the error to display through state + alert("You are not authorized to make a post. If you create an account you can begin making posts.") + } + + const handleSave = async e => { + e.preventDefault(); + // Create save post function on backend + alert("Save the post to user profile.") + } + + const handleNotification = async e => { + e.preventDefault(); + // Create notification function on backend + alert("Start being alerted when user makes posts.") + } return ( - - - + + + - + {isAdmin ? + + : + + } ) diff --git a/src/Components/Sticky/StickyFooter.jsx b/src/Components/Sticky/StickyFooter.jsx new file mode 100644 index 00000000..7e80ce32 --- /dev/null +++ b/src/Components/Sticky/StickyFooter.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import Sticky from 'react-sticky-state'; +import {ArticleHr} from '../../Layout/Hr/styledHr'; +import {AiFillTwitterCircle } from 'react-icons/ai'; +import {FaRegThumbsUp, FaRegComment, FaFacebook} from 'react-icons/fa'; +import {Font2} from '../../Layout/Text/styledText'; +import {JustifyContent} from '../../Layout/Container/styledArticle'; +import {MdBookmarkBorder} from 'react-icons/md'; +import {RiShareCircleFill} from 'react-icons/ri'; +import {TiSocialLinkedinCircular} from 'react-icons/ti'; +import './StickyState.css'; + +const StickyFooter = () => { + return ( + +
+ + + + +   1 + + +   1 + + + + + + + + + + +
+
+ ) +} + +export default StickyFooter; diff --git a/src/Components/Article/StickyState.css b/src/Components/Sticky/StickyState.css similarity index 100% rename from src/Components/Article/StickyState.css rename to src/Components/Sticky/StickyState.css diff --git a/src/Components/User/ListUser.jsx b/src/Components/User/ListUser.jsx new file mode 100644 index 00000000..fede8c09 --- /dev/null +++ b/src/Components/User/ListUser.jsx @@ -0,0 +1,174 @@ +import React, { useState, useContext, useEffect } from 'react' +import { Button, Row, Table, Card, Col, Form, + Container, } from 'react-bootstrap'; +import {CircleImage} from '../../Layout/Image/styledImage'; +import { GlobalState } from '../../GlobalState'; +import axios from "axios"; +import moment from 'moment-timezone' +import NavBar from '../NavBar/NavBar'; +import Footer from '../Footer/Footer'; + +const initialState = { + name: "", + email: "", + password: "", + role: 0 +} +const UsersList = () => { + const state = useContext(GlobalState) + const [user] = state.userAPI.user + const [users, setUsers] = useState([]) + const [active, setActive] = useState(false) + const [userView, setUserView] = useState(false) + const [createdUser, setCreatedUser] = useState(initialState); + + useEffect(() => { + const getAllUsers = async () => { + const res = await axios.get(`/api/user/${user._id}`) + console.log(res) + console.log(users) + setUsers(res.data.users) + } + getAllUsers() +}, [user, active]) + +const deleteUser = async (id) => { + try { + const deleteUser = axios.delete(`/api/user/${id}`) + await deleteUser + setActive(!active) + } catch (err) { + alert(err.response.data.msg) + } +} + +const addUser = async () => { + try { + const addUser = axios.post(`/api/user/register`, { ...createdUser }) + await addUser + setUserView(false) + } catch (err) { + alert(err.response.data.msg) + } +} + + const timeFormater = (date) => { + return moment.utc(date).format('MMMM Do') + } + + const joinedDate = (date) => { + const today = new Date() + const year = today.getFullYear() + const month = today.getMonth() + const createdDateYear = moment.utc(date).format('YYYY') + const createdDateMonth = moment.utc(date).format('M') + const returnYear = year - createdDateYear + const returnMonth = createdDateMonth - month + return `${returnMonth} Mon. ${returnYear} Yr.` + } + + const handleChangeInput = e => { + const { name, value } = e.target + console.log(name) + console.log(value) + setCreatedUser({ ...createdUser, [name]: value }) +} + +const {name, email, password, role} = createdUser; + + const addUserView = () => { + return ( + <> + + + +

Add User

+
+ + +
+ + + Name + + + + Role + + + + + Email + + + + Password + + + + +
+
+
+
+