diff --git a/package-lock.json b/package-lock.json index da6a784..9afe9c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@paypal/react-paypal-js": "^7.8.3", "@reduxjs/toolkit": "^1.9.5", "axios": "^1.4.0", + "cookie": "^0.5.0", "eslint": "8.39.0", "eslint-config-next": "13.3.4", "mongodb": "^5.4.0", @@ -901,6 +902,14 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", diff --git a/package.json b/package.json index a18eb23..98ec267 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@paypal/react-paypal-js": "^7.8.3", "@reduxjs/toolkit": "^1.9.5", "axios": "^1.4.0", + "cookie": "^0.5.0", "eslint": "8.39.0", "eslint-config-next": "13.3.4", "mongodb": "^5.4.0", diff --git a/pages/admin/index.jsx b/pages/admin/index.jsx index b9c4e9e..2cefbdd 100644 --- a/pages/admin/index.jsx +++ b/pages/admin/index.jsx @@ -115,7 +115,18 @@ const Index = ({ orders, products }) => { ); }; -export const getServerSideProps = async () => { +export const getServerSideProps = async (ctx) => { + const myCookie = ctx.req?.cookies || ""; + + if (myCookie.token !== process.env.TOKEN) { + return { + redirect: { + destination: "/admin/login", + permanent: false, + }, + }; + } + const productRes = await axios.get("http://localhost:3000/api/products"); const orderRes = await axios.get("http://localhost:3000/api/orders"); diff --git a/pages/admin/login.jsx b/pages/admin/login.jsx new file mode 100644 index 0000000..edec4fc --- /dev/null +++ b/pages/admin/login.jsx @@ -0,0 +1,48 @@ +import styles from "@/styles/Login.module.css"; +import { useState } from "react"; +import { useRouter } from "next/router"; +import axios from "axios"; + +const Login = () => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(false); + const router = useRouter(); + + const handleClick = async () => { + try { + await axios.post("http://localhost:3000/api/login", { + username, + password, + }); + router.push("/admin"); + } catch (err) { + setError(true); + } + }; + + return ( +
+
+

Admin Dashboard

+ setUsername(e.target.value)} + /> + setPassword(e.target.value)} + /> + + {error && Invalid credentials!} +
+
+ ); +}; + +export default Login; diff --git a/pages/api/login.js b/pages/api/login.js new file mode 100644 index 0000000..02eb421 --- /dev/null +++ b/pages/api/login.js @@ -0,0 +1,25 @@ +import cookie from "cookie"; + +const handler = async (req, res) => { + if (req.method === "POST") { + const { username, password } = req.body; + if ( + username === process.env.ADMIN_USERNAME && + password === process.env.ADMIN_PASSWORD + ) { + res.setHeader( + "Set-Cookie", + cookie.serialize("token", process.env.TOKEN, { + maxAge: 60 * 60, + sameSite: "strict", + path: "/", + }) + ); + res.status(200).json("Successful"); + } else { + res.status(400).json("Invalid credentials"); + } + } +}; + +export default handler; diff --git a/styles/Login.module.css b/styles/Login.module.css new file mode 100644 index 0000000..3cb60ef --- /dev/null +++ b/styles/Login.module.css @@ -0,0 +1,32 @@ +.container { + height: calc(100vh - 100px); + display: flex; + align-items: center; + justify-content: center; +} + +.wrapper { + display: flex; + flex-direction: column; +} + +.input { + height: 40px; + margin-bottom: 20px; + padding: 0 10px; +} + +.button { + height: 40px; + margin-bottom: 20px; + border: none; + background-color: teal; + color: white; + font-weight: 600; + cursor: pointer; +} + +.error { + color: red; + font-size: 13px; +}