From d160af57f9c36772f158b364c211dec419d48aac Mon Sep 17 00:00:00 2001 From: ShivanshPlays Date: Sun, 10 Nov 2024 07:28:47 +0530 Subject: [PATCH 1/4] added login page for admin only route --- client/src/App.jsx | 4 + client/src/component/Admin.jsx | 193 +++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 client/src/component/Admin.jsx diff --git a/client/src/App.jsx b/client/src/App.jsx index 9426c7f..eff663f 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -28,6 +28,8 @@ import ScrollTop from "./component/ScrollTop"; import EditProfile from "./component/EditProfile"; import Contributors from "./component/Contributors"; import Discussion from "./component/Discussion"; +import Admin from "./component/Admin"; +import Dashboard from "./component/Dashboard"; import ForgotPassword from "./component/ForgotPassword"; import ResetPassword from "./component/ResetPassword"; import NotFound from "./component/NotFound"; @@ -137,6 +139,8 @@ function App() { } /> } /> } /> + } /> + } /> } /> } /> } /> diff --git a/client/src/component/Admin.jsx b/client/src/component/Admin.jsx new file mode 100644 index 0000000..dc54231 --- /dev/null +++ b/client/src/component/Admin.jsx @@ -0,0 +1,193 @@ +import PropTypes from "prop-types"; +import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +const SERVER_URI=import.meta.env.VITE_SERVER_URI; +import { Input, Spin } from "antd"; +import { + UserOutlined, + LockOutlined, + EyeInvisibleOutlined, + EyeTwoTone, +} from "@ant-design/icons"; +import "../css/Login.css"; +import toast from "react-hot-toast"; +import { useAuth } from '../contexts/authContext'; + +const Admin = ({ mode }) => { + const [credentials, setCredentials] = useState({ email: "", password: "" }); + const [loading, setLoading] = useState(false); + const navigate = useNavigate(); + const { userLoggedIn } = useAuth(); + + // Conditional navigation if user is already logged in + useEffect(() => { + if (userLoggedIn) { + navigate('/'); + } + }, [userLoggedIn, navigate]); + + // Handle form submission for login + const handleSubmit = async (e) => { + e.preventDefault(); + + // Check for empty fields + if (!credentials.email || !credentials.password) { + toast.error("Please enter both email and password."); + return; + } + + setLoading(true); + try { + const response = await fetch(`${SERVER_URI}/api/admin/login`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(credentials), + }); + + if (!response.ok) { + // Check for network or server errors + if (response.status === 500) { + toast.error("Server error. Please try again later."); + } else { + toast.error("Login failed! Please check your credentials."); + } + throw new Error("Response not ok"); + } + + const json = await response.json(); + + if (json.success) { + localStorage.setItem("token", json.authtoken); + // setloggedin(!isloggedin); + console.log("flskd"); + + return navigate("../dashboard"); + + } else { + toast.error(json.message || "Login failed! Invalid credentials."); + } + } catch (error) { + if (error.message === "NetworkError") { + toast.error("Network error. Please check your connection."); + } else { + toast.error("An unexpected error occurred. Please try again later."); + } + console.error("Error during login:", error); + } finally { + setLoading(false); + } + }; + + // Handle changes in input fields + const onChange = (e) => { + setCredentials({ ...credentials, [e.target.name]: e.target.value }); + }; + + + + + return ( +
+ {userLoggedIn && navigate('/')} +
+ +
+

Admin Login

+ {/* Title Line */} + + + {/* Email Input */} +
+ } + placeholder="Email" + name="email" + value={credentials.email} + onChange={onChange} + autoComplete="on" + required + className="h-10 text-xl" + style={{ + backgroundColor: mode === "dark" ? "black" : "white", + color: mode === "dark" ? "white" : "black", + }} + /> +
+ + {/* Password Input */} +
+ } + placeholder="Password" + name="password" + value={credentials.password} + onChange={onChange} + autoComplete="on" + required + iconRender={(visible) => + visible ? : + } + className="h-10 text-xl" + style={{ + backgroundColor: mode === "dark" ? "black" : "white", + color: mode === "dark" ? "white" : "black", + }} + /> +
+ + + + + + +
+ +
+

