feat: 🏷 admin dashboard implemented

parent 6a9a106b
......@@ -9,6 +9,7 @@ const RestaurantAPI = require("./src/api/restaurant.api");
const Pharmacy = require("./src/api/pharmacy.api");
const GroceryAPI = require("./src/api/grocery.api")
const UserAPI = require("./src/api/user.api")
const SubscriptionAPI = require("./src/api/subscription.api")
const port = process.env.PORT || 5000;
......@@ -31,6 +32,7 @@ app.use("/restaurant", RestaurantAPI());
app.use("/pharmacy",Pharmacy());
app.use("/grocery", GroceryAPI());
app.use("/user", UserAPI());
app.use("/subscription", SubscriptionAPI());
app.listen(port, () => {
......
const express = require('express');
const router = express.Router();
const SubscriptionController = require('../controller/subscription.controller');
module.exports = function () {
router.get('/', SubscriptionController.findAllSubscription);
router.post('/create', SubscriptionController.createSubscription);
router.get('/uid/:userID', SubscriptionController.findOneByUserID);
router.get('/:subscriptionID', SubscriptionController.findOneBySubscriptionID);
router.put('/:subscriptionID', SubscriptionController.updateSubscription);
router.delete('/:subscriptionID', SubscriptionController.deleteSubscription);
return router;
}
\ No newline at end of file
......@@ -10,6 +10,10 @@ module.exports = function () {
router.get('/verify-email', UserController.verifyEmail);
router.post('/getUser', UserController.getUserByEmail);
router.post('/createGoogleUser', UserController.createGoogleUser);
router.put('/updateUser', UserController.updateUser);
router.get('/:id', UserController.getUserById);
router.delete('/:id', UserController.deleteUser);
router.post('/search/:search', UserController.searchUser);
return router;
}
var axios = require('axios');
const jwt = require("jsonwebtoken");
//get_Area_Transportation_Modes_count
const getAreaTransportationModesCount = async (req, res) => {
try {
const token = req.headers['x-access-token'];
jwt.verify(token, process.env.JWT_SECRET)
if (req.body) {
if (!req.body.latitude) return res.status(500).send("Latitude is missing");
if (!req.body.longitude) return res.status(500).send("Longitude is missing");
const latitude = req.body.latitude;
const longitude = req.body.longitude;
var config_bus = {
method: 'get',
url: `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=1000&type=bus_station&keyword=bus_station&key=${process.env.API_KEY_SECRET}`,
headers: {}
};
var config_train = {
method: 'get',
url: `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=3000&type=train_station&keyword=&key=${process.env.API_KEY_SECRET}`,
headers: {}
};
var config_airport = {
method: 'get',
url: `https://maps.googleapis.com/maps/api/place/nearbysearch/json?keyword=&location=${latitude},${longitude}&radius=5000&type=airport&key=${process.env.API_KEY_SECRET}`,
headers: {}
};
console.log("Location - ", latitude, longitude)
const busStationCount = await findTotalCount(config_bus);
console.log("busStationCount", busStationCount.length)
const trainStationCount = await findTotalCount(config_train);
console.log("trainStationCount", trainStationCount.length)
const airportCount = await findTotalCount(config_airport);
console.log("airportCount", airportCount.length)
if (busStationCount.length > -1 && trainStationCount.length > -1 && airportCount.length > -1) {
let transpotation_count = busStationCount.length + trainStationCount.length + airportCount.length;
res.status(200).send({ "transportationmodes_count": transpotation_count })
console.log("Transportationmodes_count - ", transpotation_count);
} else {
res.status(500).send("Something went wrong");
}
} else {
res.status(500).send("Something went wrong");
}
} catch (error) {
res.status(500).send(error);
}
}
//get All Area attraction Places
const getAreaAllAttractionPlaces = async (req, res) => {
const radius = req.body.radius;
const token = req.headers['x-access-token'];
jwt.verify(token, process.env.JWT_SECRET)
try {
if (req.body) {
console.log("call", req.body)
if (!req.body.latitude) return res.status(500).send("latitude is missing");
if (!req.body.longitude) return res.status(500).send("longitude is missing");
const latitude = req.body.latitude;
const longitude = req.body.longitude;
var config_attraction = {
method: 'get',
url: `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=${radius}&type=tourist_attraction&keyword=&key=${process.env.API_KEY_SECRET}`,
headers: {}
};
await findTotalCount(config_attraction).then(function (response) {
if (response.length > -1) {
res.status(200).send({ "attractionplaces_count": response.length });
console.log("Attractionplaces_count -", response.length);
} else {
res.status(500).send("Something went wrong");
}
}).catch(function (error) {
return error;
});
}
} catch (error) {
res.status(500).send(error);
}
}
//get All Near By Hotels
const getAreaNearByHotels = async (req, res) => {
const token = req.headers['x-access-token'];
jwt.verify(token, process.env.JWT_SECRET)
try {
if (req.body) {
console.log("call", req.body)
if (!req.body.latitude) return res.status(500).send("latitude is missing");
if (!req.body.longitude) return res.status(500).send("longitude is missing");
const latitude = req.body.latitude;
const longitude = req.body.longitude;
var config_hotels = {
method: 'get',
url: `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=500&type=hotel&keyword=hotel&key=${process.env.API_KEY_SECRET}`,
headers: {}
};
await findTotalCount(config_hotels).then(function (response) {
let rating_count = 0;
for (let i = 0; i < response.length; i++) {
rating_count = rating_count + response[i].user_ratings_total;
}
console.log("Hotel_count -", response.length);
return res.status(200).send({ "hotel_count": response.length, "rating_count": rating_count });
// return res.status(200).send(response);
}).catch(function (error) {
return error;
});
}
} catch (error) {
res.status(500).send(error);
}
}
const findTotalCount = async (config, soFar = []) => {
console.log("Searching...")
let data = await axios(config)
.then(function (response) {
const allResults = soFar.concat(response.data.results);
if (response.data.next_page_token) {
return new Promise(resolve => setTimeout(resolve, 2000)).then(() => findTotalCount({
method: 'get',
url: `https://maps.googleapis.com/maps/api/place/nearbysearch/json?pagetoken=${response.data.next_page_token}&key=${process.env.API_KEY_SECRET}`,
headers: {}
}, allResults));
}
return allResults;
})
.catch(function (error) {
return error;
});
return data;
}
module.exports = {
getAreaAllAttractionPlaces,
getAreaTransportationModesCount,
getAreaNearByHotels,
}
\ No newline at end of file
const Subscription = require("../model/subscription.model.js");
// Create and Save a new Subscription
const createSubscription = async (req, res) => {
// Validate request
if (!req.body) {
res.status(400).send({
message: "Content can not be empty!"
});
}
// Create a Subscription
const subscription = new Subscription(req.body);
// Save Subscription in the database
try {
const data = await subscription.save();
res.send(data);
} catch (err) {
res.status(500).send({
message: err.message || "Some error occurred while creating the Subscription."
});
}
};
// Retrieve all Subscriptions from the database.
const findAllSubscription = async (req, res) => {
try {
const data = await Subscription.find();
res.send(data);
} catch (err) {
res.status(500).send({
message: err.message || "Some error occurred while retrieving Subscriptions."
});
}
}
// Find a single Subscription with a userID
const findOneByUserID = async (req, res) => {
try {
const data = await Subscription.findById(req.params.userID);
if (!data) {
res.status(404).send({
message: "Subscription not found with id " + req.params.userID
});
}
res.send(data);
} catch (err) {
if (err.kind === 'ObjectId') {
return res.status(404).send({
message: "Subscription not found with id " + req.params.userID
});
}
return res.status(500).send({
message: "Error retrieving Subscription with id " + req.params.userID
});
}
}
// Find a single Subscription with a subscriptionID
const findOneBySubscriptionID = async (req, res) => {
try {
const data = await Subscription.findById(req.params.subscriptionID);
if (!data) {
res.status(404).send({
message: "Subscription not found with id " + req.params.subscriptionID
});
}
res.send(data);
} catch (err) {
if (err.kind === 'ObjectId') {
return res.status(404).send({
message: "Subscription not found with id " + req.params.subscriptionID
});
}
return res.status(500).send({
message: "Error retrieving Subscription with id " + req.params.subscriptionID
});
}
};
// Update a Subscription identified by the userID in the request
const updateSubscription = async (req, res) => {
// Validate Request
if (!req.body) {
return res.status(400).send({
message: "Subscription content can not be empty"
});
}
// Find Subscription and update it with the request body
try {
const data = await Subscription.findByIdAndUpdate(req.params.subscriptionID, req.body, {
new: true
});
if (!data) {
return res.status(404).send({
message: "Subscription not found with id " + req.params.subscriptionID
});
}
res.send(data);
} catch (err) {
if (err.kind === 'ObjectId') {
return res.status(404).send({
message: "Subscription not found with id " + req.params.subscriptionID
});
}
return res.status(500).send({
message: "Error updating Subscription with id " + req.params.subscriptionID
});
}
};
// Delete a Subscription with the specified subscriptionID in the request
const deleteSubscription = async (req, res) => {
try {
const data = await Subscription.findByIdAndRemove(req.params.subscriptionID);
if (!data) {
return res.status(404).send({
message: "Subscription not found with id " + req.params.subscriptionID
});
}
res.send({ message: "Subscription deleted successfully!" });
} catch (err) {
if (err.kind === 'ObjectId' || err.name === 'NotFound') {
return res.status(404).send({
message: "Subscription not found with id " + req.params.subscriptionID
});
}
return res.status(500).send({
message: "Could not delete Subscription with id " + req.params.subscriptionID
});
}
};
module.exports ={
createSubscription,
findAllSubscription,
findOneByUserID,
findOneBySubscriptionID,
updateSubscription,
deleteSubscription
}
\ No newline at end of file
......@@ -7,6 +7,7 @@ const Token = require("../model/token.model");
// const sendVerificationMail = require('./../utils/sendEmail');
const crypto = require("crypto");
const nodemailer = require('nodemailer');
const { findByIdAndDelete } = require("../model/user.model");
// const sendVerificationMail = async (email, subject, text) => {
// try {
......@@ -102,25 +103,20 @@ const createUser = async (req, res) => {
bcrypt.genSalt(saltRounds, function (err, salt) {
bcrypt.hash(req.body.password, salt, async function (err, hash) {
req.body.password = hash;
const { fullName, email, password, role } = req.body;
let user = new User({
fullName,
email,
password,
role,
emailToken: crypto.randomBytes(64).toString('hex'),
isVerified: false
});
req.body.emailToken = crypto.randomBytes(64).toString('hex'),
req.body.isVerified = false;
let usercreate = new User(req.body);
console.log( usercreate.emailToken);
try {
const data = await user.save()
const data = await usercreate.save()
let mailOptions = {
from: '"Verify your email" <expectralk@gmail.com',
to: user.email,
to: usercreate.email,
subject: 'Verify your email - BussiFinder',
html: ` <h2 align="center" style=" font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; "> Hi ${user.fullName}! Thank you for joining with BussiFinder</h2>
html: ` <h2 align="center" style=" font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; "> Hi ${usercreate.fullName}! Thank you for joining with BussiFinder</h2>
<h4 align="center" style="font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; "> Please verify your mail to continue...</h4>
<div align="center">
<a align="center" href="http://${req.headers.host}/user/verify-email?token=${user.emailToken}">
<a align="center" href="http://${req.headers.host}/user/verify-email?token=${usercreate.emailToken}">
<button style=" font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; background-color: turquoise; border: none; border-radius: 50px ; cursor:'pointer'; color: #fff; font-weight:800; font-size:20px;/* Dark grey */ padding: 15px 32px">Verify
Your Email
</button>
......@@ -129,7 +125,7 @@ const createUser = async (req, res) => {
<div align="center" bgcolor="#ffffff" style="padding: 24px; font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 24px;">
<p style="margin: 0;">If that doesn't work, copy and paste the following link in your browser:</p>
<p style="margin: 0;">
<a href="http://${req.headers.host}/user/verify-email?token=${user.emailToken}">http://${req.headers.host}/user/verify-email?token=${user.emailToken}</a>
<a href="http://${req.headers.host}/user/verify-email?token=${usercreate.emailToken}">http://${req.headers.host}/user/verify-email?token=${usercreate.emailToken}</a>
</p>
</div>
<p align="center" style="margin: 0;">Cheers,<br> BussiFinder</p>`
......@@ -174,15 +170,9 @@ const createGoogleUser = async (req, res) => {
bcrypt.genSalt(saltRounds, function (err, salt) {
bcrypt.hash(req.body.password, salt, async function (err, hash) {
req.body.password = hash;
const { fullName, email, password, role } = req.body;
let user = new User({
fullName,
email,
password,
role,
emailToken: null,
isVerified: true
});
req.body.emailToken = null,
req.body.isVerified = true;
let user = new User(req.body);
try {
const data = await user.save()
console.log(data);
......@@ -207,7 +197,7 @@ const createGoogleUser = async (req, res) => {
const validateUser = async (req, res) => {
console.log(req);
let user = await User.findOne({ email: req.body.email }, (err, user) => {
let logUser = await User.findOne({ email: req.body.email }, (err, user) => {
if (err) {
console.log(err);
......@@ -226,7 +216,7 @@ const validateUser = async (req, res) => {
fullName: user.fullName,
}, process.env.JWT_SECRET)
res.status(200).send({ user: token });
res.status(200).send({ user: token ,userDetails:user});
} else {
console.log("Credentials Does Not Matched");
res.status(500).send({ message: "Credentials Does Not Matched" });
......@@ -241,11 +231,11 @@ const validateUser = async (req, res) => {
}
//get All User
const getAllUser = async (req, res) => {
await User.find()
.then((data) => {
console.log(data);
res.status(200).send(data);
})
.catch(error => {
......@@ -321,6 +311,83 @@ const getUserByEmail = async (req, res) => {
}
// Update User
const updateUser = async (req, res) => {
if (req.body) {
let count = req.body.predictionCount;
let countLimit = req.body.predictionCountLimit;
if(count == countLimit){
req.body.subscriptionStatus = "Over";
}
await User.updateOne({ _id: req.params.id }, { $set: req.body }, (err, result) => {
if (err) {
console.log(err);
res.status(500).send(err);
} else {
res.status(200).send({ message: "User Updated Successfully" });
console.log(result);
}
})
}
}
// Delete User
const deleteUser = async (req, res) => {
try{
const data = await User.findByIdAndDelete(req.params.id);
if(!data){
res.status(404).send({message:"User Not Found"});
}else{
res.status(200).send({message:"User Deleted Successfully"});
}
}catch(err){
console.log(err);
res.status(500).send(err);
}
}
// Search User
const searchUser = async (req, res) => {
try {
const data = await User.find({ $text: { $search: req.params.search } });
if (!data) {
res.status(404).send({ message: "User Not Found" });
} else {
res.status(200).send(data);
}
} catch (err) {
console.log(err);
res.status(500).send(err);
}
}
// pagination
const pagination = async (req, res) => {
const page = req.params.page;
const limit = req.params.limit;
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const results = {};
try {
if (endIndex < await User.countDocuments().exec()) {
results.next = {
page: page + 1,
limit: limit
}
}
if (startIndex > 0) {
results.previous = {
page: page - 1,
limit: limit
}
}
results.results = await User.find().limit(limit * 1).skip(startIndex).exec();
res.status(200).send(results);
} catch (err) {
console.log(err);
res.status(500).send(err);
}
}
module.exports = {
createUser,
......@@ -329,5 +396,9 @@ module.exports = {
verifyUser,
verifyEmail,
getUserByEmail,
createGoogleUser
createGoogleUser,
updateUser,
getUserById,
deleteUser,
searchUser,
}
\ No newline at end of file
const mongoose = require("mongoose");
const SubscriptionSchema = new mongoose.Schema({
userID: { type: String, required: true, ref: 'user' },
paymentType: { type: String, required: true },
paymentID: { type: String, required: true },
subscriptionPlan: { type: String, required: false },
subscriptionDate: { type: String, required: false },
subscriptionEndDate: { type: String, required: false },
subscriptionStatus: { type: String, required: false },
subscriptionAmount: { type: Number, required: false },
},{
timestamps:true
});
const Subscription = mongoose.model('subscription', SubscriptionSchema);
module.exports = Subscription;
\ No newline at end of file
......@@ -3,11 +3,23 @@ const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
fullName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
role: { type: String, required: true },
isVerified: { type: Boolean, required: false },
emailToken: { type: String, required: false }
emailToken: { type: String, required: false },
password: { type: String, required: true ,select: false },
predictionCount: { type: Number, required: false },
predictionCountLimit: { type: Number, required: false },
paymentType: { type: String, required: true },
paymentID: { type: String, required: true },
subscriptionPlan: { type: String, required: false },
subscriptionType: { type: String, required: false },
subscriptionDate: { type: String, required: false },
subscriptionEndDate: { type: String, required: false },
subscriptionStatus: { type: String, required: false },
subscriptionAmount: { type: Number, required: false },
},{
timestamps:true
});
const User = mongoose.model('user', UserSchema);
......
This diff is collapsed.
......@@ -22,6 +22,8 @@
"chart.js": "^3.9.1",
"export-to-csv-file": "^0.2.2",
"gapi-script": "^1.2.0",
"https": "^1.0.0",
"https-browserify": "^1.0.0",
"jspdf": "^2.5.1",
"jwt-decode": "^3.1.2",
"mdb-react-ui-kit": "^4.2.0",
......@@ -39,7 +41,7 @@
"react-google-charts": "^4.0.0",
"react-google-login": "^5.2.2",
"react-google-maps": "^9.4.5",
"react-icons": "^4.4.0",
"react-icons": "^4.6.0",
"react-minimal-pie-chart": "^8.3.0",
"react-particles": "^2.3.1",
"react-redux": "^8.0.4",
......
......@@ -25,6 +25,8 @@ import BusinessTypePage from './components/BusinessTypePage';
import MultipleResult from './components/MultipleResult';
import ResultsWOTypes from './components/ResultsWOTypes';
import LocationBasedPredict from './components/LocationBasedPredict';
import FactorDetails from './components/FactorDetails';
import AdminDashboard from './components/Admin/AdminDashboard';
const store = configureStore({
reducer: {
......@@ -57,10 +59,13 @@ function App() {
<Route path="/resultWOTypes" element={<ResultsWOTypes/>} />
<Route path="/Service" element={<BusinessTypePage />} />
<Route path="/locationBasedPredict" element={<LocationBasedPredict />} />
<Route path="/Factor%20Details" element={<FactorDetails />} />
<Route path="/AdminDashboard" element={<AdminDashboard />} />
</Route>
</Routes>
<Footer />
</Provider>
);
}
......
import React, { useEffect, useState, useRef } from 'react';
import { styled, useTheme } from "@mui/material/styles";
import Box from "@mui/material/Box";
import MuiDrawer from "@mui/material/Drawer";
import MuiAppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
import List from "@mui/material/List";
import CssBaseline from "@mui/material/CssBaseline";
import Typography from "@mui/material/Typography";
import Divider from "@mui/material/Divider";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import { IoIosGitBranch } from 'react-icons/io';
import {BsFileText} from 'react-icons/bs';
import { useSelector, useDispatch } from 'react-redux';
import { IoLogOutOutline } from 'react-icons/io5';
import { addHeader } from '../../features/header';
import Users from './Users';
import Dashboard from './Dashboard';
import Subscriptions from './Subscriptions';
import {TfiUser} from 'react-icons/tfi';
import {BsColumns} from 'react-icons/bs';
const drawerWidth = 240;
const openedMixin = (theme) => ({
width: drawerWidth,
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
overflowX: "hidden",
});
const closedMixin = (theme) => ({
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: "hidden",
width: `calc(${theme.spacing(7)} + 1px)`,
[theme.breakpoints.up("sm")]: {
width: `calc(${theme.spacing(8)} + 1px)`,
},
});
const DrawerHeader = styled("div")(({ theme }) => ({
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
}));
const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== "open",
})(({ theme, open }) => ({
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
const Drawer = styled(MuiDrawer, {
shouldForwardProp: (prop) => prop !== "open",
})(({ theme, open }) => ({
width: drawerWidth,
flexShrink: 0,
whiteSpace: "nowrap",
boxSizing: "border-box",
...(open && {
...openedMixin(theme),
"& .MuiDrawer-paper": openedMixin(theme),
}),
...(!open && {
...closedMixin(theme),
"& .MuiDrawer-paper": closedMixin(theme),
}),
}));
const AdminDashboard = () => {
const dispatch = useDispatch();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const [view, setView] = React.useState(<Users/>);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
const handleChangeView = (event) => {
switch(event.currentTarget.innerText){
case 'Users':
setView(<Users/>);
break;
case 'Dashboard':
setView(<Dashboard/>);
break;
case 'Subscriptions':
setView(<Subscriptions/>);
break;
default:
setView(<Dashboard/>);
break;
}
}
useEffect(() => {
dispatch(addHeader({ 'header': false, 'footer': false }))
}, []);
return (
<Box sx={{ display: "flex" ,boxSizing:'border-box'}}>
<CssBaseline />
<AppBar position="fixed" open={open} sx={{background:"black"}}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
sx={{
marginRight: 5,
...(open && { display: "none" }),
}}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap component="div">
Admin Dashboard
</Typography>
</Toolbar>
</AppBar>
<Drawer variant="permanent" open={open}>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === "rtl" ? (
<ChevronRightIcon />
) : (
<ChevronLeftIcon />
)}
</IconButton>
</DrawerHeader>
<Divider />
<List>
{["Dashboard","Subscriptions", "Users", "Reports"].map((text, index) => (
<ListItem key={text} disablePadding sx={{ display: "block" }}>
<ListItemButton
sx={{
minHeight: 48,
justifyContent: open ? "initial" : "center",
px: 2.5,
}}
onClick={handleChangeView}
>
<ListItemIcon
sx={{
minWidth: 0,
mr: open ? 3 : "auto",
justifyContent: "center",
fontSize: "1.5rem",
}}
>
{index === 0 ? <BsColumns /> : index === 1 ? <IoIosGitBranch/>:index === 2 ? <TfiUser/> : <BsFileText />}
</ListItemIcon>
<ListItemText primary={text} sx={{ opacity: open ? 1 : 0 }} />
</ListItemButton>
</ListItem>
))}
</List>
<Divider />
<List>
<ListItem disablePadding sx={{ display: 'block' }}>
<ListItemButton
sx={{
minHeight: 48,
justifyContent: open ? 'initial' : 'center',
px: 2.5,
fontSize: '1.7rem',
}}
>
<ListItemIcon
sx={{
minWidth: 0,
mr: open ? 3 : 'auto',
justifyContent: 'center',
color: '#bc5959',
}}
>
<IoLogOutOutline/>
</ListItemIcon>
<ListItemText primary={"Logout"} sx={{ opacity: open ? 1 : 0 }} />
</ListItemButton>
</ListItem>
</List>
</Drawer>
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<DrawerHeader />
<Box>
{view}
</Box>
</Box>
</Box>
);
};
export default AdminDashboard;
import React from 'react'
const Dashboard = () => {
return (
<div>Dashboard</div>
)
}
export default Dashboard
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
import * as React from 'react';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import Slide from '@mui/material/Slide';
import PropTypes from "prop-types";
const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
});
export default function AlertDialogSlide({ open, setOpen, title, content, setHandleConfirm }) {
// const [open, setOpen] = React.useState(false);
const handleCloseConfrim = () => {
setOpen(false);
setHandleConfirm(true);
};
const handleClose = () => {
setOpen(false);
setHandleConfirm(false);
};
return (
<div>
<Dialog
open={open}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-describedby="alert-dialog-slide-description"
>
<DialogTitle>{title}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-slide-description">
{content}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseConfrim}>Confrim</Button>
<Button onClick={handleClose}>Cancel</Button>
</DialogActions>
</Dialog>
</div>
);
}
AlertDialogSlide.propTypes = {
open: PropTypes.bool,
setOpen: PropTypes.func,
title: PropTypes.string,
content: PropTypes.string,
setHandleConfirm: PropTypes.func,
}
......@@ -29,7 +29,7 @@ import Logo from './../../images/logo-new-dark.png'
import API from '../../api';
import jwt_decode from "jwt-decode";
import { useSelector, useDispatch } from 'react-redux';
import { login } from '../../features/user';
import { login, register, userInfo } from '../../features/user';
import Snackbar from '@mui/material/Snackbar';
import MuiAlert, { AlertProps } from '@mui/material/Alert';
......@@ -187,7 +187,17 @@ export default function SignIn() {
password: res.profileObj.googleId,
role: 'user',
emailToken: null,
isVerified: true
isVerified: true,
predictionCount : 0,
predictionCountLimit : 0,
subscriptionType : 'none',
paymentType: 'none',
paymentID: 'none',
subscriptionPlan: 'none',
subscriptionEndDate : 'none',
subscriptionDate : 'none',
subscriptionStatus : 'none',
}
API.post('/user/getUser', body)
......@@ -199,10 +209,9 @@ export default function SignIn() {
API.post('user/validate', body).then(function (result) {
console.log("result", result)
let decodedToken = jwt_decode(result.data.user)
console.log("decodedToken", decodedToken)
localStorage.setItem('token', result.data.user)
dispatch(login({ 'fullName': decodedToken.fullName, 'email': decodedToken.email }))
dispatch(userInfo(result.data.userDetails))
dispatch(addHeader({ 'header': true, 'footer': true }))
navigate('/')
})
......@@ -226,6 +235,7 @@ export default function SignIn() {
localStorage.setItem('token', result.data.user)
dispatch(login({ 'fullName': decodedToken.fullName, 'email': decodedToken.email }))
dispatch(userInfo(result.data.userDetails))
dispatch(addHeader({ 'header': true, 'footer': true }))
navigate('/')
})
......@@ -280,6 +290,7 @@ export default function SignIn() {
localStorage.setItem('token', result.data.user)
dispatch(login({ 'fullName': decodedToken.fullName, 'email': decodedToken.email }))
dispatch(userInfo(result.data.userDetails))
dispatch(addHeader({ 'header': true, 'footer': true }))
navigate('/')
} catch (error) {
......
......@@ -124,7 +124,16 @@ export default function SignUp() {
fullName: data.get('firstName') + ' ' + data.get('lastName'),
email: data.get('email'),
password: data.get('password'),
role: 'user'
role: 'user',
predictionCount : 0,
predictionCountLimit : 0,
paymentType: 'none',
paymentID: 'none',
subscriptionPlan: 'none',
subscriptionType: 'none',
subscriptionEndDate : 'none',
subscriptionDate : 'none',
subscriptionStatus : 'none'
}
try {
const result = await API.post('user/create', body)
......
This diff is collapsed.
import React from 'react'
import React,{useEffect} from 'react'
import { Box } from '@mui/system'
import { makeStyles } from '@mui/styles';
import { FaFacebookF } from 'react-icons/fa'
......@@ -40,7 +40,7 @@ const useStyles = makeStyles({
fontWeight: '200',
color: themeColor => themeColor.status == 'dark' ? '#f5f5f5' : '#1e1d1d',
'&:hover': {
color: '#00b8a9',
color: '#2d4381',
}
},
footerIconBorder: {
......@@ -63,8 +63,16 @@ const Footer = () => {
const themeColor = useSelector((state) => state.theme.value);
const classes = useStyles(themeColor);
let navigate = useNavigate();
const headerVisibility = useSelector((state) => state.header)
useEffect(() => {
console.log("headerVisibilityeee", headerVisibility.value)
}, [headerVisibility]);
return (
<>
{headerVisibility.value[0].header &&
<Box
sx={{
width: "100%",
......@@ -183,8 +191,9 @@ const Footer = () => {
</Box>
{/* <div style={{width:"90%",height:"1px",backgroundColor:"#fff"}} ></div> */}
</Box>
</Box>}
</>
)
}
......
......@@ -33,7 +33,7 @@ const useStyles = makeStyles((theme) => ({
}
}));
const pages = ['Home', 'Service', 'Pricing', 'Contact Us', 'About'];
const pages = ['Home', 'Service', 'Pricing','Factor Details', 'Contact Us', 'About'];
const settings = ['Profile', 'Account', 'Dashboard', 'Logout'];
const ResponsiveAppBar = () => {
......@@ -94,7 +94,7 @@ const ResponsiveAppBar = () => {
return (
<>
{headerVisibility.value[0].header ?
<AppBar position="stick" sx={{ background: themeColor.status == 'light' ? '#f7f7f7' : '#070939' }}>
<AppBar position="stick" sx={{ background: themeColor.status == 'light' ? '#f7f7f7' : '#070939'}}>
<Container maxWidth="xl">
<Toolbar disableGutters>
......@@ -189,9 +189,9 @@ const ResponsiveAppBar = () => {
))}
</Box>
{userDetails.value.length > 0 ?
< AccountMenu onLogOut={onLogOut} name={userDetails.value.length > 0 && userDetails.value[0].fullName} email={userDetails.value.length > 0 && userDetails.value[0].email} />
< AccountMenu sx={{zIndex:10 }} onLogOut={onLogOut} name={userDetails.value.length > 0 && userDetails.value[0].fullName} email={userDetails.value.length > 0 && userDetails.value[0].email} />
:
<Button onClick={() => navigate(`/signIn`)}>Sign In</Button>
<Button sx={{zIndex:10 }} onClick={() => navigate(`/signIn`)}>Sign In</Button>
}
</Toolbar>
</Container>
......
......@@ -49,12 +49,6 @@ export const businessSlice = createSlice({
state.value[0] = null
},
// updateBusiness: (state, action) => {
// state.value.map((business)=>{
// if(business.id=== action.payload.id){}
// })
// }
}
});
export const { addBusiness: addBusiness, compareBusiness: compareBusiness ,addNewBusiness:addNewBusiness} = businessSlice.actions;
......
import { createSlice } from '@reduxjs/toolkit'
import { createSlice } from '@reduxjs/toolkit';
import api from '../api';
export const userSlice = createSlice({
name: "user",
initialState: {
value: []
value: [],
userDetails: null,
},
reducers: {
login: (state, action) => {
......@@ -13,10 +15,22 @@ export const userSlice = createSlice({
register: (state, action) => {
state.value.push(action.payload)
},
userInfo: (state, action) => {
state.userDetails.push(action.payload)
},
updateUser: (state, action) => {
const updateSubscription = async ()=>{
await api.put(`/users/updateUser/`, action.payload);
}
if(action.payload){
state.userDetails.push(updateSubscription())
}
},
logout: (state) => {
state.value = [];
state.userDetails = null;
},
}
});
export const { login: login, register: register, logout:logout } = userSlice.actions;
export const { login: login, register: register, logout:logout,userInfo:userInfo } = userSlice.actions;
export default userSlice.reducer;
\ No newline at end of file
{
"lockfileVersion": 1
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment