diff --git a/client/src/Contexts/adminContext.jsx b/client/src/Contexts/adminContext.jsx
deleted file mode 100644
index 69ca829..0000000
--- a/client/src/Contexts/adminContext.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-/* eslint-disable camelcase */
-import React, { createContext, useState, useEffect, useMemo } from 'react';
-import PropTypes from 'prop-types';
-import jwt_decode from 'jwt-decode';
-import { useNavigate, useLocation } from 'react-router-dom';
-
-const adminContext = createContext();
-
-function AdminProvider({ children }) {
- const navigate = useNavigate();
- const [adminInfo, setAdminInfo] = useState({});
- const [isAdminLogged, setIsAdminLogged] = useState(false);
- const token = document.cookie.split('tokenAdmin=')[1];
- const { pathname } = useLocation();
- const adminData = useMemo(
- () => ({ adminInfo, setAdminInfo, isAdminLogged, setIsAdminLogged }),
- [isAdminLogged, adminInfo]
- );
- useEffect(() => {
- if (token) {
- setAdminInfo(jwt_decode(token));
- switch (pathname) {
- case '/dashboard/contact':
- navigate('/dashboard/contact', { replace: true });
- break;
- case '/dashboard/books':
- navigate('/dashboard/books', { replace: true });
- break;
- case '/dashboard/services':
- navigate('/dashboard/services', { replace: true });
- break;
- case '/dashboard/categories':
- navigate('/dashboard/categories', { replace: true });
- break;
- default:
- navigate('/dashboard', { replace: true });
- break;
- }
- }
- }, [isAdminLogged]);
- return (
-
{children}
- );
-}
-AdminProvider.propTypes = {
- children: PropTypes.node.isRequired,
-};
-export { AdminProvider, adminContext };
diff --git a/client/src/Contexts/userContext copy.jsx b/client/src/Contexts/userContext copy.jsx
new file mode 100644
index 0000000..490450d
--- /dev/null
+++ b/client/src/Contexts/userContext copy.jsx
@@ -0,0 +1,71 @@
+/* eslint-disable camelcase */
+import React, {
+ createContext,
+ useState,
+ useEffect,
+ useMemo,
+ useContext,
+} from 'react';
+import PropTypes from 'prop-types';
+import jwt_decode from 'jwt-decode';
+import { useLocation, useNavigate } from 'react-router-dom';
+import { message } from 'antd';
+import axios from 'axios';
+import { ModalLoginContext } from './ModalLogin';
+
+const userContext = createContext();
+const useAuth = () => useContext(userContext);
+function UserProvider({ children }) {
+ const [userInfo, setUserInfo] = useState('');
+ const [isLogged, setIsLogged] = useState(false);
+ const token = document.cookie.split('token=')[1];
+ const { setIsOpen } = useContext(ModalLoginContext);
+ const { pathname } = useLocation();
+ const navigate = useNavigate();
+
+ const logout = () => {
+ axios
+ .get('/api/v1/logout')
+ .then(() => {
+ setIsLogged(false);
+ navigate('/', { replace: true });
+ setIsOpen(false);
+ })
+ .catch(() => {
+ message.error('حدث خطأ ما');
+ });
+ };
+
+ const userData = useMemo(
+ () => ({ userInfo, setUserInfo, isLogged, setIsLogged, logout }),
+ [userInfo, setUserInfo]
+ );
+ useEffect(() => {
+ if (token) {
+ console.log('userInfo', userInfo);
+ setUserInfo(jwt_decode(token));
+ setIsLogged(true);
+ if (userInfo.role === 'admin' && pathname === '/login/admin') {
+ navigate('/dashboard', { replace: true });
+ }
+ if (userInfo.role === 'admin') {
+ navigate(pathname, { replace: true });
+ }
+ if (pathname === '/profile' || pathname === '/book') {
+ navigate(pathname, { replace: true });
+ setIsOpen(false);
+ }
+ } else {
+ setIsLogged(false);
+ setUserInfo('');
+ }
+ }, [isLogged]);
+
+ return (
+
{children}
+ );
+}
+UserProvider.propTypes = {
+ children: PropTypes.node.isRequired,
+};
+export { UserProvider, userContext, useAuth };
diff --git a/client/src/Contexts/userContext.jsx b/client/src/Contexts/userContext.jsx
index 879094f..3268411 100644
--- a/client/src/Contexts/userContext.jsx
+++ b/client/src/Contexts/userContext.jsx
@@ -1,36 +1,97 @@
/* eslint-disable camelcase */
-import React, {
- createContext,
- useState,
- useEffect,
- useMemo,
- useContext,
-} from 'react';
+import React, { createContext, useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import jwt_decode from 'jwt-decode';
import { useLocation, useNavigate } from 'react-router-dom';
+import { message } from 'antd';
+import axios from 'axios';
import { ModalLoginContext } from './ModalLogin';
-const userContext = createContext();
+const AuthContext = createContext();
-function UserProvider({ children }) {
+const useAuth = () => useContext(AuthContext);
+
+function useProvideAuth() {
const [userInfo, setUserInfo] = useState('');
const [isLogged, setIsLogged] = useState(false);
+ const [isloading, setIsLoading] = useState(false);
+ const [error, setError] = useState('');
+ const [errorEmail, setErrorEmail] = useState('');
const token = document.cookie.split('token=')[1];
const { setIsOpen } = useContext(ModalLoginContext);
const { pathname } = useLocation();
const navigate = useNavigate();
- const userData = useMemo(
- () => ({ userInfo, setUserInfo, isLogged, setIsLogged }),
- [userInfo, setUserInfo]
- );
+ const register = ({ name, email, phone, password, locationDetails }) => {
+ axios
+ .post('/api/v1/signup', { name, email, phone, password, locationDetails })
+ .then(() => {
+ setIsLoading(false);
+ setIsOpen(false);
+ setIsLogged(true);
+ })
+ .catch((err) => {
+ if (err.response) {
+ setErrorEmail('الإيميل موجود مسبقاً');
+ setIsLoading(false);
+ } else {
+ message.error('حدث خطأ ما');
+ setIsLoading(false);
+ }
+ });
+ };
+
+ const login = ({ email, password }) => {
+ setIsLoading(true);
+ setError('');
+ axios
+ .post('/api/v1/signin', { email, password })
+ .then(({ data }) => {
+ if (data.data === 'admin') {
+ navigate('/dashboard', { replace: true });
+ }
+ setIsLoading(false);
+ setIsOpen(false);
+ setIsLogged(true);
+ })
+ .catch((err) => {
+ if (err.response) {
+ setError('يوجد خطأ بالإيميل أو كلمة السر');
+ setIsLoading(false);
+ } else {
+ message.error('حدث خطأ ما');
+ setIsLoading(false);
+ }
+ });
+ };
+
+ const logout = () => {
+ axios
+ .get('/api/v1/logout')
+ .then(() => {
+ setIsLogged(false);
+ setUserInfo('');
+ navigate('/', { replace: true });
+ // setIsOpen(false);
+ })
+ .catch(() => {
+ message.error('حدث خطأ ما');
+ });
+ };
+
useEffect(() => {
if (token) {
+ console.log('userInfo', userInfo);
setUserInfo(jwt_decode(token));
setIsLogged(true);
- if (pathname === '/profile') {
- navigate('/profile', { replace: true });
+ if (userInfo.role === 'admin' && pathname === '/login/admin') {
+ navigate('/dashboard', { replace: true });
+ }
+ if (userInfo.role === 'admin') {
+ navigate(pathname, { replace: true });
+ }
+ if (pathname === '/profile' || pathname === '/book') {
+ navigate(pathname, { replace: true });
setIsOpen(false);
}
} else {
@@ -39,11 +100,25 @@ function UserProvider({ children }) {
}
}, [isLogged]);
- return (
-
{children}
- );
+ return {
+ userInfo,
+ register,
+ logout,
+ login,
+ errorEmail,
+ error,
+ isLogged,
+ isloading,
+ };
+}
+
+function ProvideAuth({ children }) {
+ const auth = useProvideAuth();
+ return
{children};
}
-UserProvider.propTypes = {
+
+ProvideAuth.propTypes = {
children: PropTypes.node.isRequired,
};
-export { UserProvider, userContext };
+
+export { ProvideAuth, useAuth };
diff --git a/client/src/Pages/Dashboard/index.jsx b/client/src/Pages/Dashboard/index.jsx
index 738e97d..aec2381 100644
--- a/client/src/Pages/Dashboard/index.jsx
+++ b/client/src/Pages/Dashboard/index.jsx
@@ -1,6 +1,5 @@
import React, { useContext } from 'react';
-import axios from 'axios';
-import { Link, Outlet, useLocation, useNavigate } from 'react-router-dom';
+import { Link, Outlet, useLocation } from 'react-router-dom';
import {
Layout,
Menu,
@@ -10,7 +9,6 @@ import {
Avatar,
Button,
Badge,
- message,
} from 'antd';
import {
PieChartOutlined,
@@ -21,7 +19,7 @@ import {
LogoutOutlined,
BellOutlined,
} from '@ant-design/icons';
-import { adminContext } from '../../Contexts/adminContext';
+import { useAuth } from '../../Contexts/userContext';
import './style.css';
import logo from '../../Assets/images/logo.svg';
import user from '../../Assets/images/user.png';
@@ -64,20 +62,9 @@ const breadcrumbNameMap = {
};
function Dashboard() {
- const { adminInfo, setIsAdminLogged } = useContext(adminContext);
+ const { userInfo, logout } = useAuth();
const { pathname } = useLocation();
- const navigate = useNavigate();
- const logout = () => {
- axios
- .get('/api/v1/logoutAdmin')
- .then(() => {
- setIsAdminLogged(false);
- navigate('/login/admin', { replace: true });
- })
- .catch(() => {
- message.error('حدث خطأ ما');
- });
- };
+
return (
}
/>
-
{adminInfo.name}
+
{userInfo.name}
diff --git a/client/src/Pages/NotFound/index.jsx b/client/src/Pages/NotFound/index.jsx
index a959a25..4fe1752 100644
--- a/client/src/Pages/NotFound/index.jsx
+++ b/client/src/Pages/NotFound/index.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Image, Typography, Button } from 'antd';
-import notfoundimage from '../../Assets/images/notfoundimage.png';
+import notfoundImage from '../../Assets/images/notfoundimage.png';
import './style.css';
const { Title } = Typography;
@@ -9,13 +9,13 @@ const { Title } = Typography;
function NotFound() {
return (
-
+
- We can not seem to find the page you are looking for
+ لا توجد هذه الصفحة
diff --git a/client/src/Pages/NotFound/style.css b/client/src/Pages/NotFound/style.css
index 5a50d1a..38bed55 100644
--- a/client/src/Pages/NotFound/style.css
+++ b/client/src/Pages/NotFound/style.css
@@ -8,6 +8,6 @@
.go-home-button{
border-radius: 3px !important;
margin-top: 10px;
- border-color: #f2473f !important;
- background: #f2473f !important;
+ border-color: var(--main) !important;
+ background: var(--main) !important;
}
\ No newline at end of file
diff --git a/client/src/Pages/Profile/Cover.jsx b/client/src/Pages/Profile/Cover.jsx
index 5de6771..31446d1 100644
--- a/client/src/Pages/Profile/Cover.jsx
+++ b/client/src/Pages/Profile/Cover.jsx
@@ -1,11 +1,12 @@
-import React from 'react';
-import PropTypes from 'prop-types';
+import React, { useContext } from 'react';
import { Avatar, Card, Image } from 'antd';
import headerBackground from '../../Assets/images/headerBackground.svg';
+import { useAuth } from '../../Contexts/userContext';
const { Meta } = Card;
-function Cover({ userInfo }) {
+function Cover() {
+ const { userInfo } = useAuth();
return (
@@ -33,10 +34,5 @@ function Cover({ userInfo }) {
);
}
-Cover.propTypes = {
- userInfo: PropTypes.shape({
- name: PropTypes.string.isRequired,
- location: PropTypes.string.isRequired,
- }).isRequired,
-};
+
export default Cover;
diff --git a/client/src/Pages/Profile/index.jsx b/client/src/Pages/Profile/index.jsx
index beedcf1..52a9282 100644
--- a/client/src/Pages/Profile/index.jsx
+++ b/client/src/Pages/Profile/index.jsx
@@ -1,8 +1,8 @@
import React, { useContext, useEffect, useState } from 'react';
import axios from 'axios';
import uuid from 'react-uuid';
-import { Row, Col, message, Descriptions, Typography, Spin, Empty } from 'antd';
-import { userContext } from '../../Contexts/userContext';
+import { Row, Col, Descriptions, Typography, Spin, Empty } from 'antd';
+import { useAuth } from '../../Contexts/userContext';
import Cover from './Cover';
import './style.css';
@@ -11,25 +11,24 @@ const { Title } = Typography;
function Profile() {
const [myBooks, setMyBooks] = useState([]);
const [loading, setLoading] = useState(false);
- const { userInfo } = useContext(userContext);
+ const { userInfo } = useAuth();
useEffect(() => {
setLoading(true);
const cancelTokenSource = axios.CancelToken.source();
- axios
- .get(`/api/v1//user/${userInfo.id}/book`, {
- cancelToken: cancelTokenSource.token,
- })
- .then(({ data: { data } }) => {
- setMyBooks(data);
- })
- .catch(() => {
- message.error('حدث خطأ ما');
- })
- .finally(() => setLoading(false));
-
+ if (userInfo) {
+ axios
+ .get(`/api/v1/user/${userInfo.id}/book`, {
+ cancelToken: cancelTokenSource.token,
+ })
+ .then(({ data: { data } }) => {
+ setMyBooks(data);
+ })
+ .catch(() => {})
+ .finally(() => setLoading(false));
+ }
return () => cancelTokenSource.cancel();
- }, [userInfo]);
+ }, []);
return (
@@ -40,7 +39,7 @@ function Profile() {
lg={{ span: 20 }}
xl={{ span: 20 }}
>
-
+
{loading ? (
) : myBooks.length ? (
diff --git a/client/src/ProtectedRoute/AdminProtected.jsx b/client/src/ProtectedRoute/AdminProtected.jsx
index 519cfbe..4f30f0a 100644
--- a/client/src/ProtectedRoute/AdminProtected.jsx
+++ b/client/src/ProtectedRoute/AdminProtected.jsx
@@ -1,12 +1,51 @@
-import React, { useContext } from 'react';
-import { Navigate, Outlet } from 'react-router-dom';
-import { adminContext } from '../Contexts/adminContext';
-
-function AdminProtected() {
- const { adminInfo } = useContext(adminContext);
- if (!(adminInfo.role === 'admin')) {
- return ;
+import React, { useContext, useEffect } from 'react';
+import { Navigate, Outlet, useNavigate } from 'react-router-dom';
+import { userContext, useAuth } from '../Contexts/userContext';
+
+function AdminProtected({ children }) {
+ // const navigate = useNavigate();
+ // const userPromise = new Promise((resolve, reject) => {
+ // const { userInfo } = useContext(userContext);
+ // if (userInfo) resolve(userInfo);
+ // else reject(new Error('no user'));
+ // });
+
+ // userPromise
+ // .then((userInfo) => {
+ // if (userInfo.role !== 'admin' || userInfo.role === 'user') {
+ // return navigate('/login/admin', { replace: true });
+ // }
+ // // if (userInfo.role === 'admin') {
+ // // return navigate('/dashboard', { replace: true });
+ // // }
+ // })
+ // .catch(() => console.log('no user'));
+
+ // const { userInfo } = useContext(userContext);
+ // console.log('Admin Protected userInfo', userInfo);
+ // if (userInfo.role !== 'admin' || userInfo.role === 'user') {
+ // return ;
+ // }
+
+ const { userInfo } = useAuth();
+ console.log('Admin Protected userInfo', userInfo);
+ if (userInfo?.role !== 'admin' || userInfo?.role === 'user') {
+ return ;
}
- return ;
+ return children || ;
+
+ // useEffect(() => {
+ // console.log('Admin Protected userInfo', typeof userInfo !== 'string');
+ // console.log('Admin Protected Before userInfo', userInfo);
+ // if (typeof userInfo !== 'string') {
+ // console.log('Admin Protected userInfo', userInfo);
+ // if (!userInfo.role || userInfo.role === 'user') {
+ // navigate('/', { replace: true });
+ // }
+ // }
+ // console.log('Admin Protected userInfo', userInfo);
+ // }, []);
+ // return ;
}
+
export default AdminProtected;
diff --git a/client/src/ProtectedRoute/UserProtected.jsx b/client/src/ProtectedRoute/UserProtected.jsx
index 5c31e61..154c9af 100644
--- a/client/src/ProtectedRoute/UserProtected.jsx
+++ b/client/src/ProtectedRoute/UserProtected.jsx
@@ -1,16 +1,19 @@
import React, { useContext, useEffect } from 'react';
import { useNavigate, Outlet } from 'react-router-dom';
-import { userContext } from '../Contexts/userContext';
+import { useAuth } from '../Contexts/userContext';
import { ModalLoginContext } from '../Contexts/ModalLogin';
function UserProtected() {
const navigate = useNavigate();
- const { userInfo } = useContext(userContext);
+ const { userInfo } = useAuth();
const { setIsOpen } = useContext(ModalLoginContext);
+
useEffect(() => {
- if (!userInfo.name) {
- navigate('/', { replace: true });
- setIsOpen(true);
+ if (typeof userInfo === 'string') {
+ if (!userInfo.name) {
+ navigate('/', { replace: true });
+ setIsOpen(true);
+ }
}
}, []);
return ;
diff --git a/package.json b/package.json
index fb73fd3..3c43d4f 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,9 @@
"version": "1.0.0",
"description": "",
"main": "index.js",
+ "engines": {
+ "node": "16.14.0"
+ },
"scripts": {
"start": "NODE_ENV=production node dist/",
"dev": "cross-env NODE_ENV=development ts-node-dev server/index.ts",
diff --git a/server/controllers/index.ts b/server/controllers/index.ts
index 9a28835..0da3f0f 100644
--- a/server/controllers/index.ts
+++ b/server/controllers/index.ts
@@ -8,10 +8,12 @@ import {
getContacts, addContact, deleteContact, updateContactStatus,
} from './contact';
import signup from './signup';
-import { logout, logoutAdmin } from './logout';
+import logout from './logout';
import { checkAuth, checkAdmin } from './middlewares/auth';
import signin from './signin';
-import { postService, archivedService, putService, getServices } from './services';
+import {
+ postService, archivedService, putService, getServices,
+} from './services';
import {
getBooks, getUserBooks, getBook, postBook, deleteBook, getStatus,
getBookDay, getBookMonth, updateBook, updateStatusBook,
@@ -45,7 +47,6 @@ export {
validateLink,
signinAdmin,
updateContactStatus,
- logoutAdmin,
getStatus,
deleteBook,
getBookDay,
diff --git a/server/controllers/logout/index.ts b/server/controllers/logout/index.ts
index e01490d..1793b82 100644
--- a/server/controllers/logout/index.ts
+++ b/server/controllers/logout/index.ts
@@ -1,10 +1,7 @@
import { RequestHandler } from 'express';
-const logout: RequestHandler = async (req, res, next) => {
+const logout: RequestHandler = async (req, res) => {
res.clearCookie('token').json({ message: 'You have been successfully logged out', status: 200 });
};
-const logoutAdmin: RequestHandler = async (req, res, next) => {
- res.clearCookie('tokenAdmin').json({ message: 'You have been successfully logged out', status: 200 });
-};
-export { logout, logoutAdmin };
+export default logout;
diff --git a/server/controllers/signin/index.ts b/server/controllers/signin/index.ts
index c41bc89..9e111db 100644
--- a/server/controllers/signin/index.ts
+++ b/server/controllers/signin/index.ts
@@ -1,7 +1,7 @@
import { RequestHandler } from 'express';
import { compare } from 'bcrypt';
import dotenv from 'dotenv';
-import { checkEmailExistsQuery } from '../../queries';
+import { checkEmailExistsQuery, checkEmailAdminExistsQuery } from '../../queries';
import { jwtSign, CustomizedError } from '../../utils';
import { signinSchema } from '../../validation';
@@ -13,10 +13,22 @@ const signin: RequestHandler = async (req, res, next) => {
} = await signinSchema.validate(req.body, { abortEarly: false });
const { rowCount, rows: data } = await checkEmailExistsQuery(email);
if (rowCount === 0) {
- throw new CustomizedError(400, 'There have error with email or password');
+ const { rowCount: count, rows: dataUser } = await checkEmailAdminExistsQuery(email);
+ if (count === 0) {
+ throw new CustomizedError(400, 'There have error with email or password');
+ } else {
+ const resultCompare = await compare(password, dataUser[0].password);
+ if (!resultCompare) {
+ throw new CustomizedError(400, 'There have error with email or password');
+ }
+ const token = await jwtSign({
+ id: dataUser[0].id, email, role: 'admin', name: dataUser[0].name,
+ });
+ res.cookie('token', token).json({ message: 'You have been successfully logged in', status: 200, data: 'admin' });
+ }
}
- const resultComapre = await compare(password, data[0].password);
- if (!resultComapre) {
+ const resultCompare = await compare(password, data[0].password);
+ if (!resultCompare) {
throw new CustomizedError(400, 'There have error with email or password');
}
const token = await jwtSign({
@@ -27,8 +39,9 @@ const signin: RequestHandler = async (req, res, next) => {
location: data[0].location,
lat: data[0].lat,
lng: data[0].lng,
+ role: 'user',
});
- res.cookie('token', token).json({ message:'You have been successfully logged in', status: 200 });
+ res.cookie('token', token).json({ message: 'You have been successfully logged in', status: 200, data: 'user' });
} catch (error: any) {
if (error.name === 'ValidationError') {
return next(new CustomizedError(400, error.errors[0]));
diff --git a/server/controllers/signinAdmin/index.ts b/server/controllers/signinAdmin/index.ts
index e49dbfa..53d2e4b 100644
--- a/server/controllers/signinAdmin/index.ts
+++ b/server/controllers/signinAdmin/index.ts
@@ -6,9 +6,7 @@ import { jwtSign, CustomizedError } from '../../utils';
import { signinSchema } from '../../validation';
dotenv.config();
-const {
- NODE_ENV,
-} = process.env;
+
const signinAdmin: RequestHandler = async (req, res, next) => {
try {
const {
@@ -18,14 +16,14 @@ const signinAdmin: RequestHandler = async (req, res, next) => {
if (rowCount === 0) {
throw new CustomizedError(400, 'There have error with email or password');
}
- const resultComapre = await compare(password, data[0].password);
- if (!resultComapre) {
+ const resultCompare = await compare(password, data[0].password);
+ if (!resultCompare) {
throw new CustomizedError(400, 'There have error with email or password');
}
const token = await jwtSign({
id: data[0].id, email, role: 'admin', name: data[0].name,
});
- res.cookie('tokenAdmin', token).json({ message: 'You have been successfully logged in', status: 200 });
+ res.cookie('token', token).json({ message: 'You have been successfully logged in', status: 200 });
} catch (error: any) {
if (error.name === 'ValidationError') {
return next(new CustomizedError(400, error.errors[0]));
diff --git a/server/controllers/signup/index.ts b/server/controllers/signup/index.ts
index 67b9ee0..18b00f3 100644
--- a/server/controllers/signup/index.ts
+++ b/server/controllers/signup/index.ts
@@ -31,6 +31,7 @@ const signup: RequestHandler = async (req, res, next) => {
name,
phone,
locationDetails,
+ role: 'user',
});
res.cookie('token', token).status(201).json({ message: 'You have been successfully register', status: 201 });
} catch (error: any) {
diff --git a/server/queries/book/getUserBooksQuery.ts b/server/queries/book/getUserBooksQuery.ts
index 29e1497..bdf1e59 100644
--- a/server/queries/book/getUserBooksQuery.ts
+++ b/server/queries/book/getUserBooksQuery.ts
@@ -13,5 +13,6 @@ const getUserBooksQuery = (id:number) => connection.query(`
FROM
appointments AS a
JOIN users AS u ON a.user_id = u.id
- WHERE a.user_id = $1`, [id]);
+ WHERE a.user_id = $1
+ ORDER BY a.id DESC`, [id]);
export default getUserBooksQuery;
diff --git a/server/routes/index.ts b/server/routes/index.ts
index e0fbea0..072c6af 100644
--- a/server/routes/index.ts
+++ b/server/routes/index.ts
@@ -22,7 +22,6 @@ import {
signinAdmin,
updateContactStatus,
checkAuth,
- logoutAdmin,
getStatus,
deleteBook,
getBookDay,
@@ -43,7 +42,6 @@ router.delete('/contact/archives/:id', validateLink, deleteContact);
router.put('/contact/status/:id', validateLink, updateContactStatus);
router.post('/signup', signup);
router.get('/logout', logout);
-router.get('/logoutAdmin', logoutAdmin);
router.post('/signin', signin);
router.post('/admin/signin', signinAdmin);
router.get('/book/status', getStatus);