+ WELCOME +
+ BACK! +

+

+ Please Sign In here +
+ with your real info +

+
+
+
+ ); +}; + +Admin.propTypes = { + mode: PropTypes.string.isRequired, +}; + +export default Admin; \ No newline at end of file From 76b9abffe87b658ac7e3153ad9868f080fd99695 Mon Sep 17 00:00:00 2001 From: ShivanshPlays Date: Sun, 10 Nov 2024 07:32:36 +0530 Subject: [PATCH 2/4] some err fixes --- client/src/App.jsx | 2 -- client/src/component/Admin.jsx | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/client/src/App.jsx b/client/src/App.jsx index eff663f..69e3d85 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -29,7 +29,6 @@ import EditProfile from "./component/EditProfile"; import Contributors from "./component/Contributors"; import Discussion from "./component/Discussion"; import Admin from "./component/Admin"; -import Dashboard from "./component/Dashboard"; import ForgotPassword from "./component/ForgotPassword"; import ResetPassword from "./component/ResetPassword"; import NotFound from "./component/NotFound"; @@ -140,7 +139,6 @@ function App() { } /> } /> } /> - } /> } /> } /> } /> diff --git a/client/src/component/Admin.jsx b/client/src/component/Admin.jsx index dc54231..e6cd4b9 100644 --- a/client/src/component/Admin.jsx +++ b/client/src/component/Admin.jsx @@ -63,7 +63,7 @@ const Admin = ({ mode }) => { // setloggedin(!isloggedin); console.log("flskd"); - return navigate("../dashboard"); + return navigate("/"); } else { toast.error(json.message || "Login failed! Invalid credentials."); From 383797cdd868d4514d5feefdeb7b10711637018d Mon Sep 17 00:00:00 2001 From: ShivanshPlays Date: Sun, 10 Nov 2024 15:42:06 +0530 Subject: [PATCH 3/4] working on admin dashboard --- client/package-lock.json | 2 +- client/package.json | 2 +- client/src/App.jsx | 2 + client/src/component/Admin.jsx | 7 +- client/src/component/Dashboard.jsx | 103 ++++++++++++++++++++++++++ server/Controllers/adminController.js | 9 +-- 6 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 client/src/component/Dashboard.jsx diff --git a/client/package-lock.json b/client/package-lock.json index 03a809a..3de2066 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -39,7 +39,7 @@ "open-source": "file:", "otp-input-react": "^0.3.0", "prop-types": "^15.8.1", - "react": "^18.3.1", + "react": "^18.2.0", "react-animated-cursor": "^2.11.2", "react-bootstrap": "^2.10.2", "react-dom": "^18.2.0", diff --git a/client/package.json b/client/package.json index d4f53cc..d4a1f73 100644 --- a/client/package.json +++ b/client/package.json @@ -41,7 +41,7 @@ "open-source": "file:", "otp-input-react": "^0.3.0", "prop-types": "^15.8.1", - "react": "^18.3.1", + "react": "^18.2.0", "react-animated-cursor": "^2.11.2", "react-bootstrap": "^2.10.2", "react-dom": "^18.2.0", diff --git a/client/src/App.jsx b/client/src/App.jsx index 69e3d85..e6f655a 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -29,6 +29,7 @@ import EditProfile from "./component/EditProfile"; import Contributors from "./component/Contributors"; import Discussion from "./component/Discussion"; import Admin from "./component/Admin"; +import Dashboard from "./component/Dashboard"; import ForgotPassword from "./component/ForgotPassword"; import ResetPassword from "./component/ResetPassword"; import NotFound from "./component/NotFound"; @@ -139,6 +140,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/client/src/component/Admin.jsx b/client/src/component/Admin.jsx index e6cd4b9..02901f3 100644 --- a/client/src/component/Admin.jsx +++ b/client/src/component/Admin.jsx @@ -45,7 +45,6 @@ const Admin = ({ mode }) => { }, body: JSON.stringify(credentials), }); - if (!response.ok) { // Check for network or server errors if (response.status === 500) { @@ -58,12 +57,12 @@ const Admin = ({ mode }) => { const json = await response.json(); + console.log(json) if (json.success) { - localStorage.setItem("token", json.authtoken); + // localStorage.setItem("token", json.authtoken); // this breakes // setloggedin(!isloggedin); - console.log("flskd"); - return navigate("/"); + navigate("/Dashboard"); } else { toast.error(json.message || "Login failed! Invalid credentials."); diff --git a/client/src/component/Dashboard.jsx b/client/src/component/Dashboard.jsx new file mode 100644 index 0000000..d80c97c --- /dev/null +++ b/client/src/component/Dashboard.jsx @@ -0,0 +1,103 @@ +// import React from 'react'; +import PropTypes from "prop-types"; + + + +const InsightCard = ({ icon, title, count, progress, color }) => ( +
+
+ + {icon} + +
+

{title}

+

{count}

+
+
+
+
+ + + + +
+ {progress} +
+
+
+ Last 24 Hours +
+); + +const PostCard = ({ post }) => ( +
+

{post.title}

+

{post.content}

+ {post.date} +
+); + +const Dashboard = () => { + const posts=[ + {id:1,title:"title1"}, + ] + // Placeholder data; replace with actual data from backend if needed. + const insightsData = [ + { icon: 'trending_up', title: 'Total Views', count: '100', progress: '80%', color: 'bg-coral' }, + { icon: 'local_mall', title: 'New Users', count: '323', progress: '50%', color: 'bg-red-400' }, + { icon: 'stacked_line_chart', title: 'Total Posts', count: '12', progress: '90%', color: 'bg-green-400' }, + ]; + + return ( +
+ {/* Header */} +
+

Dashboard

+ +
+ + {/* Insights */} +
+ {insightsData.map((item, index) => ( + + ))} +
+ + {/* Recent Posts */} +
+

Recent Posts

+
+ {posts && posts.length > 0 ? ( + posts.map((post, index) => ) + ) : ( +

No posts available.

+ )} +
+ Show All +
+
+ ); +}; +PostCard.propTypes = { + post: PropTypes.string.isRequired, +}; +Dashboard.propTypes = { + post: PropTypes.string.isRequired, +}; +InsightCard.propTypes = { + post: PropTypes.string.isRequired, + icon: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + count: PropTypes.string.isRequired, + progress: PropTypes.string.isRequired, + color: PropTypes.string.isRequired +}; +export default Dashboard; diff --git a/server/Controllers/adminController.js b/server/Controllers/adminController.js index c4e1e7e..c508b77 100644 --- a/server/Controllers/adminController.js +++ b/server/Controllers/adminController.js @@ -8,13 +8,6 @@ const { body, validationResult } = require("express-validator"); const login= async (req, res) => { let success = false; console.log("see"); - - // Check for validation errors - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(400).json({ errors: errors.array() }); - } - const { email, password } = req.body; try { @@ -37,7 +30,7 @@ const login= async (req, res) => { error: "Please try to login with correct credentials", }); } - + // Create JWT payload const data = { user: { From d31f0c6a97e8ca5a36f7b36c25ef107c1fccf54f Mon Sep 17 00:00:00 2001 From: ShivanshPlays Date: Sun, 10 Nov 2024 16:56:47 +0530 Subject: [PATCH 4/4] done nearly --- client/package-lock.json | 5 +- client/package.json | 2 +- client/src/component/Dashboard.jsx | 242 +++++++++++++++++++---------- 3 files changed, 165 insertions(+), 84 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 3de2066..62002c9 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -45,7 +45,7 @@ "react-dom": "^18.2.0", "react-google-recaptcha": "^3.1.0", "react-hot-toast": "^2.4.1", - "react-icons": "^5.0.1", + "react-icons": "^5.3.0", "react-phone-input-2": "^2.15.1", "react-phone-number-input": "^3.3.10", "react-quill": "^2.0.0", @@ -6517,7 +6517,8 @@ }, "node_modules/react-icons": { "version": "5.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", "peerDependencies": { "react": "*" } diff --git a/client/package.json b/client/package.json index d4a1f73..55fb2f1 100644 --- a/client/package.json +++ b/client/package.json @@ -47,7 +47,7 @@ "react-dom": "^18.2.0", "react-google-recaptcha": "^3.1.0", "react-hot-toast": "^2.4.1", - "react-icons": "^5.0.1", + "react-icons": "^5.3.0", "react-phone-input-2": "^2.15.1", "react-phone-number-input": "^3.3.10", "react-quill": "^2.0.0", diff --git a/client/src/component/Dashboard.jsx b/client/src/component/Dashboard.jsx index d80c97c..d738d21 100644 --- a/client/src/component/Dashboard.jsx +++ b/client/src/component/Dashboard.jsx @@ -1,103 +1,183 @@ // import React from 'react'; -import PropTypes from "prop-types"; - - +import { FaUsers, FaMicroblog } from 'react-icons/fa'; +import { PiEyesDuotone } from 'react-icons/pi'; -const InsightCard = ({ icon, title, count, progress, color }) => ( -
-
- - {icon} - -
-

{title}

-

{count}

-
-
-
-
- - - - -
- {progress} -
-
-
- Last 24 Hours -
-); - -const PostCard = ({ post }) => ( -
-

{post.title}

-

{post.content}

- {post.date} -
-); +import PropTypes from "prop-types"; -const Dashboard = () => { - const posts=[ - {id:1,title:"title1"}, - ] - // Placeholder data; replace with actual data from backend if needed. - const insightsData = [ - { icon: 'trending_up', title: 'Total Views', count: '100', progress: '80%', color: 'bg-coral' }, - { icon: 'local_mall', title: 'New Users', count: '323', progress: '50%', color: 'bg-red-400' }, - { icon: 'stacked_line_chart', title: 'Total Posts', count: '12', progress: '90%', color: 'bg-green-400' }, +const Dashboard = ({ mode }) => { + const isDarkMode = mode === 'dark'; + const blogs = [ + { id: 1, title: 'Understanding React', author: 'John Doe', category: 'Web Development' }, + { id: 2, title: 'CSS Tips and Tricks', author: 'Jane Smith', category: 'Design' }, + { id: 3, title: 'JavaScript Basics', author: 'Alice Johnson', category: 'Programming' }, ]; + const handleDelete = (id) => { + console.log(`Blog with id ${id} deleted`); + }; + return ( -
+
{/* Header */}
-

Dashboard

- +

Dashboard

{/* Insights */}
- {insightsData.map((item, index) => ( - - ))} +
+
+ + + +
+

Total Views

+

100

+
+
+
+
+ + + + +
+ 80% +
+
+
+ Last 24 Hours +
+ +
+
+ + + +
+

New Users

+

323

+
+
+
+
+ + + + +
+ 50% +
+
+
+ Last 24 Hours +
+ +
+
+ + + +
+

Total Posts

+

12

+
+
+
+
+ + + + +
+ 90% +
+
+
+ Last 24 Hours +
- {/* Recent Posts */} + {/* Blog Table */}
-

Recent Posts

-
- {posts && posts.length > 0 ? ( - posts.map((post, index) => ) - ) : ( -

No posts available.

- )} -
- Show All +

Blog Posts

+ + + + + + + + + + + {blogs.map((blog) => ( + + + + + + + ))} + +
TitleAuthorCategoryActions
{blog.title}{blog.author}{blog.category} + +
+ + Show All +
); }; -PostCard.propTypes = { - post: PropTypes.string.isRequired, -}; Dashboard.propTypes = { - post: PropTypes.string.isRequired, -}; -InsightCard.propTypes = { - post: PropTypes.string.isRequired, - icon: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - count: PropTypes.string.isRequired, - progress: PropTypes.string.isRequired, - color: PropTypes.string.isRequired + mode: PropTypes.string, // Function to notify parent about profile update }; export default Dashboard;