diff --git a/src/components/FeatureCard/FeatureCard.css b/docs/Firebase Backend.md similarity index 100% rename from src/components/FeatureCard/FeatureCard.css rename to docs/Firebase Backend.md diff --git a/src/components/Newsletter/Newsletter.js b/docs/React Frontend.md similarity index 100% rename from src/components/Newsletter/Newsletter.js rename to docs/React Frontend.md diff --git a/public/google (2).png b/public/google (2).png deleted file mode 100644 index a682471..0000000 Binary files a/public/google (2).png and /dev/null differ diff --git a/src/App.js b/src/App.js index 489be62..f9dcd29 100644 --- a/src/App.js +++ b/src/App.js @@ -1,16 +1,15 @@ import React from 'react'; import './App.css'; import { Routes, Route } from "react-router-dom"; -import Homepage from './pages/Homepage'; -import Onboard from "./pages/Onboard" -import Feed from "./pages/Feed" -import Dashboard from "./pages/Dashboard" -import ProtectedRoute from './Protect/ProtectedRoute'; -import Tos from "./pages/Tos" -import Write from './pages/Write'; -import NotFound from "./pages/NotFound" +import Homepage from './pages/homepage'; +import Onboard from "./pages/onboard" +import Feed from "./pages/feed" +import Dashboard from "./pages/dashboard" +import ProtectedRoute from './protect/ProtectedRoute'; +import Tos from "./pages/tos" +import Write from './pages/write'; +import NotFound from "./pages/notfound" import Article from "./components/Article/Article" -import UserProfile from './pages/UserProfile'; import { useUserAuth } from './context/UserAuthContext' @@ -25,13 +24,13 @@ function App() { } /> } /> - {user ? ( + { user ? ( null - ) : } />} + ) : } /> + } } /> } /> - } /> } /> } /> } /> diff --git a/src/pages/facebook.png b/src/assets/facebook.png similarity index 100% rename from src/pages/facebook.png rename to src/assets/facebook.png diff --git a/src/pages/github.png b/src/assets/github.png similarity index 100% rename from src/pages/github.png rename to src/assets/github.png diff --git a/src/pages/google.png b/src/assets/google.png similarity index 100% rename from src/pages/google.png rename to src/assets/google.png diff --git a/src/components/Navbar/logo.png b/src/assets/logo.png similarity index 100% rename from src/components/Navbar/logo.png rename to src/assets/logo.png diff --git a/src/pages/not.png b/src/assets/not.png similarity index 100% rename from src/pages/not.png rename to src/assets/not.png diff --git a/src/pages/twitter.png b/src/assets/twitter.png similarity index 100% rename from src/pages/twitter.png rename to src/assets/twitter.png diff --git a/src/components/Article/AddArticle.js b/src/components/Article/AddArticle.js deleted file mode 100644 index 417caa8..0000000 --- a/src/components/Article/AddArticle.js +++ /dev/null @@ -1,211 +0,0 @@ - -import React, { Fragment, useState ,useCallback} from 'react'; -import Box from '@mui/material/Box'; -import TextField from '@mui/material/TextField'; -import { Button, Container, Stack, Typography } from '@mui/material'; -import { Timestamp, collection, addDoc } from "firebase/firestore" -import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage" -import { storage, db } from "../../firebase/firebase.utils" -import { toast } from "react-toastify"; -import { useNavigate } from "react-router-dom" -import { useUserAuth } from '../../context/UserAuthContext' -import SimpleMdeReact from 'react-simplemde-editor'; -import { makeStyles } from "@material-ui/styles"; -import 'easymde/dist/easymde.min.css'; - - - -const useStyles = makeStyles({ - input: { - color: "white" - } -}); - -export default function AddArticle() { - const [value, setValue] = useState("Tell your story..."); - - const onChange = useCallback((value) => { - setValue(value); - console.log(value) - }, []); - - - - const classes = useStyles(); - - const { user } = useUserAuth(); - - const navigate = useNavigate() - - - const [formData, setFormData] = useState({ - title: "", - image: "", - createdAt: Timestamp.now().toDate(), - }); - - - const handleChange = (e) => { - setFormData({ ...formData, [e.target.name]: e.target.value }); - - }; - - const handleImageChange = (e) => { - setFormData({ ...formData, image: e.target.files[0] }); - }; - - const handlePublish = () => { - if (!formData.title || !value || !formData.image) { - toast("Please fill all the fields", { type: "error" }); - return; - } - - - const storageRef = ref( - storage, - `/images/${Date.now()}${formData.image.name}` - ); - - const uploadImage = uploadBytesResumable(storageRef, formData.image); - - uploadImage.on( - (err) => { - console.log(err); - }, - - () => { - setFormData({ - title: "", - - image: "", - }); - - getDownloadURL(uploadImage.snapshot.ref).then((url) => { - - const articleRef = collection(db, "Articles"); - - addDoc(articleRef, { - title: formData.title, - description: value, - thumbnail: url, - createdAt: Timestamp.now().toDate(), - createdBy: user.displayName, - userId: user.uid, - userImg: user.photoURL, - likes: [], - comments: [] - }) - - - .then(() => { - - toast("Article added successfully", { type: "success" }); - navigate("/dashboard") - - }) - .catch((err) => { - toast("Error adding article", { type: "error" }); - }); - - }); - - - } - ); - - - - } - return ( - - - - - - - - Create A Post - - - {/*
- - -
*/} - handleChange(e)} - /> - -


