Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin login page and admin dashboard page #436

Merged
merged 5 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -142,6 +144,8 @@ function App() {
<Route exact path='/myproject' element={<MyProject mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/editprofile' element={<EditProfile mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path="/login" element={<Login mode={mode} setProgress={setProgress} showAlert={showAlert} loggedin={islogged} setloggedin={setloggedin} />} />
<Route exact path="/admin" element={<Admin mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path="/Dashboard" element={<Dashboard mode={mode}/>} />
<Route exact path="/login-otp" element={<LoginOTP mode={mode} setProgress={setProgress} showAlert={showAlert} loggedin={islogged} setloggedin={setloggedin} />} />
<Route exact path='/signup' element={<Signup mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/forgot-password' element={<ForgotPassword mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
Expand Down
192 changes: 192 additions & 0 deletions client/src/component/Admin.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
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();

console.log(json)
if (json.success) {
// localStorage.setItem("token", json.authtoken); // this breakes
// setloggedin(!isloggedin);

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 (
<div className="min-h-screen flex items-center justify-center mt-14" data-aos="zoom-in" data-aos-duration="1800">
{userLoggedIn && navigate('/')}
<div
className="wrapper h-3/4 mt-10"
style={{
backgroundColor: mode === "dark" ? "black" : "white",
color: mode === "dark" ? "white" : "black",
}}
>

<form
onSubmit={handleSubmit}
className="form"
style={{
backgroundColor: mode === "dark" ? "black" : "white",
color: mode === "dark" ? "white" : "black",
}}
>
<h1 className="title">Admin Login</h1>
{/* Title Line */}
<span className="title-line" style={{ backgroundColor: mode === "dark" ? "white" : "" }}></span>

{/* Email Input */}
<div className="inp">
<Input
prefix={<UserOutlined />}
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",
}}
/>
</div>

{/* Password Input */}
<div className="inp">
<Input
prefix={<LockOutlined />}
placeholder="Password"
name="password"
value={credentials.password}
onChange={onChange}
autoComplete="on"
required
iconRender={(visible) =>
visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />
}
className="h-10 text-xl"
style={{
backgroundColor: mode === "dark" ? "black" : "white",
color: mode === "dark" ? "white" : "black",
}}
/>
</div>


<button className="submit" type="submit" disabled={loading}>
{loading ? <Spin size="small" /> : "Login"}
</button>



</form>

<div className="banner">
<h1
className="wel_text"
style={{
color: mode === "dark" ? "black" : "white",
}}
>
WELCOME
<br />
BACK!
</h1>
<p
className="para"
style={{
color: mode === "dark" ? "black" : "white",
}}
>
Please Sign In here
<br />
with your real info
</p>
</div>
</div>
</div>
);
};

Admin.propTypes = {
mode: PropTypes.string.isRequired,
};

export default Admin;
Loading
Loading