Commit b350ec31 by jaymehta

permissions

1 parent 7cbeb538
......@@ -6,13 +6,14 @@ import { useDispatch, useSelector } from "react-redux";
import { cleanImage } from "../../services/imageHandling";
import { Button, Container, Form, Nav, Navbar } from "react-bootstrap";
import { loadUser } from "../../redux/actions/userActions";
import { useRouter } from "next/router";
const Header = () => {
const { user, error } = useSelector(state => state.loadedUser);
const dispatch = useDispatch();
// console.log("user", user);
const [isSticky, setIsSticky] = useState(false);
const router = useRouter();
useEffect(() => {
const handleScroll = () => {
// Check if the scroll position is greater than a certain threshold
......@@ -66,8 +67,10 @@ const Header = () => {
</div>
<p>{user.phone}</p>
<Button
onClick={() => {
onClick={async () => {
signOut({ redirect: false });
await router.push("/")
window.location.reload()
}}
className="me-3"
variant="primary"
......@@ -77,10 +80,14 @@ const Header = () => {
</div>
) : (
<div>
<Button className="me-3" variant="primary">
<Button onClick={()=> {
router.push("/signup/user")
}} className="me-3" variant="primary">
Sign Up
</Button>
<Button className="" variant="primary">
<Button onClick={()=> {
router.push("/login/user")
}} className="" variant="primary">
Log In
</Button>
</div>
......
......@@ -5,7 +5,7 @@ import Footer from "./Footer";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { loadUser } from "../../redux/actions/userActions";
import { useDispatch } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
const Layout = ({ children, title = "Zango", description = "" }) => {
const dispatch = useDispatch();
......
import React, { useState, useRef } from "react";
import React, { useState, useRef, useEffect } from "react";
import { Formik } from "formik";
import Link from "next/link";
import { Fragment } from "react";
......@@ -18,14 +18,12 @@ import { Loader } from "react-bootstrap-typeahead";
const Signup = props => {
console.log(props.type);
const router = useRouter();
const [otp, setOtp] = useState(new Array(4).fill(""));
const [isOtpSent, setOtpSent] = useState(false);
const [otpVerified, setOtpVerified] = useState(false);
const [loading, setLoading] = useState();
const dispatch = useDispatch();
const router = useRouter()
const otpValue = useRef();
const changeOtpRef = value => {
console.log(otpValue);
......@@ -76,7 +74,6 @@ const Signup = props => {
}
};
// console.log("otp", otp);
return (
<Fragment>
......@@ -252,7 +249,7 @@ const Signup = props => {
)}
<div className="input-group mb-0">
<Button type="submit" className="btn btn-primary btn-submit" disabled={(!values.termsConditions && !isValid) || loading}>
{loading ? <Loader/> : `${isOtpSent ? "Verify OTP" : "Sign Up Now"}`}
{loading ? <Loader /> : `${isOtpSent ? "Verify OTP" : "Sign Up Now"}`}
</Button>
</div>
</Form>
......
......@@ -26,6 +26,7 @@
"react-icons": "^5.0.1",
"react-image-gallery": "^1.3.0",
"react-js-pagination": "^3.0.3",
"react-loading-icons": "^1.1.0",
"react-multi-carousel": "^2.8.2",
"react-otp-input": "^3.1.1",
"react-owl-carousel": "^2.3.3",
......
......@@ -21,17 +21,16 @@ export default function BusinessDetailsPage () {
);
};
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
// Get the menu data.
// get the locations data.
// await store.dispatch(getVendorDetails())
await store.dispatch(loadUser());
return {
props: {},
props: {}
};
});
\ No newline at end of file
import Image from "next/image";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import Sidebar from "../../../components/layout/VendorDashboardSidebar";
import Layout from "../../../components/layout/Layout";
import { Button } from "react-bootstrap";
import { FaPlus } from "react-icons/fa";
import { useDispatch, useSelector } from "react-redux";
import { loadUser } from "../../../redux/actions/userActions";
import { wrapper } from "../../../redux/store";
import { useRouter } from "next/router";
const VendorDashboard = () => {
const { user, error } = useSelector(state => state.loadedUser);
const router = useRouter();
console.log("user", user);
const [collapsed, setCollapsed] = useState(false);
const [collapsed, setCollapsed] = useState(false);
const toggleSidebar = () => {
setCollapsed(!collapsed);
};
const toggleSidebar = () => {
setCollapsed(!collapsed);
};
const ApprovalStatus = () => {
if (user) {
switch (user.approved) {
case "approved":
return <></>;
return (
<Layout>
<div className="sidebarContainer">
<Sidebar collapsed={collapsed} toggleSidebar={toggleSidebar} />
<div className="content">
<div className="row">
<div className="col-12 offset-lg-2 col-lg-8">
<div className="infoSent">
<div className="bgCircleBlue">
<Image alt="" src="/images/vendor/icon-tick.svg" width="15" height="10" />
</div>
<div className="px-3">
<p className="p1">Business information sent successfully.</p>
<p className="p2">Kindly wait until we verify the details. You can start adding activities once your account is verified.</p>
</div>
<div>
<Image alt="" src="/images/vendor/icon-close.svg" width="14" height="14" />
</div>
</div>
</div>
case "rejected":
return (
<>
<div class="alert alert-danger" role="alert">
Your profile has been rejected! Please contact the admin for more details!
</div>
</>
);
<div className="d-flex justify-content-center py-4">
<span className="image-container">
<Image alt="" layout="fill" src="/images/vendor/Isolation_Mode.png" className="image" />
</span>
</div>
<div className="text-center py-2 mb-5">
<p className="p3">No information is available right now</p>
<Button type="button" variant="" className="btnAdd" disabled>
<span className="image-container me-2">
<Image alt="" layout="fill" src="/images/vendor/icon-plus.svg" width="14" height="14" className="image" />
</span>
{/* <FaPlus className="me-2" /> */}
<span>Add Activity</span>
</Button>
<Button type="button" variant="" className="btnAdd">
<span className="image-container me-2">
<Image alt="" layout="fill" src="/images/vendor/icon-plus.svg" width="14" height="14" className="image" />
</span>
{/* <FaPlus className="me-2" /> */}
<span>Add Activity</span>
</Button>
</div>
</div>
case "pending":
return (
<>
<div className="col-12 offset-lg-2 col-lg-8 ">
<div className="alert alert-danger alert-dismissible fade show text-center" role="alert">
{/* <div className="bgCircleBlue">
<Image alt="" src="/images/vendor/icon-tick.svg" width="15" height="10" />
</div> */}
<div className="text-center">
<p className="p1 text-center">Business information sent successfully.</p>
<p className="p2 text-center">Kindly wait until we verify the details. You can start adding activities once your account is verified.</p>
</div>
{/* <button type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> */}
</div>
{/* <div className="infoSent">
<div className="bgCircleBlue">
<Image alt="" src="/images/vendor/icon-tick.svg" width="15" height="10" />
</div>
<div className="px-3">
<p className="p1">Business information sent successfully.</p>
<p className="p2">Kindly wait until we verify the details. You can start adding activities once your account is verified.</p>
</div>
<div>
<Image alt="" src="/images/vendor/icon-close.svg" width="14" height="14" />
</div>
</div> */}
</div>
</>
);
case "none":
return <></>;
default:
break;
}
}
};
return (
<Layout>
<div className="sidebarContainer">
<Sidebar collapsed={collapsed} toggleSidebar={toggleSidebar} />
<div className="content">
<div className="row">
<ApprovalStatus />
<div className="d-flex justify-content-center py-4">
<span className="image-container">
<Image alt="" layout="fill" src="/images/vendor/Isolation_Mode.png" className="image" />
</span>
</div>
<div className="text-center py-2 mb-5">
<p className="p3">No information is available right now</p>
<Button
onClick={() => {
router.push("/vendor/activity-details");
}}
type="button"
variant=""
className="btnAdd"
disabled={user?.approved != "approved"}
>
<span className="image-container me-2">
<Image alt="" layout="fill" src="/images/vendor/icon-plus.svg" width="14" height="14" className="image" />
</span>
{/* <FaPlus className="me-2" /> */}
<span>Add Activity</span>
</Button>
</div>
</Layout>
);
</div>
</div>
</div>
</Layout>
);
};
export default VendorDashboard;
\ No newline at end of file
export default VendorDashboard;
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
// Get the menu data.
// get the locations data.
await store.dispatch(loadUser());
return {
props: {}
};
});
import axios from "axios";
import { getSession } from "next-auth/react";
import { CREATE_ACTIVITY_FAIL, CREATE_ACTIVITY_REQUEST, CREATE_ACTIVITY_SUCCESS } from "../constants/activitiesConstants";
export const createActivity = data => async dispatch => {
const session = await getSession();
try {
if (!session) {
return "You are not authenticated, please log in.";
}
dispatch({
type: CREATE_ACTIVITY_REQUEST,
loading: true
});
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session.jwt}`
}
};
let activityData = {
data: {
...data
}
};
const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/experiences`);
dispatch({
type: CREATE_ACTIVITY_SUCCESS,
payload: response.data
});
return response.data;
} catch (error) {
dispatch({
type: CREATE_ACTIVITY_FAIL,
payload: error.response.data
});
}
};
......@@ -381,3 +381,26 @@ export const finishEndUserOtpVerification = async verificationData => {
return await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/end-users/finish-otp-verification`, verificationData, config);
};
export const updateUserApprovalStatus = async ({ status }) => {
const session = await getSession();
if (!session) {
console.log("You are not authorized, please login");
}
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session.jwt}`
}
};
const response = await axios.put(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users/${session.id}`,
{
approved: status
},
config
);
return response;
};
export const CREATE_ACTIVITY_REQUEST = "CREATE_ACTIVITY_REQUEST"
export const CREATE_ACTIVITY_SUCCESS = "CREATE_ACTIVITY_SUCCESS"
export const CREATE_ACTIVITY_FAIL = "CREATE_ACTIVITY_FAIL"
export const CLEAR_ERRORS = "CLEAR_ERRORS";
\ No newline at end of file
import { CREATE_ACTIVITY_FAIL, CREATE_ACTIVITY_REQUEST, CREATE_ACTIVITY_SUCCESS } from "../constants/activitiesConstants";
import { CLEAR_ERRORS } from "../constants/vendorConstants";
export const createActivityReducer = (state = {}, action) => {
switch (action.type) {
case CREATE_ACTIVITY_REQUEST:
return { loading: true };
case CREATE_ACTIVITY_SUCCESS:
return {
loading: false,
activityData: action.payload
};
case CREATE_ACTIVITY_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
\ No newline at end of file
......@@ -5,6 +5,7 @@ import { authReducer, forgotPasswordReducer, loadedUserReducer, resetPasswordRed
import { enquiryReducer } from "./enquiryReducer";
import { displayEnquireNowReducer } from "./enquireNowModalReducer";
import { getVendorDetailsReducer, loggedInVendorReducer, updateVendorReducer } from "./vendorReducers";
import { createActivityReducer } from "./activitiesReducer";
const reducers = combineReducers({
townships: townshipsReducer,
......@@ -22,6 +23,7 @@ const reducers = combineReducers({
loggedInVendor: loggedInVendorReducer,
updatedVendorData: updateVendorReducer,
vendorDetails: getVendorDetailsReducer,
activityData: createActivityReducer,
});
export default reducers;
......@@ -2271,7 +2271,12 @@ footer hr {
padding-right: 1rem;
}
input:disabled {
cursor: not-allowed;
background-color: -internal-light-dark(rgba(239, 239, 239, 0.3), rgba(59, 59, 59, 0.3)) !important;
color: -internal-light-dark(rgb(84, 84, 84), rgb(170, 170, 170)) !important;
border-color: rgba(118, 118, 118, 0.3) !important;
}
@media (min-width: 992px) {
.navbar-expand-lg .navbar-nav .nav-link {
......
......@@ -4030,6 +4030,11 @@
"resolved" "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"
"version" "3.0.4"
"react-loading-icons@^1.1.0":
"integrity" "sha512-Y9eZ6HAufmUd8DIQd6rFrx5Bt/oDlTM9Nsjvf8YpajTa3dI8cLNU8jUN5z7KTANU+Yd6/KJuBjxVlrU2dMw33g=="
"resolved" "https://registry.npmjs.org/react-loading-icons/-/react-loading-icons-1.1.0.tgz"
"version" "1.1.0"
"react-modal@^3.8.1":
"integrity" "sha512-duB9bxOaYg7Zt6TMFldIFxQRtSP+Dg3F1ZX3FXxSUn+3tZZ/9JCgeAQKDg7rhZSAqopq8TFRw3yIbnx77gyFTw=="
"resolved" "https://registry.npmjs.org/react-modal/-/react-modal-3.15.1.tgz"
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!