- {/* handleChange(e)} - - /> */} - - - - {formData.image.name} - - {/* Markdown Editor */} - - - - - -
-
-
-
- - - - - ); -} diff --git a/src/components/Article/AddArticle.jsx b/src/components/Article/AddArticle.jsx new file mode 100644 index 0000000..8e9fed9 --- /dev/null +++ b/src/components/Article/AddArticle.jsx @@ -0,0 +1,162 @@ +import React, { Fragment, useState, useCallback } from 'react' +import Box from '@mui/material/Box' +import TextField from '@mui/material/TextField' +import { Button, Container, Stack, Typography } from '@mui/material' +import { Timestamp, collection, addDoc } from 'firebase/firestore' +import { ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage' +import { storage, db } from '../../firebase/firebase.utils' +import { toast } from 'react-toastify' +import { useNavigate } from 'react-router-dom' +import { useUserAuth } from '../../context/UserAuthContext' +import SimpleMdeReact from 'react-simplemde-editor' +import { makeStyles } from '@material-ui/styles' +import 'easymde/dist/easymde.min.css' + +const useStyles = makeStyles({ + input: { + color: 'white', + }, +}) + +export default function AddArticle() { + const [value, setValue] = useState('Tell your story...') + + const onChange = useCallback((value) => { + setValue(value) + console.log(value) + }, []) + + const classes = useStyles() + + const { user } = useUserAuth() + + const navigate = useNavigate() + + const [formData, setFormData] = useState({ + title: '', + image: '', + createdAt: Timestamp.now().toDate(), + }) + + const handleChange = (e) => { + setFormData({ ...formData, [e.target.name]: e.target.value }) + } + + const handleImageChange = (e) => { + setFormData({ ...formData, image: e.target.files[0] }) + } + + const handlePublish = () => { + if (!formData.title || !value || !formData.image) { + toast('Please fill all the fields', { type: 'error' }) + return + } + + const storageRef = ref( + storage, + `/images/${Date.now()}${formData.image.name}` + ) + + const uploadImage = uploadBytesResumable(storageRef, formData.image) + + uploadImage.on( + (err) => { + console.log(err) + }, + + () => { + setFormData({ + title: '', + image: '', + }) + + getDownloadURL(uploadImage.snapshot.ref).then((url) => { + const articleRef = collection(db, 'Articles') + + addDoc(articleRef, { + title: formData.title, + description: value, + thumbnail: url, + createdAt: Timestamp.now().toDate(), + createdBy: user.displayName, + userId: user.uid, + userImg: user.photoURL, + likes: [], + comments: [], + }) + .then(() => { + toast('Article added successfully', { type: 'success' }) + navigate('/dashboard') + }) + .catch((err) => { + toast('Error adding article', { type: 'error' }) + }) + }) + } + ) + } + return ( + + + + + Create A Post + + + handleChange(e)} + /> + + + {formData.image.name} + {/* Markdown Editor */} + + + + + + + ) +} diff --git a/src/components/Article/Article.js b/src/components/Article/Article.js deleted file mode 100644 index eb8a9da..0000000 --- a/src/components/Article/Article.js +++ /dev/null @@ -1,87 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { Link, useParams } from "react-router-dom"; -import { doc, onSnapshot } from "firebase/firestore"; -import { db } from "../../firebase/firebase.utils" -import { Avatar } from "@mui/material"; -import Comments from "./Comments" -import Navbar from "../Navbar/Navbar" - - -import ReactMarkdown from 'react-markdown' -import remarkGfm from 'remark-gfm' -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" -import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism" - - - -export default function Article() { - const { id } = useParams(); - const [article, setArticle] = useState(null); - useEffect(() => { - const docRef = doc(db, "Articles", id); - onSnapshot(docRef, (snapshot) => { - setArticle({ ...snapshot.data(), id: snapshot.id }); - }); - }, [id]); - - - - return ( - <> - - -
- {article && ( -
- -

{article.title}

- - - - - {/*

{article.createdBy}

*/} - - - -

-
- -
- -
- - -
- )} -
- - ) -} - - - -const Component = ({ language, value }) => { - - return ( - - {value ?? ""} - - ); - -}; - - diff --git a/src/components/Article/Article.jsx b/src/components/Article/Article.jsx new file mode 100644 index 0000000..9a68b0c --- /dev/null +++ b/src/components/Article/Article.jsx @@ -0,0 +1,90 @@ +import React, { useEffect, useState } from 'react' +import { useParams } from 'react-router-dom' +import { doc, onSnapshot } from 'firebase/firestore' +import { db } from '../../firebase/firebase.utils' +// import { Avatar} from '@mui/material' +import Comments from './Comments' +import Navbar from '../Navbar/Navbar' +import ReactMarkdown from 'react-markdown' +import remarkGfm from 'remark-gfm' +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' +import { materialDark } from 'react-syntax-highlighter/dist/esm/styles/prism' + +export default function Article() { + const { id } = useParams() + const [article, setArticle] = useState(null) + useEffect(() => { + const docRef = doc(db, 'Articles', id) + onSnapshot(docRef, (snapshot) => { + setArticle({ ...snapshot.data(), id: snapshot.id }) + }) + }, [id]) + + return ( + <> + +
+ {article && ( +
+

+ {article.title} +

+ +
+
+ {/* + + */} +
+

+
+ +
+
+ +
+ )} +
+ + ) +} + +const Component = ({ language, value }) => { + return ( + + {value ?? ''} + + ) +} diff --git a/src/components/Article/Articles.js b/src/components/Article/Articles.js deleted file mode 100644 index f2f7536..0000000 --- a/src/components/Article/Articles.js +++ /dev/null @@ -1,97 +0,0 @@ -import { Avatar, Card, CardContent, CardHeader, CardMedia, Grid, IconButton, Typography } from '@mui/material' -import { collection, onSnapshot, orderBy, query } from 'firebase/firestore' -import React, { useEffect, useState } from 'react' -import { db } from "../../firebase/firebase.utils" -import FavoriteIcon from '@mui/icons-material/Favorite'; -import CardActions from '@mui/material/CardActions'; -import { Link } from 'react-router-dom'; - - - -export default function Articles() { - const [articles, setArticles] = useState([]); - - - useEffect(() => { - const articleRef = collection(db, "Articles"); - const q = query(articleRef, orderBy("createdAt", "desc")); - onSnapshot(q, (snapshot) => { - console.log(onSnapshot) - const articles = snapshot.docs.map((doc) => ({ - id: doc.id, - ...doc.data(), - })); - - setArticles(articles); - console.log(articles); - }); - }, []); - - - return ( - <> - - - { - articles.length === 0 ? ( -

No articles

- - ) : (articles.map(({ - id, - title, - description, - thumbnail, - createdAt, - createdBy, - userId, - userImg, - likes, - comments, - }) => ( - - - - - - - - - - - {title} - - - - - - - - - } - - title={createdBy} - subheader={createdAt.toDate().toDateString()} - action={ - - - - - } - /> - - - - - - )) - ) - } -
- - - ) - -} diff --git a/src/components/Article/Articles.jsx b/src/components/Article/Articles.jsx new file mode 100644 index 0000000..ced80bf --- /dev/null +++ b/src/components/Article/Articles.jsx @@ -0,0 +1,108 @@ +import { + Avatar, + Card, + CardContent, + CardHeader, + CardMedia, + Grid, + IconButton, + Typography, +} from '@mui/material' +import { collection, onSnapshot, orderBy, query } from 'firebase/firestore' +import React, { useEffect, useState } from 'react' +import { db } from '../../firebase/firebase.utils' +import FavoriteIcon from '@mui/icons-material/Favorite' +import CardActions from '@mui/material/CardActions' +import { Link } from 'react-router-dom' + +export default function Articles() { + const [articles, setArticles] = useState([]) + + useEffect(() => { + const articleRef = collection(db, 'Articles') + const q = query(articleRef, orderBy('createdAt', 'desc')) + onSnapshot(q, (snapshot) => { + console.log(onSnapshot) + const articles = snapshot.docs.map((doc) => ({ + id: doc.id, + ...doc.data(), + })) + + setArticles(articles) + console.log(articles) + }) + }, []) + + return ( + <> + + {articles.length === 0 ? ( +

No articles

+ ) : ( + articles.map( + ({ + id, + title, + description, + thumbnail, + createdAt, + createdBy, + userId, + userImg, + likes, + comments, + }) => ( + + + + + + + + {title} + + + + + + + } + title={createdBy} + subheader={createdAt.toDate().toDateString()} + action={ + + + + + + } + /> + + ) + ) + )} +
+ + ) +} diff --git a/src/components/Article/Comments.js b/src/components/Article/Comments.js deleted file mode 100644 index c1df3c5..0000000 --- a/src/components/Article/Comments.js +++ /dev/null @@ -1,36 +0,0 @@ -import React, { Component } from 'react' - -export default class Comments extends Component { - constructor(props) { - super(props); - this.commentBox = React.createRef(); - } - - componentDidMount() { - let scriptEl = document.createElement("script"); - scriptEl.setAttribute("src", "https://giscus.app/client.js") - scriptEl.setAttribute("crossorigin", "anonymous") - scriptEl.setAttribute("async", true) - scriptEl.setAttribute("data-repo", "wisdomekpotu/devhouse") - scriptEl.setAttribute("issue-term", "title") - scriptEl.setAttribute("data-repo-id", "R_kgDOHIrJQA") - scriptEl.setAttribute("data-reactions-enabled", "1") - scriptEl.setAttribute("data-category-id", "DIC_kwDOHIrJQM4CPLPC") - scriptEl.setAttribute("data-category", "Comments") - scriptEl.setAttribute("data-theme", "dark") - scriptEl.setAttribute("data-lang", "en") - scriptEl.setAttribute("data-input-position", "bottom") - scriptEl.setAttribute("data-emit-metadata", "0") - scriptEl.setAttribute("data-mapping", "pathname") - scriptEl.setAttribute("theme", "github-light") - this.commentBox.current.appendChild(scriptEl) - } - - render() { - return ( -
-
-
- ) - } -} \ No newline at end of file diff --git a/src/components/Article/Comments.jsx b/src/components/Article/Comments.jsx new file mode 100644 index 0000000..f00231f --- /dev/null +++ b/src/components/Article/Comments.jsx @@ -0,0 +1,31 @@ +import React, { createRef, useEffect } from 'react' + +export default function Comments() { + const commentBox = createRef() + + useEffect(() => { + let scriptEl = document.createElement('script') + scriptEl.setAttribute('src', 'https://giscus.app/client.js') + scriptEl.setAttribute('crossorigin', 'anonymous') + scriptEl.setAttribute('async', true) + scriptEl.setAttribute('data-repo', 'wisdomekpotu/devhouse') + scriptEl.setAttribute('issue-term', 'title') + scriptEl.setAttribute('data-repo-id', 'R_kgDOHIrJQA') + scriptEl.setAttribute('data-reactions-enabled', '1') + scriptEl.setAttribute('data-category-id', 'DIC_kwDOHIrJQM4CPLPC') + scriptEl.setAttribute('data-category', 'Comments') + scriptEl.setAttribute('data-theme', 'dark') + scriptEl.setAttribute('data-lang', 'en') + scriptEl.setAttribute('data-input-position', 'bottom') + scriptEl.setAttribute('data-emit-metadata', '0') + scriptEl.setAttribute('data-mapping', 'pathname') + scriptEl.setAttribute('theme', 'github-light') + commentBox.current.appendChild(scriptEl) + }, [commentBox]) + + return ( +
+
+
+ ) +} diff --git a/src/components/Article/DeleteArticle.js b/src/components/Article/DeleteArticle.js deleted file mode 100644 index 4c1b882..0000000 --- a/src/components/Article/DeleteArticle.js +++ /dev/null @@ -1,32 +0,0 @@ -import { Button } from '@mui/material' -import { deleteDoc, doc } from 'firebase/firestore' -import { deleteObject, ref } from 'firebase/storage' -import React from 'react' -import { toast } from 'react-toastify' -import { db, storage } from '../../firebase/firebase.utils' - -export default function DeleteArticle ({id, thumbnail}) { - - - const handleDelete = async () =>{ - - try { - await deleteDoc(doc(db, "Articles", id)) - toast("Article Deleted", { type: "success" }); - - const storageRef = ref(storage, thumbnail) -await deleteObject(storageRef) - } catch (error) { - toast("Article Not Deleted", { type: "error" }); - console.log(error) - - } - - } - return ( -
- - -
- ) -} diff --git a/src/components/Article/DeleteArticle.jsx b/src/components/Article/DeleteArticle.jsx new file mode 100644 index 0000000..0e41006 --- /dev/null +++ b/src/components/Article/DeleteArticle.jsx @@ -0,0 +1,30 @@ +import { Button } from '@mui/material' +import { deleteDoc, doc } from 'firebase/firestore' +import { deleteObject, ref } from 'firebase/storage' +import { toast } from 'react-toastify' +import { db, storage } from '../../firebase/firebase.utils' + +export default function DeleteArticle({ id, thumbnail }) { + const handleDelete = async () => { + try { + await deleteDoc(doc(db, 'Articles', id)) + toast('Article Deleted', { type: 'success' }) + + const storageRef = ref(storage, thumbnail) + await deleteObject(storageRef) + } catch (error) { + toast('Article Not Deleted', { type: 'error' }) + console.log(error) + } + } + return ( +
+ +
+ ) +} diff --git a/src/components/Article/EditArticle.js b/src/components/Article/EditArticle.js deleted file mode 100644 index d0b0c4b..0000000 --- a/src/components/Article/EditArticle.js +++ /dev/null @@ -1,20 +0,0 @@ -import { Button } from '@mui/material' -import { deleteDoc, doc } from 'firebase/firestore' -import { deleteObject, ref } from 'firebase/storage' -import React from 'react' -import { toast } from 'react-toastify' -import { db, storage } from '../../firebase/firebase.utils' - -export default function EditArticle ({id, thumbnail}) { - - - const handleEdit = async () =>{ - - - } - return ( -
- -
- ) -} diff --git a/src/components/Article/EditArticle.jsx b/src/components/Article/EditArticle.jsx new file mode 100644 index 0000000..df443a2 --- /dev/null +++ b/src/components/Article/EditArticle.jsx @@ -0,0 +1,15 @@ +import { Button } from '@mui/material' + +export default function EditArticle({ id, thumbnail }) { + const handleEdit = async () => {} + return ( +
+ +
+ ) +} diff --git a/src/components/Card/Card.jsx b/src/components/Card/Card.jsx deleted file mode 100644 index d278c0a..0000000 --- a/src/components/Card/Card.jsx +++ /dev/null @@ -1,63 +0,0 @@ -import * as React from 'react'; -import Card from '@mui/material/Card'; -import CardHeader from '@mui/material/CardHeader'; -import CardMedia from '@mui/material/CardMedia'; -import CardContent from '@mui/material/CardContent'; -import Avatar from '@mui/material/Avatar'; -import IconButton from '@mui/material/IconButton'; -import Typography from '@mui/material/Typography'; -import { red } from '@mui/material/colors'; -import FavoriteIcon from '@mui/icons-material/Favorite'; -import ShareIcon from '@mui/icons-material/Share'; -import MoreVertIcon from '@mui/icons-material/MoreVert'; - - -export default function card() { - - return ( - - - - - - Building a Progressive Web App with React 18 - - {/* - This impressive paella is a perfect party dish and a fun meal to cook - together with your guests... - - */} - - - R - - } - action={ - - - - - - - - - } - - - title="wisdom ekpotu" - subheader="September 14, 2016" - /> - - - - ); -} diff --git a/src/components/DashControl/DashControl.js b/src/components/DashControl/DashControl.jsx similarity index 54% rename from src/components/DashControl/DashControl.js rename to src/components/DashControl/DashControl.jsx index 61aecf6..6e6ad34 100644 --- a/src/components/DashControl/DashControl.js +++ b/src/components/DashControl/DashControl.jsx @@ -1,12 +1,10 @@ -import React from 'react' import Table from '../Table/Table' - export default function DashControl() { return ( <> -

My Articles

- +

My Articles

+
) } diff --git a/src/components/EventCard/EventCard.js b/src/components/EventCard/EventCard.js deleted file mode 100644 index 2bcee4e..0000000 --- a/src/components/EventCard/EventCard.js +++ /dev/null @@ -1,43 +0,0 @@ -import { CardActionArea, Stack } from '@mui/material'; -import Card from '@mui/material/Card'; -import CardMedia from '@mui/material/CardMedia'; - -export default function EventCard() { - return ( -
- - - - - - - - - - - - - - - - - -
- ); -} diff --git a/src/components/FeatureCard/FeatureCard.jsx b/src/components/FeatureCard/FeatureCard.jsx index d8412e7..fe70059 100644 --- a/src/components/FeatureCard/FeatureCard.jsx +++ b/src/components/FeatureCard/FeatureCard.jsx @@ -1,48 +1,68 @@ -import * as React from 'react'; -import "./FeatureCard.css" -import Typography from '@mui/material/Typography'; -import { Stack } from '@mui/material'; - - -export default function card() { +import Typography from '@mui/material/Typography' +import { Stack } from '@mui/material' +export default function FeatureCard() { return ( - - - - Instantly find your audience - - Devhouse publishes your articles and distributes them to the dev community through the feedpage. - + + + Instantly find your audience + + Devhouse publishes your articles and distributes them to the dev + community through the feedpage. - - - + - - No annoying ads/pop-ups - - - Devhouse is and always will be a free platform for knowledge sharing. + + No annoying ads/pop-ups + + Devhouse is and always will be a free platform for knowledge sharing. - - - - - - Write in Markdown - - + -Write your content in a distraction-free Markdown editor with proper syntax highlighting and see live previews instantly - - - - - - - - ); + + Write in Markdown + + Write your content in a distraction-free Markdown editor with proper + syntax highlighting and see live previews instantly + + + + ) } diff --git a/src/components/FeaturedArticles/FeaturedArticles.js b/src/components/FeaturedArticles/FeaturedArticles.js deleted file mode 100644 index 57210e5..0000000 --- a/src/components/FeaturedArticles/FeaturedArticles.js +++ /dev/null @@ -1,47 +0,0 @@ -import Card from '@mui/material/Card'; -import CardHeader from '@mui/material/CardHeader'; -import CardMedia from '@mui/material/CardMedia'; -import CardContent from '@mui/material/CardContent'; -import Avatar from '@mui/material/Avatar'; -import IconButton from '@mui/material/IconButton'; -import Typography from '@mui/material/Typography'; -import { red } from '@mui/material/colors'; -import MoreVertIcon from '@mui/icons-material/MoreVert'; - - -export default function FeaturedArticles() { - - return ( - - - - - - A Dive into React Storybook - - - - - R - - } - action={ - - - - } - title="Shrimp and Chorizo Paella" - subheader="September 14, 2016" - /> - - - - ); -} diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx deleted file mode 100644 index 6cf08cd..0000000 --- a/src/components/Footer/Footer.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react' - -export default function Footer() { - return ( -
Footer
- ) -} diff --git a/src/components/Hero/Hero.css b/src/components/Hero/Hero.css index 9b68fb4..0e803c0 100644 --- a/src/components/Hero/Hero.css +++ b/src/components/Hero/Hero.css @@ -1,3 +1,3 @@ -.Hero{ -background-color: red; +.Hero { + background-color: red; } diff --git a/src/components/Hero/Hero.jsx b/src/components/Hero/Hero.jsx index 59f5d10..63fa7c4 100644 --- a/src/components/Hero/Hero.jsx +++ b/src/components/Hero/Hero.jsx @@ -1,58 +1,68 @@ -import React, {Fragment} from 'react'; -import Button from "@mui/material/Button"; -import Stack from "@mui/material/Stack"; -import Typography from '@mui/material/Typography'; -import Box from '@mui/material/Box'; -import Container from '@mui/material/Container'; -import { motion } from "framer-motion"; - +import Button from '@mui/material/Button' +import Stack from '@mui/material/Stack' +import Typography from '@mui/material/Typography' +import Box from '@mui/material/Box' +import Container from '@mui/material/Container' +import { motion } from 'framer-motion' export default function Hero() { return ( - + <> + + + + + The Open Source Blogging +
Platform for Developers{' '} +
+
- - - - - - The Open Source Blogging
Platform for Developers
-
- - Taking Developer Conversations To The Moon🚀 - - - - - - - -
-
-
- + whileTap={{ scale: 0.9 }} + variant="outlined" + style={{ + color: 'black', + backgroundColor: 'aqua', + textAlign: 'center', + fontWeight: 'bold', + }} + href="/onboard" + > + {' '} + Join the Community - it's free⚡ + + + + + ) } diff --git a/src/components/LinearLoader/LinearLoader.js b/src/components/LinearLoader/LinearLoader.js deleted file mode 100644 index 2370f1f..0000000 --- a/src/components/LinearLoader/LinearLoader.js +++ /dev/null @@ -1,47 +0,0 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import LinearProgress from '@mui/material/LinearProgress'; -import Typography from '@mui/material/Typography'; -import Box from '@mui/material/Box'; - -function LinearProgressWithLabel(props) { - return ( - - - - - - {`${Math.round( - props.value, - )}%`} - - - ); -} - -LinearProgressWithLabel.propTypes = { - /** - * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. - */ - value: PropTypes.number.isRequired, -}; - -export default function LinearLoader() { - const [progress, setProgress] = React.useState(10); - - React.useEffect(() => { - const timer = setInterval(() => { - setProgress((prevProgress) => (prevProgress >= 100 ? 10 : prevProgress + 10)); - }, 800); - return () => { - clearInterval(timer); - }; - }, []); - - return ( - - - - ); -} diff --git a/src/components/Navbar/Navbar.css b/src/components/Navbar/Navbar.css index 7868671..6bcf70a 100644 --- a/src/components/Navbar/Navbar.css +++ b/src/components/Navbar/Navbar.css @@ -1,10 +1,9 @@ .bar { - background-color: #05152E; + background-color: #05152e; } - -.serch{ +.serch { @media screen and (max-width: 511px) { - display: none + display: none; + } } -} \ No newline at end of file diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx index b437a38..aff705f 100644 --- a/src/components/Navbar/Navbar.jsx +++ b/src/components/Navbar/Navbar.jsx @@ -1,192 +1,174 @@ -import React from 'react'; -import "./Navbar.css"; -import { Link} from "react-router-dom"; -import AppBar from '@mui/material/AppBar'; -import NotificationsNoneOutlinedIcon from '@mui/icons-material/NotificationsNoneOutlined'; -import Box from '@mui/material/Box'; -import Toolbar from '@mui/material/Toolbar'; -import IconButton from '@mui/material/IconButton'; -import Typography from '@mui/material/Typography'; -import Menu from '@mui/material/Menu'; -import Container from '@mui/material/Container'; -import Avatar from '@mui/material/Avatar'; -import Tooltip from '@mui/material/Tooltip'; -import MenuItem from '@mui/material/MenuItem'; -import Serch from '../Search/Search'; -import WbSunnyIcon from '@mui/icons-material/WbSunny'; -import Badge from '@mui/material/Badge'; -import logo from "./logo.png" -import ProfilePopover from '../ProfilePopover/ProfilePopover'; -import NotifyPopover from '../NotifyPopover/NotifyPopover'; +import React, { useState } from 'react' +import './Navbar.css' +import { Link } from 'react-router-dom' +import { + AppBar, + Typography, + IconButton, + Toolbar, + Box, + Menu, + Container, + Badge, + Avatar, + Tooltip, + MenuItem, +} from '@mui/material' +import NotificationsNoneOutlinedIcon from '@mui/icons-material/NotificationsNoneOutlined' +import Serch from '../Search/Search' +import WbSunnyIcon from '@mui/icons-material/WbSunny' +import logo from '../../assets/logo.png' +import ProfilePopover from '../ProfilePopover/ProfilePopover' import { useUserAuth } from '../../context/UserAuthContext' - const Navbar = () => { -const {user} = useUserAuth() - - const [anchorElUser, setAnchorElUser] = React.useState(null); - + const { user } = useUserAuth() + const [anchorElUser, setAnchorElUser] = useState(null) const handleOpenUserMenu = (event) => { - setAnchorElUser(event.currentTarget); - }; + setAnchorElUser(event.currentTarget) + } const handleCloseUserMenu = () => { - setAnchorElUser(null); - }; + setAnchorElUser(null) + } return ( - - - - - - - - - - logo devhouse - - - - - {/* hambuger icon */} - - - logo devhouse - - - - {/* - */} - - - - - - {/* Search Component */} - - - - - - - - < WbSunnyIcon style={{color:"aqua"}}/> - - - {/* + + + + - {settings.map((setting) => ( - - {setting} - - ))} - */} - - - - - - - - - - < NotificationsNoneOutlinedIcon style={{color:"aqua"}}/> - - - - - + logo +  devhouse + + + + - { - - {} - - } - - - - - + logo +  devhouse + + + {/* + */} + - - - - {user ? : } - - - - - { - - {} - - } - - - - + + + + + + + + + + + + + + + + + - - - - - - - - ); -}; -export default Navbar; + + { + + + + } + + + + + + + {user ? ( + + ) : ( + + )} + + + + { + + + {} + + + } + + + + + + + ) +} +export default Navbar diff --git a/src/components/NotifyPopover/NotifyPopover.jsx b/src/components/NotifyPopover/NotifyPopover.jsx deleted file mode 100644 index c893b09..0000000 --- a/src/components/NotifyPopover/NotifyPopover.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react' - -export default function NotifyPopover() { - return ( -
NotifyPopover
- ) -} diff --git a/src/components/ProfilePopover/ProfilePopover.jsx b/src/components/ProfilePopover/ProfilePopover.jsx index d6b243e..c0dbd3a 100644 --- a/src/components/ProfilePopover/ProfilePopover.jsx +++ b/src/components/ProfilePopover/ProfilePopover.jsx @@ -1,78 +1,107 @@ -import React from 'react' -import Avatar from '@mui/material/Avatar'; -import Typography from '@mui/material/Typography'; +import Avatar from '@mui/material/Avatar' +import Typography from '@mui/material/Typography' import Box from '@mui/material/Box' -import IconButton from '@mui/material/IconButton'; -import Container from '@mui/material/Container'; -import Button from "@mui/material/Button"; -import { Stack } from '@mui/material'; -import {Link} from "react-router-dom" - -import {useUserAuth} from "../../context/UserAuthContext" -import { useNavigate } from "react-router-dom"; +import IconButton from '@mui/material/IconButton' +import Container from '@mui/material/Container' +import Button from '@mui/material/Button' +import { Stack } from '@mui/material' +import { Link } from 'react-router-dom' +import { useUserAuth } from '../../context/UserAuthContext' +import { useNavigate } from 'react-router-dom' export default function ProfilePopover() { const navigate = useNavigate() + const { user, logOut } = useUserAuth() - const {user,logOut} = useUserAuth() - - const handleGoogleLogOut = async (e) =>{ - e.preventDefault() + const handleGoogleLogOut = async (e) => { + e.preventDefault() try { - await logOut(); - navigate("/") + await logOut() + navigate('/') } catch (err) { - console.log( err.message) - + console.log(err.message) } } - return ( - - {user ? - - - -    {user.displayName} - + + {user ? ( + + + + + {' '} +    {user.displayName} + +
- - Dashboard + + + {' '} + Dashboard + - - + +
- - : - - - - - - -
-
- Sign up or log in to
your DevHouse
account.
-
Takes less than a few seconds.
- - + + + +
+
+ + {' '} + + Sign up or log in to
your DevHouse
account. +
+
+
{' '} + Takes less than a few seconds.{' '} +
+ + - - - - + {' '} + Signup + - -
- } - - + + +
+ )}
) } diff --git a/src/components/Search/Search.jsx b/src/components/Search/Search.jsx index 932d575..7d44f28 100644 --- a/src/components/Search/Search.jsx +++ b/src/components/Search/Search.jsx @@ -1,9 +1,6 @@ -import React from 'react' -import SearchIcon from '@mui/icons-material/Search'; -import { styled, alpha } from '@mui/material/styles'; -import InputBase from '@mui/material/InputBase'; - - +import SearchIcon from '@mui/icons-material/Search' +import { styled, alpha } from '@mui/material/styles' +import InputBase from '@mui/material/InputBase' const Search = styled('div')(({ theme }) => ({ position: 'relative', @@ -19,7 +16,7 @@ const Search = styled('div')(({ theme }) => ({ marginLeft: theme.spacing(3), width: 'auto', }, -})); +})) const SearchIconWrapper = styled('div')(({ theme }) => ({ padding: theme.spacing(0, 2), @@ -29,7 +26,7 @@ const SearchIconWrapper = styled('div')(({ theme }) => ({ display: 'flex', alignItems: 'center', justifyContent: 'center', -})); +})) const StyledInputBase = styled(InputBase)(({ theme }) => ({ color: 'inherit', @@ -45,19 +42,18 @@ const StyledInputBase = styled(InputBase)(({ theme }) => ({ }, })) - export default function Serch() { return (
- - - - - - + + + + + +
) } diff --git a/src/components/Spinner/Spinner.js b/src/components/Spinner/Spinner.js deleted file mode 100644 index 5ebe910..0000000 --- a/src/components/Spinner/Spinner.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import spinner from "./spinner.gif" - -export default function Spinner() { - return ( - <> - loading - - ) -} diff --git a/src/components/Spinner/spinner.gif b/src/components/Spinner/spinner.gif deleted file mode 100644 index d293b37..0000000 Binary files a/src/components/Spinner/spinner.gif and /dev/null differ diff --git a/src/components/Table/Table.css b/src/components/Table/Table.css index 81b2807..84f1681 100644 --- a/src/components/Table/Table.css +++ b/src/components/Table/Table.css @@ -4,7 +4,8 @@ table { width: 100%; } -td, th { +td, +th { border: 1px solid #dddddd; text-align: left; padding: 8px; @@ -12,4 +13,4 @@ td, th { tr:nth-child(even) { background-color: #dddddd; -} \ No newline at end of file +} diff --git a/src/components/Table/Table.js b/src/components/Table/Table.js deleted file mode 100644 index 79c0456..0000000 --- a/src/components/Table/Table.js +++ /dev/null @@ -1,94 +0,0 @@ -import "./Table.css"; -import { useUserAuth } from '../../context/UserAuthContext' -import DeleteArticle from '../Article/DeleteArticle'; -import { Link } from 'react-router-dom'; -import { collection, onSnapshot, orderBy, query } from 'firebase/firestore' -import React, { useEffect, useState } from 'react' -import { db } from "../../firebase/firebase.utils" -import EditArticle from "../Article/EditArticle" - -export default function Table() { - const { user } = useUserAuth() - - const [articles, setArticles] = useState([]); - - - useEffect(() => { - const articleRef = collection(db, "Articles"); - const q = query(articleRef, orderBy("createdAt", "desc")); - onSnapshot(q, (snapshot) => { - console.log(onSnapshot) - const articles = snapshot.docs.map((doc) => ({ - id: doc.id, - ...doc.data(), - })); - - setArticles(articles); - console.log(articles); - }); - }, []); - - return ( -
- - -
- - - - - - - { - articles.length === 0 ? ( -

No articles

- - ) : (articles.map(({ - id, - title, - description, - thumbnail, - createdAt, - createdBy, - userId, - userImg, - likes, - comments, - }) => ( - - - - - - - - - - - )) - ) - } - - - - - -
Your ArticlesEdit ArticleDelete
- {user && user.uid === userId && ( - title - )} - - - - {user && user.uid === userId && ( - - )} - - {user && user.uid === userId && ( - - )} -
- - - ) -} diff --git a/src/components/Table/Table.jsx b/src/components/Table/Table.jsx new file mode 100644 index 0000000..678e173 --- /dev/null +++ b/src/components/Table/Table.jsx @@ -0,0 +1,74 @@ +import './Table.css' +import { useUserAuth } from '../../context/UserAuthContext' +import DeleteArticle from '../Article/DeleteArticle' +import { Link } from 'react-router-dom' +import { collection, onSnapshot, orderBy, query } from 'firebase/firestore' +import React, { useEffect, useState } from 'react' +import { db } from '../../firebase/firebase.utils' +import EditArticle from '../Article/EditArticle' + +export default function Table() { + const { user } = useUserAuth() + + const [articles, setArticles] = useState([]) + + useEffect(() => { + const articleRef = collection(db, 'Articles') + const q = query(articleRef, orderBy('createdAt', 'desc')) + onSnapshot(q, (snapshot) => { + console.log(onSnapshot) + const articles = snapshot.docs.map((doc) => ({ + id: doc.id, + ...doc.data(), + })) + + setArticles(articles) + console.log(articles) + }) + }, []) + + return ( +
+ + + + + + + + {articles.length === 0 ? ( +

No articles

+ ) : ( + articles.map( + ({ + id, + title, + description, + thumbnail, + createdAt, + createdBy, + userId, + userImg, + likes, + comments, + }) => ( + + + + + + + + + + ) + ) + )} +
Your ArticlesEdit ArticleDelete
{user && user.uid === userId && title}{user && user.uid === userId && } + {user && user.uid === userId && ( + + )} +
+
+ ) +} diff --git a/src/components/Testimonials/Testimonials.js b/src/components/Testimonials/Testimonials.js deleted file mode 100644 index 3735445..0000000 --- a/src/components/Testimonials/Testimonials.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import TestimonialCard from 'material-testimonial-card'; -import { Stack } from '@mui/material'; - -const Testimonials = () => { - return - - - - - -} - -export default Testimonials; \ No newline at end of file diff --git a/src/context/UserAuthContext.js b/src/context/UserAuthContext.js index 5912e71..46668e8 100644 --- a/src/context/UserAuthContext.js +++ b/src/context/UserAuthContext.js @@ -11,6 +11,7 @@ export function UserAuthContextProvider({ children }) { return signOut(auth); } + function googleSignIn() { const googleAuthProvider = new GoogleAuthProvider(); return signInWithPopup(auth, googleAuthProvider); @@ -44,7 +45,7 @@ export function UserAuthContextProvider({ children }) { }, []); - //will be accessible in application + //Will be accessible in application return ( - - -
- - - - - {/* - - - UPCOMING ONLINE MEETUPS - - - - Featured Virtual Community Events - - - - - Create amazing experiences for the web in record time—without
thinking once about servers or devops. -
- -
- - */} - - - - FROM THE COMMUNITY - - - - Featured Articles Today - - - - - - - - - - - - - - ) -} diff --git a/src/pages/Onboard.js b/src/pages/Onboard.js deleted file mode 100644 index 90cc349..0000000 --- a/src/pages/Onboard.js +++ /dev/null @@ -1,138 +0,0 @@ -import React, { Fragment, useState } from 'react' -import { Stack } from '@mui/material'; -import { Typography } from '@mui/material'; -import Box from '@mui/material/Box'; -import Container from '@mui/material/Container'; -import Button from "@mui/material/Button"; -import { useUserAuth } from '../context/UserAuthContext' -import { Link, useNavigate } from "react-router-dom"; -import logo from "../components/Navbar/logo.png" -import google from "../pages/google.png" -import github from "../pages/github.png" -import twitter from "../pages/twitter.png" -import facebook from "../pages/facebook.png" - - - -export default function Onboard() { - const { error, setError } = useState("") - - const navigate = useNavigate() - - const { googleSignIn, githubSignIn, twitterSignIn, facebookSignIn } = useUserAuth() - - const handleGoogleSignIn = async (e) => { - e.preventDefault() - try { - await googleSignIn(); - navigate("/feed") - } catch (err) { - setError(err.message) - console.log(error) - } - } - - - const handleGithubSignIn = async (e) => { - e.preventDefault() - try { - await githubSignIn(); - navigate("/feed") - } catch (err) { - setError(err.message) - console.log(error) - } - } - - const handleTwitterSignIn = async (e) => { - e.preventDefault() - try { - await twitterSignIn(); - navigate("/feed") - } catch (err) { - setError(err.message) - console.log(error) - } - } - - const handleFacebookSignIn = async (e) => { - e.preventDefault() - try { - await facebookSignIn(); - navigate("/feed") - } catch (err) { - setError(err.message) - console.log(error) - } - } - return ( - - - - - - - - logo - - - - Welcome to Devhouse - - - Log in with one of the following: - - - - - - - - - - - - - - - - - - {/* */} - - {/* */} - - - By signing in to Devhouse, you agree to our -   - terms of service. - - - - - - - - - ) -} diff --git a/src/pages/UserProfile.js b/src/pages/UserProfile.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/Dashboard.js b/src/pages/dashboard.jsx similarity index 92% rename from src/pages/Dashboard.js rename to src/pages/dashboard.jsx index 4e1a472..873b705 100644 --- a/src/pages/Dashboard.js +++ b/src/pages/dashboard.jsx @@ -1,4 +1,3 @@ -import React from 'react' import { useUserAuth } from '../context/UserAuthContext' import Navbar from "../components/Navbar/Navbar" import { Stack, Typography } from '@mui/material' @@ -7,21 +6,18 @@ import DashControl from '../components/DashControl/DashControl' - export default function Dashboard() { - const { user } = useUserAuth() - return ( <> +

Welcome, {user.displayName}!🖐️

- + @@ -34,14 +30,11 @@ export default function Dashboard() { - 2. Share Your Knowledge - Neque porro quisquam est qui dolorem ipsum quia dolor sit amet,conse - @@ -49,16 +42,14 @@ export default function Dashboard() { 3. Grow Your Professional Network - - Neque porro quisquam est qui dolorem ipsum quia dolor sit amet,conse - + diff --git a/src/pages/Feed.js b/src/pages/feed.jsx similarity index 90% rename from src/pages/Feed.js rename to src/pages/feed.jsx index 1bec4de..69dd6a7 100644 --- a/src/pages/Feed.js +++ b/src/pages/feed.jsx @@ -1,4 +1,3 @@ -import * as React from 'react'; import Box from '@mui/material/Box'; import Navbar from "../components/Navbar/Navbar" import Articles from '../components/Article/Articles'; @@ -9,10 +8,7 @@ export default function Feed() {
- - -
); diff --git a/src/pages/homepage.jsx b/src/pages/homepage.jsx new file mode 100644 index 0000000..20ca05a --- /dev/null +++ b/src/pages/homepage.jsx @@ -0,0 +1,14 @@ +import Hero from '../components/Hero/Hero'; +import FeatureCard from '../components/FeatureCard/FeatureCard'; +import Navbar from '../components/Navbar/Navbar'; + +export default function Homepage() { + return ( + <> + + +
+ + + ) +} diff --git a/src/pages/NotFound.js b/src/pages/notfound.jsx similarity index 91% rename from src/pages/NotFound.js rename to src/pages/notfound.jsx index fe8def6..e96404a 100644 --- a/src/pages/NotFound.js +++ b/src/pages/notfound.jsx @@ -1,5 +1,4 @@ -import React from 'react' -import not from "./not.png" +import not from "../assets/not.png" import { Link } from 'react-router-dom' import { Button, Grid } from '@mui/material' @@ -7,7 +6,8 @@ export default function NotFound() { return ( <> -

+
+
diff --git a/src/pages/onboard.jsx b/src/pages/onboard.jsx new file mode 100644 index 0000000..dae077e --- /dev/null +++ b/src/pages/onboard.jsx @@ -0,0 +1,188 @@ +import React, { Fragment, useState } from 'react' +import { Stack } from '@mui/material' +import { Typography } from '@mui/material' +import Box from '@mui/material/Box' +import Container from '@mui/material/Container' +import Button from '@mui/material/Button' +import { useUserAuth } from '../context/UserAuthContext' +import { Link, useNavigate } from 'react-router-dom' +import logo from '../assets/logo.png' +import google from '../assets/google.png' +import github from '../assets/github.png' +import twitter from '../assets/twitter.png' +import facebook from '../assets/facebook.png' + +export default function Onboard() { + const { error, setError } = useState('') + const navigate = useNavigate() + const { googleSignIn, githubSignIn, twitterSignIn, facebookSignIn } = + useUserAuth() + + const handleGoogleSignIn = async (e) => { + e.preventDefault() + try { + await googleSignIn() + navigate('/feed') + } catch (err) { + setError(err.message) + console.log(error) + } + } + + const handleGithubSignIn = async (e) => { + e.preventDefault() + try { + await githubSignIn() + navigate('/feed') + } catch (err) { + setError(err.message) + console.log(error) + } + } + + const handleTwitterSignIn = async (e) => { + e.preventDefault() + try { + await twitterSignIn() + navigate('/feed') + } catch (err) { + setError(err.message) + console.log(error) + } + } + + const handleFacebookSignIn = async (e) => { + e.preventDefault() + try { + await facebookSignIn() + navigate('/feed') + } catch (err) { + setError(err.message) + console.log(error) + } + } + + return ( + + + + + + logo + + + + Welcome to Devhouse + + + Log in with one of the following: + + + + + + + + + + + + + + By signing in to Devhouse, you agree to our   + + terms of service. + + + + + + ) +} diff --git a/src/pages/Tos.js b/src/pages/tos.jsx similarity index 71% rename from src/pages/Tos.js rename to src/pages/tos.jsx index 8e62900..b42705b 100644 --- a/src/pages/Tos.js +++ b/src/pages/tos.jsx @@ -1,5 +1,3 @@ -import React from 'react' - export default function Tos() { return (
Tos
diff --git a/src/pages/Write.js b/src/pages/write.jsx similarity index 84% rename from src/pages/Write.js rename to src/pages/write.jsx index 8bfda9d..2c518e5 100644 --- a/src/pages/Write.js +++ b/src/pages/write.jsx @@ -1,12 +1,9 @@ -import React from 'react' import AddArticle from '../components/Article/AddArticle' export default function Write() { return (
- -
) }