first commit
This commit is contained in:
commit
2f0cd84c4a
|
|
@ -0,0 +1,20 @@
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: { browser: true, es2020: true },
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react/jsx-runtime',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
],
|
||||||
|
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||||
|
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||||
|
settings: { react: { version: '18.2' } },
|
||||||
|
plugins: ['react-refresh'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{ allowConstantExport: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,8 @@
|
||||||
|
# React + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
|
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React, { useState,useRef,useCallback ,useEffect} from 'react';
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Modal,Form } from 'antd';
|
||||||
|
import {EyeOutlined,PlusOutlined, CloseOutlined,ArrowRightOutlined } from '@ant-design/icons';
|
||||||
|
import Android from "../../../../Images/android.png";
|
||||||
|
import { InputField } from "../../../../Components/Forms/InputField";
|
||||||
|
import OverView2 from './OverView2';
|
||||||
|
import {changeOverviewData,changeOverview2Img,changeOverview2Video,overviewPostData,overview2Img,overview2Video} from "../../../../features/themeChange/themeChange.js"
|
||||||
|
import "../../../../styles/template/overView/overView2.scss";
|
||||||
|
|
||||||
|
|
||||||
|
const Name =() => {
|
||||||
|
|
||||||
|
const formRef = useRef(null);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const overView1Data = useSelector(overviewPostData);
|
||||||
|
const imageUrl = useSelector(overview1Img);
|
||||||
|
|
||||||
|
const [messageType, setMessageType] = useState(null);
|
||||||
|
const [messageData, setMessageData] = useState(null);
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [editopen, setEditOpen] = useState(false);
|
||||||
|
const [editData, setEditData] = useState(false);
|
||||||
|
|
||||||
|
const items = []
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const sampleFunction = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Name
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Pozo Store</title>
|
||||||
|
<link rel="icon" href="/fav.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Arimo:ital,wght@0,400..700;1,400..700&family=Crimson+Pro:ital,wght@0,200..900;1,200..900&family=Dhurjati&family=Diplomata+SC&family=Inconsolata:wght@200..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Lexend+Zetta:wght@200;300;400;500;700&family=Libre+Franklin:ital,wght@0,100..900;1,100..900&family=Podkova:wght@400..800&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto+Slab:wght@200;300;400;500;600;700&family=VT323&family=Cute+Font&family=Kumar+One&family=Lemon&family=Lily+Script+One&family=M+PLUS+Rounded+1c&family=Maiden+Orange&family=Kode+Mono:wght@400..700&family=Eczar:wght@400..800&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
<iframe
|
||||||
|
id="ifmcontentstoprint"
|
||||||
|
style="
|
||||||
|
height: 0px;
|
||||||
|
width: 0px;
|
||||||
|
position: absolute;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
font-family: "Poppins", sans-serif;
|
||||||
|
"
|
||||||
|
></iframe>
|
||||||
|
</html>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,63 @@
|
||||||
|
{
|
||||||
|
"name": "retail-application",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@ant-design/plots": "^1.2.5",
|
||||||
|
"@autocomplete/material-ui": "0.0.17",
|
||||||
|
"@emotion/react": "^11.11.1",
|
||||||
|
"@emotion/styled": "^11.11.0",
|
||||||
|
"@material-ui/lab": "^4.0.0-alpha.61",
|
||||||
|
"@mui/material": "^5.14.18",
|
||||||
|
"@reduxjs/toolkit": "^1.9.5",
|
||||||
|
"antd": "^5.9.2",
|
||||||
|
"antd-img-crop": "^4.21.0",
|
||||||
|
"aos": "^2.3.4",
|
||||||
|
"axios": "^1.5.0",
|
||||||
|
"classnames": "^2.3.2",
|
||||||
|
"cropperjs": "^1.6.1",
|
||||||
|
"crypto-js": "^4.1.1",
|
||||||
|
"exceljs": "^4.3.0",
|
||||||
|
"google-maps-react": "^2.0.6",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
|
"html2pdf.js": "^0.10.2",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
|
"material-ui": "^0.20.2",
|
||||||
|
"moment": "^2.29.4",
|
||||||
|
"mui-autocomplete": "^2.0.1",
|
||||||
|
"number-to-words": "^1.2.4",
|
||||||
|
"qrcode": "^1.5.3",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-color": "^2.19.3",
|
||||||
|
"react-device-detect": "^2.2.3",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-icons": "^4.11.0",
|
||||||
|
"react-qr-code": "^2.0.12",
|
||||||
|
"react-redux": "^8.1.2",
|
||||||
|
"react-router-dom": "^6.16.0",
|
||||||
|
"react-select": "^5.8.0",
|
||||||
|
"react-speech-recognition": "^3.10.0",
|
||||||
|
"react-timer-hook": "^3.0.7",
|
||||||
|
"universal-cookie": "^6.1.1",
|
||||||
|
"webfontloader": "^1.6.28",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^18.2.15",
|
||||||
|
"@types/react-dom": "^18.2.7",
|
||||||
|
"@vitejs/plugin-react": "^4.0.3",
|
||||||
|
"eslint": "^8.45.0",
|
||||||
|
"eslint-plugin-react": "^7.32.2",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.3",
|
||||||
|
"sass": "^1.68.0",
|
||||||
|
"vite": "^4.4.11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,9 @@
|
||||||
|
ENV_BASE_URL='/'
|
||||||
|
ENV_COMMON_BASE_URL='https://pozo.app'
|
||||||
|
ENV_API_URL='http://192.168.1.37:8010'
|
||||||
|
# ENV_API_URL='http://192.168.1.38:8003'
|
||||||
|
ENV_API_URL_COMMON='http://192.168.1.38'
|
||||||
|
ENV_IMAGE_UPLOAD_API_URL="https://api.pozo.app/pozo-common-image-api/"
|
||||||
|
ENV_SECRET_KEY="3a939a2eed2cca4b64cd47f51b23b135b2b9b765273f695d47682ea803c8429d"
|
||||||
|
ENV_URL_SECRET_KEY="f2ef79b8b2d4fc1cc569726a5a753552257b4ff2872d6a71cf3119bce3f07c1b"
|
||||||
|
ENV_MAIN_BASE_URL='http://192.168.1.16:3006/'
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
ENV_BASE_URL='/apps/retail-public/'
|
||||||
|
ENV_COMMON_BASE_URL='https://pozo.app'
|
||||||
|
ENV_API_URL='https://api.pozo.app/pozo-retail-api'
|
||||||
|
ENV_API_URL_COMMON='https://api.pozo.app/pozo-common-api'
|
||||||
|
ENV_IMAGE_UPLOAD_API_URL="https://api.pozo.app/pozo-common-image-api/"
|
||||||
|
ENV_SECRET_KEY="3a939a2eed2cca4b64cd47f51b23b135b2b9b765273f695d47682ea803c8429d"
|
||||||
|
ENV_URL_SECRET_KEY="f2ef79b8b2d4fc1cc569726a5a753552257b4ff2872d6a71cf3119bce3f07c1b"
|
||||||
|
ENV_MAIN_BASE_URL='https://pozo.app/apps/retail/'
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
import { Routes, Route } from "react-router-dom";
|
||||||
|
import PozoPublicHomePage from "../src/Pages/HomePage/PozoPublicHomePage";
|
||||||
|
import Purchase from "./Pages/Purchcase/Purchase";
|
||||||
|
import PozoStore from "./Pages/PozoStore/PozoStore";
|
||||||
|
import PozoIndividualCard from "../src/Pages/PozoIndividualCard/PozoIndividualCard.jsx";
|
||||||
|
import LandingPage from "./Pages/LandingPage/landingPage.jsx";
|
||||||
|
import PozoPublicCheckOut from "./Pages/CheckOut/PozoPublicCheckOut.jsx";
|
||||||
|
import PozoCart from "./Pages/PozoCart/PozoCart.jsx";
|
||||||
|
import PozoPublicSignIn from "./Pages/SignIn/PozoPublicSignIn.jsx";
|
||||||
|
// import PozoPublicNavbar from "./Components/PozoPublicNavbar/PozoPubliNavbar.jsx";
|
||||||
|
import PozoPublicFavouriteList from "./Pages/FavouriteList/PozoPublicFavouriteList.jsx";
|
||||||
|
import PozoPublicFavShop from "./Pages/FavShop/PozoPublicFavShop.jsx";
|
||||||
|
import PozoPublicOrder from "./Pages/MyOrderPage/PozoPublicOrder.jsx";
|
||||||
|
import PozoPublicOrderInfo from "./Pages/MyOrderPage/PozoPublicOrderInfo.jsx";
|
||||||
|
import PozoPublicMyProfile from "./Pages/MyProfile/PozoPublicMyProfile.jsx";
|
||||||
|
import PozoPublicInvoice from "./Pages/Invoice/PozoPublicInvoice.jsx";
|
||||||
|
import StepProgress from "./Pages/MyOrderPage/StepProgress.jsx";
|
||||||
|
import PozoPublicCollapse from "./Components/Collapse/PozoPublicCollapse.jsx";
|
||||||
|
import PozoPublicImagePicker from "./Components/ImagePicker/PozoPublicImagePicker.jsx";
|
||||||
|
import ModalPozoPublic from "./Components/PozoPublicCard/ModalPozoPublic.jsx";
|
||||||
|
import PublicPozoModal from "./Components/PublicPozoModal/PublicPozoModal.jsx";
|
||||||
|
import PozoPublicDatePicker from "./Components/DatePicker/PozoPublicDatePicker.jsx";
|
||||||
|
import PozoPublicProductMaster from "./Pages/ProductMaster/PozoPublicProductMaster.jsx";
|
||||||
|
import PozoPublicStore from "./Pages/Store/PozoPublicStore.jsx";
|
||||||
|
import PozoPublicSellerRegister from "./Pages/SellerRegister/PozoPublicSellerRegister.jsx";
|
||||||
|
import PozoPublicSalesReport from "./Pages/SalesReport/PozoPublicSalesReport.jsx";
|
||||||
|
import SadminUsers from "./Pages/Sadmin/SadminUsers/SadminUser.jsx"
|
||||||
|
|
||||||
|
import PozoChartGraphs from "./Components/Charts/PozoGraphchart.jsx";
|
||||||
|
|
||||||
|
import PozoPublicBarchart from "./Components/Charts/PozoPublicBarchart.jsx";
|
||||||
|
import PozoPublicSadminReport from "./Pages/Sadmin/PozoPublicSadminReport.jsx";
|
||||||
|
import PozoPublicSetting from "./Pages/Setting/PozoPublicSetting.jsx";
|
||||||
|
import PozoPublicDashboard from "./Pages/Dashboard/PozoPublicDashboard.jsx";
|
||||||
|
import PozoPublicPaymentReport from "./Pages/Payment Report/PozoPublicPaymentReport.jsx";
|
||||||
|
import PozoPublicQueryManagement from "./Pages/QueryManagement/PozoPublicQueryManagement.jsx";
|
||||||
|
import Orders from "./Pages/Orders/Orders.jsx";
|
||||||
|
import GraphChart from "./Components/Charts/GraphChart.jsx";
|
||||||
|
import QueryRequest from "./Pages/QueryRequestForm/QueryRequest.jsx";
|
||||||
|
import AdminlandingPage from "./Pages/AdminLandingPage/AdminLandingPage.jsx";
|
||||||
|
import QueryContact from "./Pages/QueryRequestForm/QueryContact.jsx";
|
||||||
|
import CustomModal from "./Components/CustomModal/CustomModals.jsx";
|
||||||
|
import PozoPublicSAdminDashboard from "./Pages/SAdminDashboard/PozoPublicSAdminDashboard.jsx"
|
||||||
|
import AdsManagement from "./Pages/Ads Management/AdsManagement.jsx";
|
||||||
|
import PozoPublicMyProduct from "./Pages/MyProduct/PozoPublicMyProduct.jsx"
|
||||||
|
import SadminOveriew from "./Pages/SadminOverview/SadminOveriew.jsx"
|
||||||
|
const subDirectory = import.meta.env.BASE_URL;
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path={`${subDirectory}app-page`} element={<LandingPage />}>
|
||||||
|
<Route index element={<PozoPublicHomePage />} />
|
||||||
|
<Route path="purchase" element={<Purchase />} />
|
||||||
|
<Route path="individualCard" element={<PozoIndividualCard />} />
|
||||||
|
<Route path="cart" element={<PozoCart />} />
|
||||||
|
<Route path="store" element={<PozoStore />} />
|
||||||
|
<Route path="order" element={<PozoPublicOrder />} />
|
||||||
|
<Route path="checkout" element={<PozoPublicCheckOut />} />
|
||||||
|
|
||||||
|
<Route path="register" element={<PozoPublicSellerRegister />} />
|
||||||
|
<Route path="Stores" element={<PozoPublicStore />} />
|
||||||
|
<Route path="SignIn" element={<PozoPublicSignIn />} />
|
||||||
|
<Route path="myprofile" element={<PozoPublicMyProfile />} />
|
||||||
|
<Route path="favlist" element={<PozoPublicFavouriteList />} />
|
||||||
|
<Route path="favshop" element={<PozoPublicFavShop />} />
|
||||||
|
<Route path="orderinfo" element={<PozoPublicOrderInfo />} />
|
||||||
|
<Route path="invoice" element={<PozoPublicInvoice />} />
|
||||||
|
<Route path="step" element={<StepProgress />} />
|
||||||
|
<Route path="message" element={<PozoPublicDatePicker />} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path={`${subDirectory}admin-page`} element={<AdminlandingPage />}>
|
||||||
|
<Route path="product" element={<PozoPublicProductMaster />} />
|
||||||
|
<Route path="salesreport" element={<PozoPublicSalesReport />} />
|
||||||
|
<Route path="paymentreport" element={<PozoPublicPaymentReport />} />
|
||||||
|
<Route path="dashboard" element={<PozoPublicDashboard />} />
|
||||||
|
<Route path="graphs" element={<PozoChartGraphs />} />
|
||||||
|
<Route path="sadminreport" element={<PozoPublicSadminReport />} />
|
||||||
|
<Route path="setting" element={<PozoPublicSetting />} />
|
||||||
|
<Route path="orders" element={<Orders />} />
|
||||||
|
<Route path="sadminusers" element={<SadminUsers />} />
|
||||||
|
<Route path="querymanagement" element={<PozoPublicQueryManagement />} />
|
||||||
|
<Route path="grpahchart" element={<GraphChart />} />
|
||||||
|
<Route path="qryrqst" element={<QueryRequest />} />
|
||||||
|
<Route path="querycontact" element={<QueryContact />} />
|
||||||
|
<Route path="sadmindashboard" element={<PozoPublicSAdminDashboard />} />
|
||||||
|
<Route path="adsmanagement" element={<AdsManagement />} />
|
||||||
|
<Route path="myproduct" element={<PozoPublicMyProduct />} />
|
||||||
|
<Route path="custommodal" element={<CustomModal />} />
|
||||||
|
<Route path="overview" element={<SadminOveriew />} />
|
||||||
|
|
||||||
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
|
@ -0,0 +1,706 @@
|
||||||
|
import { CgClose } from "react-icons/cg";
|
||||||
|
import { RiAddBoxLine, RiDeleteBinLine } from "react-icons/ri";
|
||||||
|
import { BsFillCheckCircleFill } from "react-icons/bs";
|
||||||
|
import { IoLogoYoutube, IoMdClose } from "react-icons/io";
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import PozoPublicNavbar from "../../Components/PozoPublicNavbar/PozoPubliNavbar.jsx";
|
||||||
|
import "../../Styles/Pages/PozoPublicSellerRegister.scss"
|
||||||
|
import PozoPublicInputSearch from '../../Components/InputSearch/PozoPublicInputSearch.jsx';
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import AllCategories from "../../Images/AllCategories.png"
|
||||||
|
import book from "../../Images/book.png"
|
||||||
|
import fooddelivery from "../../Images/fooddelivery.png"
|
||||||
|
import grocery from "../../Images/grocery.png"
|
||||||
|
import meat from "../../Images/meat.png"
|
||||||
|
import PozoPublicInput from "../../Components/Input/PozoPublicInput.jsx";
|
||||||
|
const subDirectory = import.meta.env.BASE_URL;
|
||||||
|
import { RxPencil2 } from "react-icons/rx";
|
||||||
|
import FullPageLoader from "../../Components/Loader/PozoPublicLoader.jsx";
|
||||||
|
import PozoPublicButton from "../../Components/Button/PozoPublicButton.jsx";
|
||||||
|
import { MdOutlineAddLocationAlt, MdOutlineWorkOutline } from "react-icons/md";
|
||||||
|
import { HiOutlineHome } from "react-icons/hi";
|
||||||
|
import { TiTick } from "react-icons/ti";
|
||||||
|
import Popconfirm from "../../Components/Popconfirm/Popconfirm.jsx";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const PozoPublicSellerRegister = () => {
|
||||||
|
const [showUserInfoDetails, setShowUserInfoDetails] = useState(false);
|
||||||
|
|
||||||
|
const [userdetail, setUserdetail] = useState(false);
|
||||||
|
// const [showAddressInputs, setShowAddressInputs] = useState(false);
|
||||||
|
const [email, setEmail] = useState("pannerselvam@gmail.com"); // Initial email
|
||||||
|
const [phone, setPhone] = useState("9442603558");
|
||||||
|
const [ShowCancel, setShowCancel] = useState(false);
|
||||||
|
const [editingIndex, setEditingIndex] = useState(null);
|
||||||
|
const [userAddress, setUserAddress] = useState([]);
|
||||||
|
const [pickupAddress, setPickupAddress] = useState([]);
|
||||||
|
|
||||||
|
// State for toggling input visibility
|
||||||
|
const [showAddressInputs, setShowAddressInputs] = useState(false);
|
||||||
|
const [showPickupAddressInputs, setShowPickupAddressInputs] = useState(false);
|
||||||
|
|
||||||
|
// State for new address inputs
|
||||||
|
const [newAddress, setNewAddress] = useState({
|
||||||
|
address1: "",
|
||||||
|
address2: "",
|
||||||
|
city: "",
|
||||||
|
state: "",
|
||||||
|
zipcode: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
const [newPickupAddress, setNewPickupAddress] = useState({
|
||||||
|
address1: "",
|
||||||
|
address2: "",
|
||||||
|
city: "",
|
||||||
|
state: "",
|
||||||
|
zipcode: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
// State for edit functionality
|
||||||
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
|
const [editIndex, setEditIndex] = useState(null);
|
||||||
|
|
||||||
|
// Toggle input visibility for business address
|
||||||
|
const toggleAddressInputs = () => setShowAddressInputs(!showAddressInputs);
|
||||||
|
|
||||||
|
// Toggle input visibility for pickup address
|
||||||
|
const togglePickupAddressInputs = () => setShowPickupAddressInputs(!showPickupAddressInputs);
|
||||||
|
|
||||||
|
// Handle input changes for new address
|
||||||
|
const handleNewAddressChange = (e) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setNewAddress((prev) => ({ ...prev, [name]: value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle input changes for new pickup address
|
||||||
|
const handleNewPickupAddressChange = (e) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setNewPickupAddress((prev) => ({ ...prev, [name]: value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle submission of new address
|
||||||
|
const handleNewAddressSubmit = () => {
|
||||||
|
setUserAddress([...userAddress, newAddress]);
|
||||||
|
setNewAddress({ address1: "", address2: "", city: "", state: "", zipcode: "" });
|
||||||
|
setShowAddressInputs(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle submission of new pickup address
|
||||||
|
const handleNewPickupAddressSubmit = () => {
|
||||||
|
setPickupAddress([...pickupAddress, newPickupAddress]);
|
||||||
|
setNewPickupAddress({ address1: "", address2: "", city: "", state: "", zipcode: "" });
|
||||||
|
setShowPickupAddressInputs(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle editing an address
|
||||||
|
const handleEditAddress = (index, item) => {
|
||||||
|
setNewAddress(item);
|
||||||
|
setIsEditing(true);
|
||||||
|
setEditIndex(index);
|
||||||
|
setShowAddressInputs(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle canceling the edit for business address
|
||||||
|
const handleEditCancel = () => {
|
||||||
|
setNewAddress({ address1: "", address2: "", city: "", state: "", zipcode: "" });
|
||||||
|
setIsEditing(false);
|
||||||
|
setShowAddressInputs(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle updating the edited address
|
||||||
|
const handleUpdateAddress = () => {
|
||||||
|
const updatedAddresses = [...userAddress];
|
||||||
|
updatedAddresses[editIndex] = newAddress;
|
||||||
|
setUserAddress(updatedAddresses);
|
||||||
|
handleEditCancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle editing a pickup address
|
||||||
|
const handleEditPickupAddress = (index, item) => {
|
||||||
|
setNewPickupAddress(item);
|
||||||
|
setIsEditing(true);
|
||||||
|
setEditIndex(index);
|
||||||
|
setShowPickupAddressInputs(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle canceling the edit for pickup address
|
||||||
|
const handlePickupEditCancel = () => {
|
||||||
|
setNewPickupAddress({ address1: "", address2: "", city: "", state: "", zipcode: "" });
|
||||||
|
setIsEditing(false);
|
||||||
|
setShowPickupAddressInputs(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle updating the edited pickup address
|
||||||
|
const handleUpdatePickupAddress = () => {
|
||||||
|
const updatedPickupAddresses = [...pickupAddress];
|
||||||
|
updatedPickupAddresses[editIndex] = newPickupAddress;
|
||||||
|
setPickupAddress(updatedPickupAddresses);
|
||||||
|
handlePickupEditCancel();
|
||||||
|
}; const isSubmitDisabled = Object.values(newAddress).some(field => field === "");
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
console.log("New data submitted:", { email, phone });
|
||||||
|
setUserdetail(false); // Optionally close the edit mode after submission
|
||||||
|
};
|
||||||
|
const [showConfirm, setShowConfirm] = useState(false);
|
||||||
|
const handleConfirm = () => {
|
||||||
|
console.log('Confirmed');
|
||||||
|
setShowConfirm(false);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
console.log('Cancelled');
|
||||||
|
setShowConfirm(false);
|
||||||
|
};
|
||||||
|
const handleClose = () => {
|
||||||
|
// Clean up any additional state or side effects
|
||||||
|
};
|
||||||
|
const [userInfo, setUserInfo] = useState({
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
mb: "",
|
||||||
|
dob: "",
|
||||||
|
gender: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
// const toggleAddressInputs = () => {
|
||||||
|
// setNewAddress({
|
||||||
|
// address1: "",
|
||||||
|
// address2: "",
|
||||||
|
// city: "",
|
||||||
|
// state: "",
|
||||||
|
// zipcode: ""
|
||||||
|
// });
|
||||||
|
// setShowAddressInputs(true);
|
||||||
|
|
||||||
|
// };
|
||||||
|
const toggleUserInfoDetails = () => {
|
||||||
|
setShowUserInfoDetails((prevState) => !prevState);
|
||||||
|
};
|
||||||
|
const handleUserInfoChange = (e) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setUserInfo((prevUserInfo) => ({
|
||||||
|
...prevUserInfo,
|
||||||
|
[name]: value,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// const handleEditAddress = (index, item) => {
|
||||||
|
|
||||||
|
// setNewAddress(item)
|
||||||
|
// setEditingIndex(index);
|
||||||
|
// setShowAddressInputs(true);
|
||||||
|
// setShowCancel(true);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleEditCancel = (index, item) => {
|
||||||
|
// setShowCancel(false);
|
||||||
|
// setShowAddressInputs(false);
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// const [userAddress, setUserAddress] = useState([
|
||||||
|
// {
|
||||||
|
// address1: "dharga hosur",
|
||||||
|
// address2: "software solution",
|
||||||
|
// city: "chennai",
|
||||||
|
// state: "Tamil nadu",
|
||||||
|
// zipcode: "636542"
|
||||||
|
// },
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
|
||||||
|
// Handle new address form submission
|
||||||
|
// const handleNewAddressSubmit = () => {
|
||||||
|
// if (editingIndex !== null) {
|
||||||
|
// // Update existing address
|
||||||
|
// const updatedAddresses = [...userAddress];
|
||||||
|
// updatedAddresses[editingIndex] = newAddress;
|
||||||
|
// setUserAddress(updatedAddresses);
|
||||||
|
// } else {
|
||||||
|
// // Add new address
|
||||||
|
// setUserAddress((prevAddresses) => [...prevAddresses, newAddress]);
|
||||||
|
// }
|
||||||
|
// setNewAddress({
|
||||||
|
// address1: "",
|
||||||
|
// address2: "",
|
||||||
|
// city: "",
|
||||||
|
// state: "",
|
||||||
|
// zipcode: ""
|
||||||
|
// });
|
||||||
|
// setShowAddressInputs(false);
|
||||||
|
// setEditingIndex(null);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const deleteConformination = (index) => {
|
||||||
|
setdeleteconfirmination(false)
|
||||||
|
setUserAddress((prevAddresses) => prevAddresses.filter((_, i) => i !== dataIndex));
|
||||||
|
setNewAddress({
|
||||||
|
address1: "",
|
||||||
|
address2: "",
|
||||||
|
city: "",
|
||||||
|
state: "",
|
||||||
|
zipcode: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleEditSellerUser = () => {
|
||||||
|
setUserdetail(!userdetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const toProductMaster = () => {
|
||||||
|
navigate(`${subDirectory}admin-page/product`);
|
||||||
|
|
||||||
|
}
|
||||||
|
const toggleAddressclose = () => {
|
||||||
|
setNewAddress({
|
||||||
|
address1: "",
|
||||||
|
address2: "",
|
||||||
|
city: "",
|
||||||
|
state: "",
|
||||||
|
zipcode: ""
|
||||||
|
});
|
||||||
|
setShowAddressInputs(false);
|
||||||
|
setShowCancel(false);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const PageNavigate = () => {
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/dashboard`);
|
||||||
|
}, 700);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// const handleNewAddressChange = (e) => {
|
||||||
|
// const { name, value } = e.target;
|
||||||
|
// setNewAddress((prevAddress) => ({
|
||||||
|
// ...prevAddress,
|
||||||
|
// [name]: value
|
||||||
|
// }));
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<>
|
||||||
|
{loading && <FullPageLoader />}
|
||||||
|
|
||||||
|
<div className='PozoPublicSellerRegister-Master'>
|
||||||
|
|
||||||
|
<div className="SellerRegister-Main">
|
||||||
|
|
||||||
|
<div className="SellerRegister-Info">
|
||||||
|
<div className="seller-verfication">
|
||||||
|
<div><BsFillCheckCircleFill color="#E3E3E3" /> Contact Verification</div>
|
||||||
|
<div><BsFillCheckCircleFill /> Business Verification</div>
|
||||||
|
<div><BsFillCheckCircleFill /> Complete</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="sellerName-Highlight">
|
||||||
|
<p> hi , Paneer Selvam</p>
|
||||||
|
<div>
|
||||||
|
{!userdetail &&
|
||||||
|
<div onClick={handleEditSellerUser}> <RxPencil2 /> Edit</div>
|
||||||
|
}
|
||||||
|
{userdetail &&
|
||||||
|
<div onClick={handleEditSellerUser}> <CgClose /> Close </div>
|
||||||
|
}
|
||||||
|
<div> <RiAddBoxLine /> New</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="Contact-Verification">
|
||||||
|
<div className="ContactVerification-header">
|
||||||
|
<div style={{ fontWeight: "600" }}> Contact Verification </div>
|
||||||
|
<div style={{
|
||||||
|
color: "#00A912", fontSize: "12px", fontWeight: "600",
|
||||||
|
display: "flex", alignItems: "center", gap: "5px"
|
||||||
|
}}>
|
||||||
|
<BsFillCheckCircleFill /> VERIFIED
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mailPhone">pannerselvam@gmail.com</div>
|
||||||
|
<div className="mailPhone"> 9442603558</div>
|
||||||
|
</div>
|
||||||
|
{userdetail &&
|
||||||
|
<>
|
||||||
|
<p>Seller Info</p>
|
||||||
|
<div className="sellerNameInfo-Input">
|
||||||
|
<>
|
||||||
|
<PozoPublicInput width="10rem"
|
||||||
|
label={"User Name"} />
|
||||||
|
<PozoPublicInput width="18rem" label={"User E-mail"} />
|
||||||
|
<PozoPublicInput width="12rem" label={"Phone No"} />
|
||||||
|
</>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', justifyContent: "flex-end", width: "100%", paddingRight: "6rem" }}>
|
||||||
|
<PozoPublicButton type={"primary"} buttonText={"submit"} />
|
||||||
|
</div>
|
||||||
|
</>}
|
||||||
|
|
||||||
|
<div className="productOffer" >
|
||||||
|
<div style={{ fontWeight: "600", fontSize: "16px" }}>What products are you offering on Pozo?</div>
|
||||||
|
<div className="productCategories-Main">
|
||||||
|
|
||||||
|
<div style={{ padding: "0rem 2rem 0rem 0rem" }}>
|
||||||
|
<img src={AllCategories} alt="AllCategories" /> <div> ALL CATEGORIES</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src={fooddelivery} alt="fooddelivery" /> <div> FOOD DELIVERY</div>
|
||||||
|
<div className="onlyProduct">ONLY</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src={grocery} alt="grocery" /> <div> GROCERY</div>
|
||||||
|
<div className="onlyProduct">ONLY</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src={meat} alt="meat" /> <div> MEAT</div>
|
||||||
|
<div className="onlyProduct">ONLY</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src={book} alt="book" /> <div> BOOK </div>
|
||||||
|
<div className="onlyProduct">ONLY</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="BusinessVerification">
|
||||||
|
<div className="BusinessVerification-Header">
|
||||||
|
<div style={{ fontWeight: "600" }}> Business Verification </div>
|
||||||
|
<div style={{
|
||||||
|
color: "#00A912", fontSize: "12px", fontWeight: "600",
|
||||||
|
display: "flex", alignItems: "center", gap: "5px"
|
||||||
|
}}> <BsFillCheckCircleFill /> VERIFIED </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="business-Input">
|
||||||
|
<PozoPublicInput
|
||||||
|
label={"Goods and Services Tax (GST) Number"}
|
||||||
|
width="300px" />
|
||||||
|
|
||||||
|
<div className="business-Input2">
|
||||||
|
<PozoPublicInput
|
||||||
|
label={"Business PAN Number"} width="225px" />
|
||||||
|
<PozoPublicInput
|
||||||
|
label={"PAN Copy"} width="100px" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="business-Input2">
|
||||||
|
<PozoPublicInput
|
||||||
|
label={"Food License (FSSAI)"} width="225px" />
|
||||||
|
<PozoPublicInput
|
||||||
|
label={"FSSAI Copy"} width="100px" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="BusinessDetails">
|
||||||
|
<div className="BusinessDetails-Header">
|
||||||
|
<div style={{ fontWeight: "600" }}> Business Verification </div>
|
||||||
|
<div style={{
|
||||||
|
color: "#00A912", fontSize: "12px", fontWeight: "600",
|
||||||
|
display: "flex", alignItems: "center", gap: "5px"
|
||||||
|
}}> <BsFillCheckCircleFill /> VERIFIED </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{/* Business Address Section */}
|
||||||
|
<div className="BuisnessAddress">
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<div className="BuisnessAddress-Header">
|
||||||
|
Business Address
|
||||||
|
<div>
|
||||||
|
{!showAddressInputs ? (
|
||||||
|
<div className="newAdd" onClick={toggleAddressInputs}>
|
||||||
|
<MdOutlineAddLocationAlt /> New
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="newAdd" onClick={handleEditCancel}>
|
||||||
|
<IoMdClose /> Cancel
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="multiple-buisnessAddress">
|
||||||
|
{userAddress.map((item, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
gap: "5rem"
|
||||||
|
}}>
|
||||||
|
<p style={{
|
||||||
|
textTransform: "capitalize",
|
||||||
|
padding: "3px 0px",
|
||||||
|
fontSize: "16px"
|
||||||
|
}}>{item.address1}</p>
|
||||||
|
<div className="edit" onClick={() => handleEditAddress(index, item)}>
|
||||||
|
<RxPencil2 /> Edit
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>{item.address2}</div>
|
||||||
|
<div>{item.city}</div>
|
||||||
|
<div>{item.state} - {item.zipcode}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Pickup Address Section */}
|
||||||
|
<div className="PickupAddress">
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<div className="PickupAddress-Header">
|
||||||
|
Pickup Address
|
||||||
|
<div>
|
||||||
|
{!showPickupAddressInputs ? (
|
||||||
|
<div className="newAdd" onClick={togglePickupAddressInputs}>
|
||||||
|
<MdOutlineAddLocationAlt /> New
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="newAdd" onClick={handlePickupEditCancel}>
|
||||||
|
<IoMdClose /> Cancel
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="multiple-pickupAddress">
|
||||||
|
{pickupAddress.map((item, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<div style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
gap: "5rem"
|
||||||
|
}}>
|
||||||
|
<p style={{
|
||||||
|
textTransform: "capitalize",
|
||||||
|
padding: "3px 0px",
|
||||||
|
fontSize: "16px"
|
||||||
|
}}>{item.address1}</p>
|
||||||
|
<div className="edit" onClick={() => handleEditPickupAddress(index, item)}>
|
||||||
|
<RxPencil2 /> Edit
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>{item.address2}</div>
|
||||||
|
<div>{item.city}</div>
|
||||||
|
<div>{item.state} - {item.zipcode}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* User Address Input Fields */}
|
||||||
|
<div className="userAddress">
|
||||||
|
<div className="userAddressEnter">
|
||||||
|
{showAddressInputs && (
|
||||||
|
<div className="userAddress-inputs">
|
||||||
|
<div className="inputfield">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
value={newAddress.address1}
|
||||||
|
onChange={handleNewAddressChange}
|
||||||
|
placeholder="Enter Address 1"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
value={newAddress.address2}
|
||||||
|
onChange={handleNewAddressChange}
|
||||||
|
placeholder="Enter Address 2"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
value={newAddress.city}
|
||||||
|
onChange={handleNewAddressChange}
|
||||||
|
placeholder="Enter City"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="state"
|
||||||
|
value={newAddress.state}
|
||||||
|
onChange={handleNewAddressChange}
|
||||||
|
placeholder="Enter State"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
value={newAddress.zipcode}
|
||||||
|
onChange={(e) => {
|
||||||
|
let value = e.target.value;
|
||||||
|
value = value.replace(/\D/g, ''); // Remove non-numeric characters
|
||||||
|
setNewAddress((prevAddress) => ({
|
||||||
|
...prevAddress,
|
||||||
|
zipcode: value
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
placeholder="Zip Code"
|
||||||
|
className="AddinputZipcode"
|
||||||
|
pattern="[0-9]*"
|
||||||
|
inputMode="numeric"
|
||||||
|
maxLength="7"
|
||||||
|
/>
|
||||||
|
<div className="addressBTN">
|
||||||
|
<div onClick={isEditing ? handleUpdateAddress : handleNewAddressSubmit}>
|
||||||
|
{isEditing ? "Update" : "Submit"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Pickup Address Input Fields */}
|
||||||
|
<div className="userPickupAddress">
|
||||||
|
<div className="userPickupAddressEnter">
|
||||||
|
{showPickupAddressInputs && (
|
||||||
|
<div className="userPickupAddress-inputs">
|
||||||
|
<div className="inputfield">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
value={newPickupAddress.address1}
|
||||||
|
onChange={handleNewPickupAddressChange}
|
||||||
|
placeholder="Enter Pickup Address 1"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
value={newPickupAddress.address2}
|
||||||
|
onChange={handleNewPickupAddressChange}
|
||||||
|
placeholder="Enter Pickup Address 2"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
value={newPickupAddress.city}
|
||||||
|
onChange={handleNewPickupAddressChange}
|
||||||
|
placeholder="Enter Pickup City"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="state"
|
||||||
|
value={newPickupAddress.state}
|
||||||
|
onChange={handleNewPickupAddressChange}
|
||||||
|
placeholder="Enter Pickup State"
|
||||||
|
className="Addinput"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
value={newPickupAddress.zipcode}
|
||||||
|
onChange={(e) => {
|
||||||
|
let value = e.target.value;
|
||||||
|
value = value.replace(/\D/g, ''); // Remove non-numeric characters
|
||||||
|
setNewPickupAddress((prevAddress) => ({
|
||||||
|
...prevAddress,
|
||||||
|
zipcode: value
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
placeholder="Pickup Zip Code"
|
||||||
|
className="AddinputZipcode"
|
||||||
|
pattern="[0-9]*"
|
||||||
|
inputMode="numeric"
|
||||||
|
maxLength="7"
|
||||||
|
/>
|
||||||
|
<div className="pickupAddressBTN">
|
||||||
|
<div onClick={isEditing ? handleUpdatePickupAddress : handleNewPickupAddressSubmit}>
|
||||||
|
{isEditing ? "Update" : "Submit"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="SellerCompleteBTN">
|
||||||
|
<div onClick={PageNavigate}>COMPLETE</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className="SellerRegister-NewPro">
|
||||||
|
|
||||||
|
<div className='NewPro1'> Add New Product </div>
|
||||||
|
<div className='NewPro2'> Add Products using product available on pozo </div>
|
||||||
|
<div className='NewPro-Search'>
|
||||||
|
<PozoPublicInputSearch
|
||||||
|
width='30vw' />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='NewPro3'> Create your listing </div>
|
||||||
|
<div className="NewPro-BTN">
|
||||||
|
<div onClick={toProductMaster}> + Single Product</div>
|
||||||
|
<div> + Bulk Product</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ border: "1px dashed rgb(28 28 28 / 73%)", width: "100%" }}> </div>
|
||||||
|
|
||||||
|
<div className="NewPro-YoutubeLink">
|
||||||
|
<div className="YoutubeLink1">
|
||||||
|
<div> Learn product listing </div>
|
||||||
|
<div>
|
||||||
|
<IoLogoYoutube size={40} color="#e33333" />
|
||||||
|
</div>
|
||||||
|
<div style={{ color: "#0071E3", fontSize: "11px" }}>Learn More</div>
|
||||||
|
</div>
|
||||||
|
<div className="YoutubeLink2">
|
||||||
|
<div>Learn product listing </div>
|
||||||
|
<div>
|
||||||
|
<IoLogoYoutube size={40} color="#e33333" />
|
||||||
|
</div>
|
||||||
|
<div style={{ color: "#0071E3", fontSize: "11px" }}>Learn More</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicSellerRegister;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import "../Arc/Arc.scss"
|
||||||
|
|
||||||
|
const Arc = ({ value, maxValue }) => {
|
||||||
|
|
||||||
|
const percentage = (value / maxValue) * 100;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="progress-bar">
|
||||||
|
<div className="progress-bar__circle">
|
||||||
|
<div className="progress-bar__circle-inner" style={{ transform: `rotate(${percentage * 1.8}deg)` }}></div>
|
||||||
|
</div>
|
||||||
|
<div className="progress-bar__text">₹{value}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Arc;
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// .progress-bar {
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: center;
|
||||||
|
// position: relative;
|
||||||
|
// width: 200px;
|
||||||
|
// height: 100px;
|
||||||
|
|
||||||
|
// &__circle {
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
// border-radius: 100px 100px 0 0;
|
||||||
|
// background: conic-gradient(purple 0%,
|
||||||
|
// purple calc(var(--percentage) * 1%),
|
||||||
|
// lightgray calc(var(--percentage) * 1%),
|
||||||
|
// lightgray 100%);
|
||||||
|
// position: relative;
|
||||||
|
// overflow: hidden;
|
||||||
|
|
||||||
|
// &-inner {
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
// background: inherit;
|
||||||
|
// transform-origin: bottom center;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &__text {
|
||||||
|
// position: absolute;
|
||||||
|
// bottom: 10px;
|
||||||
|
// font-size: 1.5rem;
|
||||||
|
// font-weight: bold;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import React from 'react';
|
||||||
|
import "../Button/PozoPublicButton.scss"
|
||||||
|
|
||||||
|
const PozoPublicButton = ({ type, buttonText, handleSubmit, suffix, disabled, htmlType, prefix }) => {
|
||||||
|
const classNames = {
|
||||||
|
primary: 'primary_Button',
|
||||||
|
secondary: '',
|
||||||
|
tertiary: 'tertiary_Button',
|
||||||
|
disabled: 'disabled_Button',
|
||||||
|
danger: 'danger_Button',
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttonClassName = classNames[type] || 'default_Button';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
type={htmlType || 'button'}
|
||||||
|
className={buttonClassName}
|
||||||
|
onClick={handleSubmit}
|
||||||
|
disabled={disabled || false}
|
||||||
|
>
|
||||||
|
{prefix}
|
||||||
|
{buttonText}
|
||||||
|
{suffix}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicButton;
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* Base button styles */
|
||||||
|
.primary_Button,
|
||||||
|
.secondary_Button,
|
||||||
|
.tertiary_Button,
|
||||||
|
.disabled_Button,
|
||||||
|
.danger_Button {
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px 18px;
|
||||||
|
width: max-content;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: 'Poppins', sans-serif; // Ensure the font is applied
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 0.5rem; // Adjust column-gap for better spacing
|
||||||
|
transition: background-color 0.3s ease, transform 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-family: "GIlroy";
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary button styles */
|
||||||
|
.primary_Button {
|
||||||
|
background-color: #1C1C1C;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary_Button:hover {
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Secondary button styles */
|
||||||
|
.secondary_Button {
|
||||||
|
background-color: #fff;
|
||||||
|
color: var(--secondayBTN-color);
|
||||||
|
border: 1px solid var(--secondayBTN-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary_Button:hover {
|
||||||
|
background-color: #ffffffc5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tertiary button styles */
|
||||||
|
.tertiary_Button {
|
||||||
|
background-color: var(--dark-red-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tertiary_Button:hover {
|
||||||
|
background-color: #ce2929;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disabled button styles */
|
||||||
|
.disabled_Button {
|
||||||
|
background-color: lightgray;
|
||||||
|
color: whitesmoke;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled_Button:hover,
|
||||||
|
.disabled_Button:focus {
|
||||||
|
background-color: lightgray;
|
||||||
|
color: whitesmoke;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Danger button styles */
|
||||||
|
.danger_Button {
|
||||||
|
background-color: #F8CCCC80;
|
||||||
|
color: #e33333;
|
||||||
|
font-weight: 550;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger_Button:hover {
|
||||||
|
background-color: #f8ccccb7;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React, { useRef, useEffect } from 'react';
|
||||||
|
|
||||||
|
const HalfCircleTubeChart = ({ data }) => {
|
||||||
|
const canvasRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const canvas = canvasRef.current;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
const total = data.reduce((acc, value) => acc + value, 0);
|
||||||
|
const width = canvas.width;
|
||||||
|
const height = canvas.height;
|
||||||
|
const centerX = width / 2;
|
||||||
|
const centerY = height;
|
||||||
|
const outerRadius = Math.min(width, height) / 2 - 10; // Outer radius
|
||||||
|
const innerRadius = outerRadius - 20; // Inner radius
|
||||||
|
const gap = 2; // Space between arcs in degrees
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, width, height); // Clear the canvas
|
||||||
|
|
||||||
|
let startAngle = Math.PI; // Start from the leftmost point (180 degrees)
|
||||||
|
|
||||||
|
data.forEach((value, index) => {
|
||||||
|
const sliceAngle = (value / total) * Math.PI; // Calculate the angle for each slice
|
||||||
|
const gapAngle = (gap / 180) * Math.PI; // Convert gap from degrees to radians
|
||||||
|
|
||||||
|
// Draw outer arc (tube)
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(centerX, centerY); // Move to the center
|
||||||
|
ctx.arc(centerX, centerY, outerRadius, startAngle, startAngle + sliceAngle, false); // Draw outer arc
|
||||||
|
ctx.lineTo(centerX + innerRadius * Math.cos(startAngle + sliceAngle), centerY + innerRadius * Math.sin(startAngle + sliceAngle)); // Draw line to inner arc
|
||||||
|
ctx.arc(centerX, centerY, innerRadius, startAngle + sliceAngle, startAngle, true); // Draw inner arc
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fillStyle = getColor(index); // Get a color for each slice
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
// Update the starting angle for the next slice, including the gap
|
||||||
|
startAngle += sliceAngle + gapAngle;
|
||||||
|
});
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
const getColor = (index) => {
|
||||||
|
const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40'];
|
||||||
|
return colors[index % colors.length]; // Cycle through colors
|
||||||
|
};
|
||||||
|
|
||||||
|
return <canvas ref={canvasRef} width={400} height={200} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HalfCircleTubeChart;
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
// import './ArcChart.scss';
|
||||||
|
|
||||||
|
const HalfArcChart = ({
|
||||||
|
values,
|
||||||
|
radius = 30,
|
||||||
|
strokeWidth = 10,
|
||||||
|
colors = ["green", "#EE89DF", "#F6CF7D", "#2196f3"],
|
||||||
|
gap = 5, // Gap between arcs
|
||||||
|
}) => {
|
||||||
|
const total = values.reduce((acc, val) => acc + val, 0); // Sum of all values
|
||||||
|
const normalizedRadius = radius - strokeWidth * 0.5;
|
||||||
|
const circumference = normalizedRadius * Math.PI; // Circumference for half-circle (πr)
|
||||||
|
|
||||||
|
const calculateDashArray = (value) => (value / total) * circumference;
|
||||||
|
|
||||||
|
const [hoveredIndex, setHoveredIndex] = useState(null); // State to track the hovered arc
|
||||||
|
|
||||||
|
let cumulativeOffset = 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: "relative" }}>
|
||||||
|
<svg
|
||||||
|
height={radius + strokeWidth}
|
||||||
|
width={radius * 2}
|
||||||
|
viewBox={`0 0 ${radius * 2} ${radius + strokeWidth}`}
|
||||||
|
>
|
||||||
|
{/* Background Path */}
|
||||||
|
<path
|
||||||
|
d={`M ${strokeWidth / 2},${radius} a ${normalizedRadius},${normalizedRadius} 0 1,1 ${normalizedRadius * 2},0`}
|
||||||
|
stroke="#ddd"
|
||||||
|
fill="transparent"
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Arcs for each value */}
|
||||||
|
{values.map((value, index) => {
|
||||||
|
const dashArray = calculateDashArray(value);
|
||||||
|
const dashOffset = circumference - cumulativeOffset;
|
||||||
|
cumulativeOffset += dashArray + gap; // Update cumulative offset for next segment, including gap
|
||||||
|
|
||||||
|
// Calculate the arc start point (always starting from the left side)
|
||||||
|
const startX = strokeWidth / 2;
|
||||||
|
const startY = radius;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g key={index}>
|
||||||
|
<path
|
||||||
|
d={`M ${startX},${startY} a ${normalizedRadius},${normalizedRadius} 0 0,1 ${normalizedRadius * 2},0`}
|
||||||
|
stroke={colors[index]}
|
||||||
|
fill="transparent"
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
strokeDasharray={`${dashArray} ${circumference}`}
|
||||||
|
strokeDashoffset={dashOffset}
|
||||||
|
strokeLinecap="round"
|
||||||
|
onMouseEnter={() => setHoveredIndex(index)} // Set hovered index on mouse enter
|
||||||
|
onMouseLeave={() => setHoveredIndex(null)} // Clear hovered index on mouse leave
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* Display percentages */}
|
||||||
|
<text
|
||||||
|
x="50%"
|
||||||
|
y="50%"
|
||||||
|
dominantBaseline="middle"
|
||||||
|
textAnchor="middle"
|
||||||
|
fontSize="18px"
|
||||||
|
fill="#000"
|
||||||
|
>
|
||||||
|
{values.map((val) => `${Math.round((val / total) * 100)}%`).join(" / ")}
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{/* Tooltip */}
|
||||||
|
{hoveredIndex !== null && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: "50%",
|
||||||
|
top: "50%",
|
||||||
|
transform: "translate(-50%, -100%)", // Center the tooltip above the arc
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
border: "1px solid #ccc",
|
||||||
|
padding: "5px",
|
||||||
|
borderRadius: "4px",
|
||||||
|
pointerEvents: "none",
|
||||||
|
whiteSpace: "nowrap"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{`Value: ${values[hoveredIndex]}`}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HalfArcChart;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
@keyframes sliceIn {
|
||||||
|
0% {
|
||||||
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,361 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import './GraphChart.scss'; // For styling
|
||||||
|
|
||||||
|
const GraphChart = ({ datasets }) => {
|
||||||
|
const [valueFormat, setValueFormat] = useState('inr');
|
||||||
|
const [animate, setAnimate] = useState(false);
|
||||||
|
const [selectedDataset, setSelectedDataset] = useState(0);
|
||||||
|
const [tooltip, setTooltip] = useState({ show: false, x: 0, y: 0, label: '', value: '', date: '' });
|
||||||
|
console.log(datasets,"datasets")
|
||||||
|
useEffect(() => {
|
||||||
|
setAnimate(true);
|
||||||
|
getYBenchmarks()
|
||||||
|
}, [selectedDataset]);
|
||||||
|
|
||||||
|
console.log(selectedDataset,"selectedDataset")
|
||||||
|
|
||||||
|
const formatToINR = (value) => {
|
||||||
|
return new Intl.NumberFormat('en-IN', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'INR',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
}).format(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatToKValues = (value) => {
|
||||||
|
return value >= 1000 ? `${(value / 1000).toFixed(1)}K` : value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatValue = (value) => {
|
||||||
|
return valueFormat === 'inr' ? formatToINR(value) : formatToKValues(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseOver = (e, point) => {
|
||||||
|
setTooltip({
|
||||||
|
show: true,
|
||||||
|
x: e.clientX,
|
||||||
|
y: e.clientY,
|
||||||
|
label: point.label,
|
||||||
|
value: formatValue(point.value),
|
||||||
|
date: point.date,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseOut = () => {
|
||||||
|
setTooltip({ ...tooltip, show: false });
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCurvePath = (data) => {
|
||||||
|
const maxValue = Math.max(...data.map(item => item.value));
|
||||||
|
const svgHeight = 200;
|
||||||
|
const svgWidth = 400;
|
||||||
|
const gap = svgWidth / (data.length - 1);
|
||||||
|
|
||||||
|
return data.map((point, index) => {
|
||||||
|
const x = index * gap;
|
||||||
|
const y = svgHeight - (point.value / maxValue) * svgHeight;
|
||||||
|
|
||||||
|
if (index === 0) return `M ${x},${y}`;
|
||||||
|
|
||||||
|
const prevX = (index - 1) * gap;
|
||||||
|
const prevY = svgHeight - (data[index - 1].value / maxValue) * svgHeight;
|
||||||
|
const controlPointX = (prevX + x) / 2;
|
||||||
|
|
||||||
|
return `C ${controlPointX},${prevY} ${controlPointX},${y} ${x},${y}`;
|
||||||
|
}).join(' ');
|
||||||
|
};
|
||||||
|
|
||||||
|
// const renderDots = (data, color) => {
|
||||||
|
// const maxValue = Math.max(...data.map(item => item.value));
|
||||||
|
// const svgHeight = 200;
|
||||||
|
// const svgWidth = 400;
|
||||||
|
// const gap = svgWidth / (data.length - 1);
|
||||||
|
|
||||||
|
// return data.map((point, index) => {
|
||||||
|
// const x = index * gap;
|
||||||
|
// const y = svgHeight - (point.value / maxValue) * svgHeight;
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <g key={index}>
|
||||||
|
// <circle
|
||||||
|
// cx={x}
|
||||||
|
// cy={animate ? y : svgHeight}
|
||||||
|
// r={5}
|
||||||
|
// fill={color}
|
||||||
|
// stroke={color}
|
||||||
|
// strokeWidth="2"
|
||||||
|
// style={{ transition: 'cy 0.5s ease-in-out' }}
|
||||||
|
// onMouseOver={(e) => handleMouseOver(e, point)}
|
||||||
|
// onMouseOut={handleMouseOut}
|
||||||
|
// />
|
||||||
|
// <text x={x} y={y - 10} fill="black" fontSize="12" textAnchor="middle">
|
||||||
|
// {formatValue(point.value)} ({item.date})
|
||||||
|
// </text>
|
||||||
|
// </g>
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
const renderDots = (data, color) => {
|
||||||
|
const maxValue = Math.max(...data.map(item => item.value));
|
||||||
|
const svgHeight = 200;
|
||||||
|
const svgWidth = 400;
|
||||||
|
const gap = svgWidth / (data.length - 1);
|
||||||
|
|
||||||
|
return data.map((point, index) => {
|
||||||
|
const x = index * gap;
|
||||||
|
const y = svgHeight - (point.value / maxValue) * svgHeight;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g key={index}>
|
||||||
|
<circle
|
||||||
|
cx={x}
|
||||||
|
cy={animate ? y : svgHeight}
|
||||||
|
r={5}
|
||||||
|
fill={color}
|
||||||
|
stroke={color}
|
||||||
|
strokeWidth="2"
|
||||||
|
style={{ transition: 'cy 0.5s ease-in-out' }}
|
||||||
|
onMouseOver={(e) => handleMouseOver(e, point)}
|
||||||
|
onMouseOut={handleMouseOut}
|
||||||
|
/>
|
||||||
|
<text x={x} y={y - 10} fill="black" fontSize="12" textAnchor="middle">
|
||||||
|
{formatValue(point.value)}
|
||||||
|
{/* ({point.date}) */}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const renderArea = (data, color) => {
|
||||||
|
const maxValue = Math.max(...data.map(item => item.value));
|
||||||
|
const svgHeight = 200;
|
||||||
|
const svgWidth = 400;
|
||||||
|
const gap = svgWidth / (data.length - 1);
|
||||||
|
|
||||||
|
const points = data.map((point, index) => {
|
||||||
|
const x = index * gap;
|
||||||
|
const y = svgHeight - (point.value / maxValue) * svgHeight;
|
||||||
|
return `${x},${animate ? y : svgHeight}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return `M 0,${svgHeight} L ${points.join(' L ')} L ${svgWidth},${svgHeight} Z`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getYBenchmarks = () => {
|
||||||
|
// Index of the dataset you want to access
|
||||||
|
const maxValue = Math.max(...datasets[selectedDataset]?.data.map(item => item.value) || []); const step = maxValue / 5;
|
||||||
|
return Array.from({ length: 6 }, (_, i) => Math.round(i * step)).reverse();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const calculateOverallAmount = () => {
|
||||||
|
return datasets.reduce((total, dataset) => {
|
||||||
|
return total + dataset.data.reduce((subTotal, item) => subTotal + item.value, 0);
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isAllValuesSelected = selectedDataset === datasets.length;
|
||||||
|
|
||||||
|
|
||||||
|
const findHighest = () => {
|
||||||
|
const allValuesWithIndex = datasets.flatMap((dataset, datasetIndex) =>
|
||||||
|
dataset.data.map((item, index) => ({
|
||||||
|
value: item.value,
|
||||||
|
datasetIndex,
|
||||||
|
index // index within the dataset
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the highest value
|
||||||
|
const highestValueEntry = allValuesWithIndex.reduce((max, entry) =>
|
||||||
|
entry.value > max.value ? entry : max,
|
||||||
|
allValuesWithIndex[0] // initial max value entry
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the index of the highest value
|
||||||
|
const highestValueIndex = {
|
||||||
|
datasetIndex: highestValueEntry.datasetIndex,
|
||||||
|
dataIndex: highestValueEntry.index
|
||||||
|
};
|
||||||
|
|
||||||
|
setSelectedDataset(highestValueEntry.datasetIndex)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="curve-graph-container">
|
||||||
|
<div className='curve-grp-head' style={{ display: 'flex', justifyContent: 'space-between', flexDirection: 'row', width: '100%', padding: '1rem 0', alignItems: 'center' }}>
|
||||||
|
<div className='ttlAmntMas'>
|
||||||
|
<a> OVERALL REVENUE</a>
|
||||||
|
<a className='ttlAmnt'>{formatValue(calculateOverallAmount())}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='inrKtabMaster'>
|
||||||
|
<button
|
||||||
|
className={`inrKtab ${valueFormat === 'inr' ? 'active' : ''}`}
|
||||||
|
onClick={() => {
|
||||||
|
setValueFormat('inr');
|
||||||
|
setAnimate(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
INR
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`inrKtab ${valueFormat === 'k' ? 'active' : ''}`}
|
||||||
|
onClick={() => {
|
||||||
|
setValueFormat('k');
|
||||||
|
setAnimate(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
K
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ zIndex: '3', position: 'absolute', top: tooltip.y, left: tooltip.x, display: tooltip.show ? 'block' : 'none', backgroundColor: 'white', padding: '5px', border: '1px solid #ccc', borderRadius: '3px', pointerEvents: 'none' }}>
|
||||||
|
<div>{tooltip.label}</div>
|
||||||
|
<div>{tooltip.value}</div>
|
||||||
|
<div>{tooltip.date}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='cruvGrphSwitchtabs' style={{ display: 'flex' }}>
|
||||||
|
<div>
|
||||||
|
<div style={{ display: "flex", }}>
|
||||||
|
<div className="benchmark-labels">
|
||||||
|
{getYBenchmarks().map((value, index) => (
|
||||||
|
<div key={index} className="benchmark-label">{formatValue(value)}</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', position: 'relative', width: '400px' }}>
|
||||||
|
<svg
|
||||||
|
viewBox="-30 -30 466 236"
|
||||||
|
preserveAspectRatio="xMidYMid meet"
|
||||||
|
style={{ width: '100%', height: 'inherit' }}
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
{isAllValuesSelected ? (
|
||||||
|
datasets.map((dataset, index) => (
|
||||||
|
<g key={index}>
|
||||||
|
<path
|
||||||
|
d={renderArea(dataset.data, dataset.color)}
|
||||||
|
fill={`${dataset.color}50`}
|
||||||
|
className={`area ${animate ? 'animated' : ''}`}
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d={getCurvePath(dataset.data)}
|
||||||
|
stroke={dataset.color}
|
||||||
|
strokeWidth="2"
|
||||||
|
fill="none"
|
||||||
|
className={`curve ${animate ? 'animated' : ''}`}
|
||||||
|
style={{
|
||||||
|
strokeDasharray: '1000',
|
||||||
|
strokeDashoffset: animate ? '0' : '1000',
|
||||||
|
transition: 'stroke-dashoffset 1s ease-in-out',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{renderDots(dataset.data, dataset.color)}
|
||||||
|
</g>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d={renderArea(datasets[selectedDataset].data, datasets[selectedDataset].color)}
|
||||||
|
fill={`${datasets[selectedDataset].color}50`}
|
||||||
|
className={`area ${animate ? 'animated' : ''}`}
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d={getCurvePath(datasets[selectedDataset].data)}
|
||||||
|
stroke={datasets[selectedDataset].color}
|
||||||
|
strokeWidth="2"
|
||||||
|
fill="none"
|
||||||
|
className={`curve ${animate ? 'animated' : ''}`}
|
||||||
|
style={{
|
||||||
|
strokeDasharray: '1000',
|
||||||
|
strokeDashoffset: animate ? '0' : '1000',
|
||||||
|
transition: 'stroke-dashoffset 1s ease-in-out',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{renderDots(datasets[selectedDataset].data, datasets[selectedDataset].color)}
|
||||||
|
</g>
|
||||||
|
)}
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div className="labels">
|
||||||
|
{isAllValuesSelected ? (
|
||||||
|
datasets[0].data.map((item, index) => (
|
||||||
|
<span key={index} className="label">{item.label}</span>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
datasets[selectedDataset].data.map((item, index) => (
|
||||||
|
<span key={index} className="label">{item.label} </span>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="tabs">
|
||||||
|
<button
|
||||||
|
className={`tab ${isAllValuesSelected ? 'active' : ''}`} // Fixed template literal syntax
|
||||||
|
onClick={() => {
|
||||||
|
findHighest();
|
||||||
|
setAnimate(true); // Trigger animation on tab switch
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: '#000',
|
||||||
|
marginRight: '5px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
All
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{datasets.map((dataset, index) => (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
className={`tab ${selectedDataset === index ? 'active' : ''}`} // Fixed template literal syntax
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedDataset(index);
|
||||||
|
setAnimate(true); // Trigger animation on tab switch
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
width: '6px',
|
||||||
|
height: '6px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: dataset.color,
|
||||||
|
marginRight: '5px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span className='valperamt'>
|
||||||
|
<a> {dataset.name} </a>
|
||||||
|
<span>{formatValue(dataset.data.reduce((total, d) => total + d.value, 0))} </span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GraphChart;
|
||||||
|
|
@ -0,0 +1,223 @@
|
||||||
|
.curve-graph-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
// width: 100vh;
|
||||||
|
margin: 1px 0rem;
|
||||||
|
font-family: "Gilroy" !important;
|
||||||
|
|
||||||
|
|
||||||
|
.grtooltip {
|
||||||
|
background-color: #E33333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.benchmark-labels {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: inherit;
|
||||||
|
font-size: 11px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.ttlAmntMas {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ttlAmnt {
|
||||||
|
font-size: 35px;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
color: #242424;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.benchmark-label {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.curve-graph-container svg {
|
||||||
|
// background: repeating-linear-gradient(
|
||||||
|
// 90deg,
|
||||||
|
// rgb(255, 255, 255),
|
||||||
|
// rgb(255, 255, 255) 10px,
|
||||||
|
// #ecb7b7 1px,
|
||||||
|
// #f8e3e3 11px
|
||||||
|
// );
|
||||||
|
// background-image: linear-gradient(90deg, #f8e3e3 20%, #ffffff 20%, #ffffff 50%, #f8e3e3 50%, #f8e3e3 70%, #ffffff 70%, #ffffff 100%);
|
||||||
|
// background-size: 10.00px 10.00px;
|
||||||
|
|
||||||
|
background-image: linear-gradient(90deg, #ebebeb 20%, #ffffff 20%, #ffffff 50%, #ebebeb 50%, #ebebeb 70%, #ffffff 70%, #ffffff 100%);
|
||||||
|
background-size: 10.00px 10.00px;
|
||||||
|
|
||||||
|
// border: 1px solid #ccc;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labels {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: inherit;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 0.5rem;
|
||||||
|
width: max-content;
|
||||||
|
|
||||||
|
button {
|
||||||
|
|
||||||
|
|
||||||
|
.valperamt {
|
||||||
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 10.5px;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 19px;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// margin-right: 15px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
background: none;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
// font-weight: bold;
|
||||||
|
color: #E33333;
|
||||||
|
// border-bottom: 2px solid #333; // Example of active tab styling
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8; // Add some hover effect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.inrKtabMaster {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.inrKtab {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 15px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
height: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #ffffff3f;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: none;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
// font-weight: bold;
|
||||||
|
color: #E33333;
|
||||||
|
background-color: #e333331c;
|
||||||
|
|
||||||
|
// border-bottom: 2px solid #333; // Example of active tab styling
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8; // Add some hover effect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.area {
|
||||||
|
animation: rise 1s forwards;
|
||||||
|
/* Animate background fill */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rise {
|
||||||
|
from {
|
||||||
|
transform: translateY(100%);
|
||||||
|
/* Start from the bottom */
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
/* Rise to the final position */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.curve {
|
||||||
|
animation: draw 3s forwards;
|
||||||
|
/* Animate curved line drawing */
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes draw {
|
||||||
|
from {
|
||||||
|
stroke-dashoffset: 1000;
|
||||||
|
/* Start from the right */
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
/* Complete the drawing */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width:768px) {
|
||||||
|
|
||||||
|
.curve-grp-head {
|
||||||
|
justify-content: unset !important;
|
||||||
|
gap: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cruvGrphSwitchtabs {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 1rem;
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
flex-direction: row !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
.HorBarHead2 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-family: "Gilroy" !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.HBDiv2 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
animation: shutter-in-lefte 3s ease 0s 1 normal none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBLabel2 {
|
||||||
|
font-weight: 500 !important;
|
||||||
|
width: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBContainer2 {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
// animation: shutter-in-lefte 3s ease 0s 1 normal none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.animationHB {
|
||||||
|
animation: shutter-in-left 0.5s ease-in 0s 1 normal forwards;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shutter-in-left {
|
||||||
|
|
||||||
|
0% {
|
||||||
|
transform: rotateY(100deg);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateY(0);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React from 'react';
|
||||||
|
import "./HorBar2Chart.scss"
|
||||||
|
const HorizontalBarChart = ({ data, maxValue }) => {
|
||||||
|
return (
|
||||||
|
<div style={{margin:'2rem 0rem'}}>
|
||||||
|
<div className="HorBarHead2" style={{rowGap:'0.7rem'}}>
|
||||||
|
{data.map((item, index) => (
|
||||||
|
<div className="HBDiv2" key={index}>
|
||||||
|
<div style={{fontWeight:'600', width:'25px', fontSize:'10px', textTransform:'uppercase'}} className="HBLabel2">{item?.label}</div>
|
||||||
|
|
||||||
|
<div className="HBContainer2" style={{ display: 'flex', alignItems: 'center', }}>
|
||||||
|
<div style={{ background: "#ddd", width: '100%', display: 'flex', height: '22px' }}>
|
||||||
|
<div style={{ background: "#F7D181", width: `${(item?.value1 / maxValue) * 100}%`,display:"flex", alignItems:"center", justifyContent:"start", padding:"0rem 2rem", fontWeight:"600", color:"#464646" , fontSize:"11.5px"}} > ₹{item?.value1} </div>
|
||||||
|
<div style={{ background: "#9F97F1", width: `${(item?.value2 / maxValue) * 100}%`, display:"flex", alignItems:"center", justifyContent:"end", padding:"0rem 2rem", fontWeight:"600", color:"#464646", fontSize:"11.5px"}} >₹{item?.value2} </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HorizontalBarChart;
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import React from 'react';
|
||||||
|
import './HorBarChart.scss'; // Import the CSS file for styling
|
||||||
|
|
||||||
|
const BarChart = ({ data }) => {
|
||||||
|
const maxValue = Math.max(...data.map(item => item.value)); // Find the maximum value for scaling
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="Horbarchart">
|
||||||
|
<div>
|
||||||
|
<div className='HorBarHead' >
|
||||||
|
|
||||||
|
{data.map((item, index) => (
|
||||||
|
<>
|
||||||
|
<div className='HBDiv'>
|
||||||
|
|
||||||
|
<div className='HBLabel'> {item.label}</div>
|
||||||
|
<div className='HBContainer' >
|
||||||
|
|
||||||
|
{/* <div className='HBLabel'> {item.label}</div> */}
|
||||||
|
|
||||||
|
<div style={{background:"#ddd",margin:"0rem 0rem", width:'100%'}}>
|
||||||
|
|
||||||
|
<div style={{background:"#82BCFD", width: `${(item.value / maxValue) * 100}%`, height:'20px',}}></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{margin:"0rem 1rem",fontSize:"11px", fontWeight:"600"}}>{item.value}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BarChart;
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
.HorBarHead {
|
||||||
|
margin: 1rem 0rem;
|
||||||
|
font-family: "Gilroy" !important;
|
||||||
|
|
||||||
|
.HBDiv {
|
||||||
|
margin: 0.5rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBLabel {
|
||||||
|
font-size: 11px;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
row-gap: 1rem;
|
||||||
|
animation: shutter-in-left 2.5s ease 0s 1 normal none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shutter-in-left {
|
||||||
|
0% {
|
||||||
|
transform: rotateY(100deg);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateY(0);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import React from 'react';
|
||||||
|
import './HorBarChart3.scss';
|
||||||
|
|
||||||
|
const BarChart3 = ({ data }) => {
|
||||||
|
const sortedData = [...data].sort((a, b) => b.value - a.value);
|
||||||
|
const maxValue = Math.max(...sortedData.map(item => item.value));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="Horbarchart3">
|
||||||
|
<div>
|
||||||
|
<div className='HorBarHead3'>
|
||||||
|
{sortedData.map((item, index) => (
|
||||||
|
<div key={index} className='HBDiv3'>
|
||||||
|
<div className='HBContainer3'>
|
||||||
|
<div className='HBLabel3'>{item.label}</div>
|
||||||
|
<div className="HBBarContainer3" style={{ background: "#fff", width: '100%', display: "flex" }}>
|
||||||
|
<div
|
||||||
|
className="HBBar3"
|
||||||
|
style={{
|
||||||
|
background: item.color,
|
||||||
|
width: `${(item.value / maxValue) * 100}%`,
|
||||||
|
height: '20px',
|
||||||
|
position: 'relative',
|
||||||
|
}}>
|
||||||
|
</div>
|
||||||
|
<span className="HBValue3">₹{item.value}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BarChart3;
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
.Horbarchart3 {
|
||||||
|
font-family: "Gilroy" !important;
|
||||||
|
|
||||||
|
.HorBarHead3 {
|
||||||
|
.HBDiv3 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBContainer3 {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.1rem 0rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBLabel3 {
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 10px;
|
||||||
|
width: 70px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBBarContainer3 {
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBBar3 {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBValue3 {
|
||||||
|
|
||||||
|
color: #464646;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 0rem 4px;
|
||||||
|
font-weight: 600;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.HBBarContainer3 {
|
||||||
|
animation: shutter-in-left 2s linear 0s 1 normal forwards;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shutter-in-left {
|
||||||
|
|
||||||
|
0% {
|
||||||
|
transform: rotateY(-100deg);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateY(0);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
// PozoGraphchart.jsx
|
||||||
|
import React from 'react';
|
||||||
|
import PozoPublicBarchart from "../../Components/Charts/PozoPublicBarchart.jsx"; // Adjust path as needed
|
||||||
|
import HalfArcChart from './ArcChart.jsx';
|
||||||
|
import HorBarChart from './HorBarChart.jsx';
|
||||||
|
import HorizontalBarChart from './HorBar2Chart.jsx';
|
||||||
|
import PozoPublicPieChart from "./PozoPublicPieChart.jsx"
|
||||||
|
const PozoGraphchart = () => {
|
||||||
|
const chartData = [
|
||||||
|
{ month: "Jan", value1: 30, value2: 30, value3: 20 },
|
||||||
|
{ month: "Feb", value1: 70, value2: 10, value3: 40 },
|
||||||
|
{ month: "Mar", value1: 40, value2: 20, value3: 60 },
|
||||||
|
{ month: "Apr", value1: 60, value2: 50, value3: 30 },
|
||||||
|
{ month: "May", value1: 80, value2: 60, value3: 20 },
|
||||||
|
{ month: "Jun", value1: 90, value2: 70, value3: 50 },
|
||||||
|
{ month: "Jul", value1: 70, value2: 80, value3: 30 },
|
||||||
|
{ month: "Aug", value1: 60, value2: 90, value3: 40 },
|
||||||
|
{ month: "Sep", value1: 100, value2: 20, value3:70 },
|
||||||
|
{ month: "Oct", value1: 80, value2: 60, value3: 50 },
|
||||||
|
{ month: "Nov", value1: 90, value2: 30, value3: 40 },
|
||||||
|
{ month: "Dec", value1:90, value2: 90, value3: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{ label: 'INDIA', value: 100 },
|
||||||
|
{ label: 'SINGAPORE', value: 200 },
|
||||||
|
{ label: 'DUBAI', value: 300 },
|
||||||
|
{ label: 'DUBAI', value: 400 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const data2 = [
|
||||||
|
{ label: "Jan", value1: 40, value2: 60 },
|
||||||
|
{ label: "Feb", value1: 30, value2: 70 },
|
||||||
|
{ label: "Mar", value1: 50, value2: 50 },
|
||||||
|
{ label: "Apr", value1: 20, value2: 80 },
|
||||||
|
];
|
||||||
|
const data4 = [30, 70,50, 60,40,150,250];
|
||||||
|
const maxValue = 100;
|
||||||
|
const values = [25, 35, 20, 20];
|
||||||
|
const staticStrokeValues = [0, 25, 50, 75, 100];
|
||||||
|
|
||||||
|
const data6 = [
|
||||||
|
{ value: 300, color: '#EE89DF', name:"Pozo Cart", date: "2024-09-01" },
|
||||||
|
{ value: 180, color: '#A29BF2' , name:"Grocery", date: "2024-09-02" },
|
||||||
|
{ value: 120, color: '#F6CF7D', name:"Food Delivery", date: "2024-09-03" },
|
||||||
|
{ value: 300, color: '#EE89DF', name:"Pozo Cart", date: "2024-09-01" },
|
||||||
|
{ value: 180, color: '#A29BF2' , name:"Grocery", date: "2024-09-02" },
|
||||||
|
{ value: 120, color: '#F6CF7D', name:"Food Delivery", date: "2024-09-03"},
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<PozoPublicBarchart data={chartData} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HalfArcChart
|
||||||
|
values={[20, 60, 50, 25]}
|
||||||
|
radius={180}
|
||||||
|
strokeWidth={17}
|
||||||
|
colors={["green", "#EE89DF", "#F6CF7D", "#2196f3"]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorBarChart data={data}/>
|
||||||
|
{/* <ArcChart data={data} /> */}
|
||||||
|
<HorizontalBarChart data={data2} maxValue={maxValue} />
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
|
||||||
|
{/* <CircleStrokeChart strokeValue={100} strokeColor="green" radius={200} /> */}
|
||||||
|
|
||||||
|
<PozoPublicPieChart data={data6} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoGraphchart;
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import React from 'react';
|
||||||
|
import './PozoPublicBarchart.scss'; // Adjust path based on your folder structure
|
||||||
|
|
||||||
|
const PozoPublicBarchart = ({ data }) => {
|
||||||
|
const numberOfLines = 8; // Set how many vertical lines you want per bar
|
||||||
|
const maxValue = Math.max(...data.flatMap(bar => [bar.value1, bar.value2, bar.value3])); // Calculate the max value across all segments
|
||||||
|
const maxHeight = 200; // Define a maximum height for the bars (in pixels)
|
||||||
|
// const scaleFactor = maxHeight / maxValue; // Calculate scale factor to scale bar heights
|
||||||
|
const scaleFactor = maxHeight / maxValue;
|
||||||
|
console.log(scaleFactor, "scaleFactorscaleFactor")
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bar-chart-container">
|
||||||
|
{/* Benchmark Scale */}
|
||||||
|
<div className="benchmark-scale">
|
||||||
|
{Array.from({ length: 6 }, (_, idx) => {
|
||||||
|
|
||||||
|
console.log(idx, _, "idxidx")
|
||||||
|
console.log(maxValue - (maxValue / 5) * idx, "idxidx2222222")
|
||||||
|
|
||||||
|
const scaleValue = maxValue - (maxValue / 5) * idx; // Calculate the scale value
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={idx}
|
||||||
|
className="scale-value"
|
||||||
|
style={{ height: `${(maxHeight / 5) * idx}px` }} // Adjust height based on max value
|
||||||
|
>
|
||||||
|
{scaleValue}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bar-chart">
|
||||||
|
{data.map((bar, index) => {
|
||||||
|
return (
|
||||||
|
<div key={index} className="bar-container">
|
||||||
|
<div className="bar1">
|
||||||
|
{/* Render multiple vertical lines */}
|
||||||
|
{[...Array(numberOfLines)].map((_, lineIndex) => (
|
||||||
|
<div
|
||||||
|
key={lineIndex}
|
||||||
|
className="vr-line"
|
||||||
|
style={{
|
||||||
|
height: '100%', // Full height of the bar
|
||||||
|
left: `${(lineIndex * 100) / (numberOfLines - 1)}%`, // Distribute evenly
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="bar-segment segment1"
|
||||||
|
style={{ height: `${(bar.value1 * scaleFactor) - 10}px` }} // Scale value1
|
||||||
|
>
|
||||||
|
{/* <div className="tooltip">
|
||||||
|
<div>Value 1: {bar.value1}</div>
|
||||||
|
<div>Value 2: {bar.value2}</div>
|
||||||
|
<div>Value 3: {bar.value3}</div>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bar-segment segment2"
|
||||||
|
style={{ height: `${(bar.value2 * scaleFactor) - 10}px` }} // Scale value2
|
||||||
|
>
|
||||||
|
{/* <div className="tooltip">
|
||||||
|
<div>Value 1: {bar.value1}</div>
|
||||||
|
<div>Value 2: {bar.value2}</div>
|
||||||
|
<div>Value 3: {bar.value3}</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bar-segment segment3"
|
||||||
|
style={{ height: `${(bar.value3 * scaleFactor) - 10}px` }} // Scale value3
|
||||||
|
>
|
||||||
|
<div className="tooltip">
|
||||||
|
<div>Value 1: {bar.value1}</div>
|
||||||
|
<div>Value 2: {bar.value2}</div>
|
||||||
|
<div>Value 3: {bar.value3}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bar-label">{bar.month}</div> {/* Display month label */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicBarchart;
|
||||||
|
|
@ -0,0 +1,138 @@
|
||||||
|
.bar-chart-container {
|
||||||
|
display: flex;
|
||||||
|
height: inherit;
|
||||||
|
// overflow: scroll;
|
||||||
|
align-items: flex-end;
|
||||||
|
font-family: "Gilroy" !important;
|
||||||
|
/* Align bars to the bottom */
|
||||||
|
}
|
||||||
|
|
||||||
|
.benchmark-scale {
|
||||||
|
display: flex;
|
||||||
|
height: inherit;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-right: 10px;
|
||||||
|
/* Space between scale and bars */
|
||||||
|
}
|
||||||
|
|
||||||
|
.scale-value {
|
||||||
|
width: 30px;
|
||||||
|
/* Width of the scale */
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
/* Align text to bottom */
|
||||||
|
color: #555;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
/* Color of scale text */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the bar-chart styles */
|
||||||
|
.bar-chart {
|
||||||
|
height: 103%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: flex-end;
|
||||||
|
// height: max-content; /* Set a fixed height for the chart */
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
/* Reduce width for the scale */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container {
|
||||||
|
background-color: #EAEAEA;
|
||||||
|
text-align: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 25px;
|
||||||
|
position: relative;
|
||||||
|
/* Needed for tooltip positioning */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar1 {
|
||||||
|
width: 25px;
|
||||||
|
background-color: #EAEAEA;
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
/* Needed for tooltip */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vertical Line Overlay Styling */
|
||||||
|
.vr-line {
|
||||||
|
position: absolute;
|
||||||
|
width: 2px;
|
||||||
|
/* Width of each vertical line */
|
||||||
|
background-color: rgba(255, 255, 255, 0.377);
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
height: 100%;
|
||||||
|
/* Span the full height of the bar */
|
||||||
|
z-index: 1;
|
||||||
|
/* Ensure it appears on top of the segments */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling for each bar segment */
|
||||||
|
.bar-segment {
|
||||||
|
width: 100%;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
position: relative;
|
||||||
|
/* For tooltip positioning */
|
||||||
|
transition: background-color 0.3s, transform 0.3s;
|
||||||
|
/* For hover effect */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Colors for each segment */
|
||||||
|
.segment1 {
|
||||||
|
background-color: #F6CF7D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segment2 {
|
||||||
|
background-color: #EE89DF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segment3 {
|
||||||
|
background-color: #978FED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tooltip Styling */
|
||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 100%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
padding: 5px 8px;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 260 !important;
|
||||||
|
text-align: left;
|
||||||
|
height: max-content;
|
||||||
|
/* Make sure tooltip appears above everything */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover Effect: Show tooltip */
|
||||||
|
.bar-container:hover .tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
/* Slightly move the segment on hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-label {
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
/* Space between label and bar */
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
import React from 'react';
|
||||||
|
import "./PozoPublicBarchart2.scss"; // Adjust path based on your folder structure
|
||||||
|
|
||||||
|
const PozoPublicBarchart = ({ data }) => {
|
||||||
|
const numberOfLines = 8; // Set how many vertical lines you want per bar
|
||||||
|
const maxValue = Math.max(...data.flatMap(bar => [bar.value1, bar.value2, bar.value3]));
|
||||||
|
|
||||||
|
const maxHeight = 200; // Define a maximum height for the bars (in pixels)
|
||||||
|
const scaleFactor = maxHeight / maxValue; // Calculate scale factor to scale bar heights
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bar-chart-container">
|
||||||
|
{/* Benchmark Scale */}
|
||||||
|
<div className="benchmark-scale">
|
||||||
|
{Array.from({ length: 6 }, (_, idx) => {
|
||||||
|
const scaleValue = Math.round((maxValue / 5) * (5 - idx)); // Ensure the benchmark aligns with the max value
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={idx}
|
||||||
|
className="scale-value"
|
||||||
|
style={{ height: `${(maxHeight / 5)}px` }} // Adjust height evenly for scale
|
||||||
|
>
|
||||||
|
{scaleValue}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bar-chart">
|
||||||
|
{data.map((bar, index) => {
|
||||||
|
|
||||||
|
const value1Height = bar.value1 * scaleFactor;
|
||||||
|
const value2Height = bar.value2 * scaleFactor;
|
||||||
|
const value3Height = bar.value3 * scaleFactor;
|
||||||
|
|
||||||
|
console.log(value1Height, 'value1Height111111')
|
||||||
|
console.log(value2Height, 'value1Height222222')
|
||||||
|
console.log(value3Height, 'value1Height3333333')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={index} className="bar-container">
|
||||||
|
<div className="bar">
|
||||||
|
{/* Render multiple vertical lines */}
|
||||||
|
{[...Array(numberOfLines)].map((_, lineIndex) => (
|
||||||
|
<div
|
||||||
|
key={lineIndex}
|
||||||
|
className="vr-line"
|
||||||
|
style={{
|
||||||
|
height: '100%', // Full height of the bar
|
||||||
|
left: `${(lineIndex * 100) / (numberOfLines - 1)}%`, // Distribute evenly
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Independent Bar segments starting from 0 */}
|
||||||
|
<div
|
||||||
|
className="bar-segment segment1"
|
||||||
|
style={{
|
||||||
|
height: `${value1Height}px`,
|
||||||
|
width: '33.3%', // Use a percentage width to show value1, value2, and value3 side-by-side
|
||||||
|
left: '0', // Left-aligned for the first value
|
||||||
|
bottom: 0, // Start from the bottom (zero benchmark)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<hr className='hrLineforHighestValue' />
|
||||||
|
|
||||||
|
{/* <div className="tooltip">
|
||||||
|
<div>Value 1: {bar.value1}</div>
|
||||||
|
<div>Value 2: {bar.value2}</div>
|
||||||
|
<div>Value 3: {bar.value3}</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bar-segment segment2"
|
||||||
|
style={{
|
||||||
|
height: `${value2Height}px`,
|
||||||
|
width: '33.3%', // Use the same width for each value
|
||||||
|
left: '35%',
|
||||||
|
position: 'absolute', // Center-align for the second value
|
||||||
|
bottom: 0, // Start from the bottom (zero benchmark)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* <div className="tooltip">
|
||||||
|
<div>Value 1: {bar.value1}</div>
|
||||||
|
<div>Value 2: {bar.value2}</div>
|
||||||
|
<div>Value 3: {bar.value3}</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bar-segment segment3"
|
||||||
|
style={{
|
||||||
|
height: `${value3Height}px`,
|
||||||
|
width: '33.3%', // Same width for the third value
|
||||||
|
left: '70%',
|
||||||
|
position: 'absolute', // Right-aligned for the third value
|
||||||
|
bottom: 0, // Start from the bottom (zero benchmark)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="tooltip">
|
||||||
|
<div>Value 1: {bar.value1}</div>
|
||||||
|
<div>Value 2: {bar.value2}</div>
|
||||||
|
<div>Value 3: {bar.value3}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bar-label">{bar.month}</div> {/* Display month label */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicBarchart;
|
||||||
|
|
@ -0,0 +1,295 @@
|
||||||
|
.bar-chart-container {
|
||||||
|
display: flex;
|
||||||
|
height: inherit;
|
||||||
|
// overflow: scroll;
|
||||||
|
align-items: flex-end;
|
||||||
|
/* Align bars to the bottom */
|
||||||
|
font-family: "Gilroy" !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benchmark-scale {
|
||||||
|
display: flex;
|
||||||
|
height: inherit;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-right: 10px;
|
||||||
|
/* Space between scale and bars */
|
||||||
|
}
|
||||||
|
|
||||||
|
.scale-value {
|
||||||
|
width: 30px;
|
||||||
|
/* Width of the scale */
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
/* Align text to bottom */
|
||||||
|
color: #555;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
/* Color of scale text */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the bar-chart styles */
|
||||||
|
.bar-chart {
|
||||||
|
height: 103%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: flex-end;
|
||||||
|
// height: max-content; /* Set a fixed height for the chart */
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
/* Reduce width for the scale */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container {
|
||||||
|
background-color: #EAEAEA;
|
||||||
|
text-align: center;
|
||||||
|
height: inherit;
|
||||||
|
width: 25px;
|
||||||
|
position: relative;
|
||||||
|
/* Needed for tooltip positioning */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
width: 25px;
|
||||||
|
background-color: #EAEAEA;
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
/* Needed for tooltip */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vertical Line Overlay Styling */
|
||||||
|
.vr-line {
|
||||||
|
position: absolute;
|
||||||
|
width: 2px;
|
||||||
|
/* Width of each vertical line */
|
||||||
|
background-color: rgba(255, 255, 255, 0.377);
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
height: 100%;
|
||||||
|
/* Span the full height of the bar */
|
||||||
|
z-index: 1;
|
||||||
|
/* Ensure it appears on top of the segments */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling for each bar segment */
|
||||||
|
.bar-segment {
|
||||||
|
width: 100%;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
position: relative;
|
||||||
|
/* For tooltip positioning */
|
||||||
|
transition: background-color 0.3s, transform 0.3s;
|
||||||
|
/* For hover effect */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Colors for each segment */
|
||||||
|
.segment1 {
|
||||||
|
background-color: #F6CF7D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segment2 {
|
||||||
|
background-color: #EE89DF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segment3 {
|
||||||
|
background-color: #978FED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tooltip Styling */
|
||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 100%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
padding: 5px 8px;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 260 !important;
|
||||||
|
text-align: left;
|
||||||
|
height: max-content;
|
||||||
|
/* Make sure tooltip appears above everything */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover Effect: Show tooltip */
|
||||||
|
.bar-container:hover .tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
/* Slightly move the segment on hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-label {
|
||||||
|
margin-top: 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
/* Space between label and bar */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container {
|
||||||
|
height: 100%;
|
||||||
|
animation: shutter-in-bottom 2.5s ease 0s 1 alternate forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shutter-in-bottom {
|
||||||
|
|
||||||
|
0% {
|
||||||
|
transform: rotateX(100deg);
|
||||||
|
transform-origin: bottom;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateX(0);
|
||||||
|
transform-origin: bottom;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// .bar-chart-container {
|
||||||
|
// display: flex;
|
||||||
|
// height: 100vh;
|
||||||
|
// overflow: scroll;
|
||||||
|
// align-items: flex-end;
|
||||||
|
// /* Align bars to the bottom */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .benchmark-scale {
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
// justify-content: space-between;
|
||||||
|
// padding-right: 10px;
|
||||||
|
// /* Space between scale and bars */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .scale-value {
|
||||||
|
// width: 30px;
|
||||||
|
// /* Width of the scale */
|
||||||
|
// position: relative;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: flex-end;
|
||||||
|
// /* Align text to bottom */
|
||||||
|
// color: #555;
|
||||||
|
// /* Color of scale text */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Adjust the bar-chart styles */
|
||||||
|
// .bar-chart {
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: space-around;
|
||||||
|
// align-items: flex-end;
|
||||||
|
// height: max-content;
|
||||||
|
// /* Set a fixed height for the chart */
|
||||||
|
// width: calc(100% - 50px);
|
||||||
|
// /* Reduce width for the scale */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .bar-container {
|
||||||
|
// background-color: #EAEAEA;
|
||||||
|
// text-align: center;
|
||||||
|
// position: relative;
|
||||||
|
// /* Needed for tooltip positioning */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .bar {
|
||||||
|
// width: 25px;
|
||||||
|
// background-color: #EAEAEA;
|
||||||
|
// display: flex;
|
||||||
|
// height: 100%;
|
||||||
|
// border-top-left-radius: 8px;
|
||||||
|
// border-top-right-radius: 8px;
|
||||||
|
// flex-direction: column-reverse;
|
||||||
|
// position: relative;
|
||||||
|
// top: 0px;
|
||||||
|
// /* Needed for tooltip */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Vertical Line Overlay Styling */
|
||||||
|
// .vr-line {
|
||||||
|
// position: absolute;
|
||||||
|
// width: 2px;
|
||||||
|
// /* Width of each vertical line */
|
||||||
|
// background-color: rgba(255, 255, 255, 0.377);
|
||||||
|
// border-top-left-radius: 8px;
|
||||||
|
// border-top-right-radius: 8px;
|
||||||
|
// height: 100%;
|
||||||
|
// /* Span the full height of the bar */
|
||||||
|
// z-index: 1;
|
||||||
|
// /* Ensure it appears on top of the segments */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Styling for each bar segment */
|
||||||
|
// .bar-segment {
|
||||||
|
// width: 100%;
|
||||||
|
// border-top-left-radius: 8px;
|
||||||
|
// border-top-right-radius: 8px;
|
||||||
|
// position: relative;
|
||||||
|
// /* For tooltip positioning */
|
||||||
|
// transition: background-color 0.3s, transform 0.3s;
|
||||||
|
// /* For hover effect */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Colors for each segment */
|
||||||
|
// .segment1 {
|
||||||
|
// background-color: #F6CF7D;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .segment2 {
|
||||||
|
// background-color: #EE89DF;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .segment3 {
|
||||||
|
// background-color: #978FED;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Tooltip Styling */
|
||||||
|
// .tooltip {
|
||||||
|
// position: absolute;
|
||||||
|
// left: 50%;
|
||||||
|
// bottom: 100%;
|
||||||
|
// transform: translateX(-50%);
|
||||||
|
// padding: 5px;
|
||||||
|
// background-color: black;
|
||||||
|
// color: white;
|
||||||
|
// font-size: 12px;
|
||||||
|
// border-radius: 4px;
|
||||||
|
// opacity: 0;
|
||||||
|
// pointer-events: none;
|
||||||
|
// transition: opacity 0.3s;
|
||||||
|
// white-space: nowrap;
|
||||||
|
// z-index: 26;
|
||||||
|
// /* Make sure tooltip appears above everything */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Hover Effect: Show tooltip */
|
||||||
|
// .bar-segment:hover .tooltip {
|
||||||
|
// opacity: 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .bar-segment:hover {
|
||||||
|
// transform: translateY(-5px);
|
||||||
|
// /* Slightly move the segment on hover */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .bar-label {
|
||||||
|
// margin-top: 40px;
|
||||||
|
// /* Space between label and bar */
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .hrLineforHighestValue {
|
||||||
|
// position: absolute;
|
||||||
|
// right: 0;
|
||||||
|
// width: 95vw;
|
||||||
|
// }
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import "./PozoPublicPiechart.scss"
|
||||||
|
|
||||||
|
// Helper function to calculate the arcs for the donut chart
|
||||||
|
const calculateArcs = (data) => {
|
||||||
|
const total = data.reduce((acc, item) => acc + item.value, 0);
|
||||||
|
let cumulativePercentage = 0;
|
||||||
|
|
||||||
|
return data.map((item) => {
|
||||||
|
const percentage = (item.value / total) * 100;
|
||||||
|
const startAngle = cumulativePercentage;
|
||||||
|
const endAngle = cumulativePercentage + percentage;
|
||||||
|
cumulativePercentage = endAngle;
|
||||||
|
|
||||||
|
const largeArcFlag = percentage > 50 ? 1 : 0;
|
||||||
|
|
||||||
|
const outerRadius = 1; // Outer radius for the arc
|
||||||
|
const innerRadius = 0.7; // Inner radius for the hollow part
|
||||||
|
|
||||||
|
// Calculate the outer arc points
|
||||||
|
const startXOuter = outerRadius * Math.cos((2 * Math.PI * startAngle) / 100);
|
||||||
|
const startYOuter = outerRadius * Math.sin((2 * Math.PI * startAngle) / 100);
|
||||||
|
const endXOuter = outerRadius * Math.cos((2 * Math.PI * endAngle) / 100);
|
||||||
|
const endYOuter = outerRadius * Math.sin((2 * Math.PI * endAngle) / 100);
|
||||||
|
|
||||||
|
// Calculate the inner arc points
|
||||||
|
const startXInner = innerRadius * Math.cos((2 * Math.PI * startAngle) / 100);
|
||||||
|
const startYInner = innerRadius * Math.sin((2 * Math.PI * startAngle) / 100);
|
||||||
|
const endXInner = innerRadius * Math.cos((2 * Math.PI * endAngle) / 100);
|
||||||
|
const endYInner = innerRadius * Math.sin((2 * Math.PI * endAngle) / 100);
|
||||||
|
|
||||||
|
// Create the path for the arc (outer and inner)
|
||||||
|
const pathData = [
|
||||||
|
`M ${startXOuter} ${startYOuter}`, // Move to start of outer arc
|
||||||
|
`A ${outerRadius} ${outerRadius} 0 ${largeArcFlag} 1 ${endXOuter} ${endYOuter}`, // Outer arc
|
||||||
|
`L ${endXInner} ${endYInner}`, // Line to inner arc
|
||||||
|
`A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${startXInner} ${startYInner}`, // Inner arc
|
||||||
|
`Z`, // Close the path
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
return {
|
||||||
|
pathData,
|
||||||
|
color: item.color,
|
||||||
|
value: item.value,
|
||||||
|
percentage: percentage.toFixed(2),
|
||||||
|
name: item.name,
|
||||||
|
date: item.date, // Add date to return object
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const PieChart = ({ data }) => {
|
||||||
|
const [tooltip, setTooltip] = useState({ x: 0, y: 0, content: '', visible: false });
|
||||||
|
const [filter, setFilter] = useState(""); // State to hold the filter criteria
|
||||||
|
const [dateFilter, setDateFilter] = useState(""); // State to hold the date filter
|
||||||
|
const [animatedValues, setAnimatedValues] = useState(data.map(item => ({ ...item, animatedValue: 0 }))); // State for animated values
|
||||||
|
|
||||||
|
// Function to filter data
|
||||||
|
const filteredData = animatedValues.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(filter.toLowerCase()) &&
|
||||||
|
(!dateFilter || item.date.includes(dateFilter)) // Filter by date
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleMouseOver = (event, arc) => {
|
||||||
|
setTooltip({
|
||||||
|
x: event.clientX + 10,
|
||||||
|
y: event.clientY - 20,
|
||||||
|
content: `${arc.name}: ₹${arc.value} (${arc.percentage}%) on ${arc.date}`,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseOut = () => {
|
||||||
|
setTooltip((prev) => ({ ...prev, visible: false }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const arcs = calculateArcs(filteredData);
|
||||||
|
console.log(arcs, "yusgd");
|
||||||
|
// Animate values from 0 to actual value
|
||||||
|
useEffect(() => {
|
||||||
|
const animationDuration = 2000; // Animation duration in ms
|
||||||
|
const interval = 50; // Interval for the animation
|
||||||
|
const step = Math.floor(animationDuration / interval);
|
||||||
|
|
||||||
|
console.log("Animated Values:", animatedValues);
|
||||||
|
|
||||||
|
const newValues = animatedValues.map(item => ({
|
||||||
|
...item,
|
||||||
|
animatedValue: 0, // Start from 0
|
||||||
|
}));
|
||||||
|
|
||||||
|
let animationFrame = 0;
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
if (animationFrame < step) {
|
||||||
|
setAnimatedValues(newValues.map(item => ({
|
||||||
|
...item,
|
||||||
|
animatedValue: Math.round((item.value / step) * (animationFrame + 0)), // Increment the value
|
||||||
|
})));
|
||||||
|
animationFrame++;
|
||||||
|
} else {
|
||||||
|
clearInterval(intervalId); // Stop the animation when complete
|
||||||
|
setAnimatedValues(newValues.map(item => ({ ...item, animatedValue: item.value }))); // Set to final value
|
||||||
|
}
|
||||||
|
}, interval);
|
||||||
|
|
||||||
|
return () => clearInterval(intervalId); // Cleanup interval on unmount
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: "relative",display: 'flex', alignItems: 'center', justifyContent: "space-around" , gap:"1rem"}}>
|
||||||
|
<div className="piechartsize">
|
||||||
|
{/* <input
|
||||||
|
type="text"
|
||||||
|
placeholder="Filter by name..."
|
||||||
|
value={filter}
|
||||||
|
onChange={(e) => setFilter(e.target.value)}
|
||||||
|
style={{ marginBottom: '1rem', padding: '8px', borderRadius: '4px', border: '1px solid #ccc' }}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Filter by date (YYYY-MM-DD)..."
|
||||||
|
value={dateFilter}
|
||||||
|
onChange={(e) => setDateFilter(e.target.value)}
|
||||||
|
style={{ marginBottom: '1rem', padding: '8px', borderRadius: '4px', border: '1px solid #ccc' }}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
<svg
|
||||||
|
viewBox="-1 -1 2 2"
|
||||||
|
className="loading-circle" // Add loading animation class here
|
||||||
|
style={{ transform: "rotate(-90deg)", width: "100%", height: "100%" }}
|
||||||
|
>
|
||||||
|
{arcs.map((arc, index) => (
|
||||||
|
<path
|
||||||
|
key={index}
|
||||||
|
d={arc.pathData}
|
||||||
|
fill={arc.color}
|
||||||
|
onMouseOver={(e) => handleMouseOver(e, arc)}
|
||||||
|
onMouseOut={handleMouseOut}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
|
||||||
|
{arcs.map((arc, index) => (
|
||||||
|
<p key={index} style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: "center",
|
||||||
|
gap: '0.5rem',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
fontWeight: '600',
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
fontSize: '10.5px',
|
||||||
|
textWrap:"nowrap"
|
||||||
|
}}>
|
||||||
|
<div style={{ width: "6px", height: '6px', borderRadius: '60px', backgroundColor: arc.color, }}> </div>
|
||||||
|
{arc.name}
|
||||||
|
<p style={{width:'25px', color: '#007E1C',fontSize: '10.5px', }}> ₹{animatedValues[index]?.animatedValue}</p>
|
||||||
|
<p style={{ color: 'green',fontSize: '10.5px', }}> ({arc.percentage}%) </p>
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{tooltip.visible && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
backgroundColor: "#23282D",
|
||||||
|
color: "#ecf0f1",
|
||||||
|
padding: "10px 15px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
pointerEvents: "none",
|
||||||
|
zIndex: 10,
|
||||||
|
transform: "translate(-50%, -100%)",
|
||||||
|
fontSize: "14px",
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "100%",
|
||||||
|
left: "50%",
|
||||||
|
marginLeft: "-5px",
|
||||||
|
borderWidth: "5px",
|
||||||
|
borderStyle: "solid",
|
||||||
|
}} />
|
||||||
|
{tooltip.content}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PieChart;
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
.piechartsize {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
import React from 'react';
|
||||||
|
import './PozoPublicBarchart.scss'; // Adjust path based on your folder structure
|
||||||
|
|
||||||
|
const PozoPublicBarchart = ({ data }) => {
|
||||||
|
const numberOfLines = 8; // Set how many vertical lines you want per bar
|
||||||
|
const maxValue = Math.max(...data.flatMap(bar => [bar.value1, bar.value2, bar.value3])); // Calculate the max value across all segments
|
||||||
|
const desiredMaxHeight = 100; // Define the desired maximum height for the bars (in pixels)
|
||||||
|
const scaleFactor = desiredMaxHeight / maxValue; // Calculate scale factor to scale bar heights
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bar-chart-container">
|
||||||
|
{/* Benchmark Scale */}
|
||||||
|
<div className="benchmark-scale">
|
||||||
|
{Array.from({ length: 6 }, (_, idx) => {
|
||||||
|
const scaleValue = Math.round(maxValue - (maxValue / 5) * idx); // Calculate the scale value
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={idx}
|
||||||
|
className="scale-value"
|
||||||
|
style={{ height: `${(desiredMaxHeight / 5) * idx}px` }} // Adjust height based on max value
|
||||||
|
>
|
||||||
|
{scaleValue}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bar-chart">
|
||||||
|
{data.map((bar, index) => {
|
||||||
|
return (
|
||||||
|
<div key={index} className="bar-container">
|
||||||
|
<div className="bar">
|
||||||
|
{/* Render multiple vertical lines */}
|
||||||
|
{[...Array(numberOfLines)].map((_, lineIndex) => (
|
||||||
|
<div
|
||||||
|
key={lineIndex}
|
||||||
|
className="vr-line"
|
||||||
|
style={{
|
||||||
|
height: '100%', // Full height of the bar
|
||||||
|
left: `${(lineIndex * 100) / (numberOfLines - 1)}%`, // Distribute evenly
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="bar-segment segment1"
|
||||||
|
style={{ height: `${bar.value1 * scaleFactor}px` }} // Scale value1
|
||||||
|
>
|
||||||
|
<div className="tooltip">Value 1: {bar.value1}</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bar-segment segment2"
|
||||||
|
style={{ height: `${bar.value2 * scaleFactor}px` }} // Scale value2
|
||||||
|
>
|
||||||
|
<div className="tooltip">Value 2: {bar.value2}</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bar-segment segment3"
|
||||||
|
style={{ height: `${bar.value3 * scaleFactor}px` }} // Scale value3
|
||||||
|
>
|
||||||
|
<div className="tooltip">Value 3: {bar.value3}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bar-label">{bar.month}</div> {/* Display month label */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicBarchart;
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
import { IoIosArrowDropup, IoIosArrowDropdown } from "react-icons/io";
|
||||||
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import "../Collapse/PozoPublicCollapse.scss";
|
||||||
|
import { PiPencilSimpleLight } from "react-icons/pi";
|
||||||
|
|
||||||
|
const PozoPublicCollapse = ({
|
||||||
|
title = "Item description",
|
||||||
|
children,
|
||||||
|
children2,
|
||||||
|
isOpenInitially = false,
|
||||||
|
width = "100%",
|
||||||
|
className = "",
|
||||||
|
title2 = "",
|
||||||
|
isEdit,
|
||||||
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(isOpenInitially); // Use false by default
|
||||||
|
const contentRef = useRef(null);
|
||||||
|
const collapseRef = useRef(null);
|
||||||
|
const [contentHeight, setContentHeight] = useState("0px");
|
||||||
|
|
||||||
|
const toggleCollapse = () => {
|
||||||
|
// Explicitly set the state based on current value
|
||||||
|
if (!isOpen) {
|
||||||
|
setIsOpen(true); // Open the collapse
|
||||||
|
} else {
|
||||||
|
setIsOpen(false); // Close the collapse
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setContentHeight(isOpen ? `${contentRef.current.scrollHeight}px` : "0px");
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (collapseRef.current && !collapseRef.current.contains(event.target)) {
|
||||||
|
setIsOpen(false); // Close the collapse if clicked outside
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uncomment this block if you want to close the collapse when clicking outside of it
|
||||||
|
// useEffect(() => {
|
||||||
|
// document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
// return () => {
|
||||||
|
// document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
// };
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={collapseRef}
|
||||||
|
className={`PozoPublicCollapse-Master ${className}`}
|
||||||
|
style={{ width }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`PozoPublicCollapseMain ${isOpen ? 'open' : ''}`}
|
||||||
|
>
|
||||||
|
<div className="PozoPublicCollapse-Header" onClick={toggleCollapse}>
|
||||||
|
<div>{title}
|
||||||
|
<span className="title2Collapse">{title2}
|
||||||
|
{isEdit && <span> <PiPencilSimpleLight opacity={0.8} size={16} /></span>}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{isOpen ? <IoIosArrowDropup size={18} /> : <IoIosArrowDropdown size={18} />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isOpen && (
|
||||||
|
<div
|
||||||
|
ref={contentRef}
|
||||||
|
className="PozoPublicCollapse-Content"
|
||||||
|
style={{ height: "max-content" }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="collapseChildren" style={{ padding: "1rem 10px" }}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
<div className="collapseChildren2" style={{ padding: "1rem 10px" }}>
|
||||||
|
{children2}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicCollapse;
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
.PozoPublicCollapse-Master {
|
||||||
|
width: 100%;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
height: 100%;
|
||||||
|
max-height: auto;
|
||||||
|
|
||||||
|
.PozoPublicCollapseMain {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid var(--input-BorderColor); // Default border color
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: border-color 0.3s ease; // Smooth transition for border color
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
border-color: #0071E3; // Border color when open
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #0071E3; // Border color on hover
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
border-color: #0071E3; // Border color on focus
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicCollapse-Header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
text-transform: capitalize;
|
||||||
|
color: #0909099d;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-weight: 550;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicCollapse-Content {
|
||||||
|
// overflow: hidden;
|
||||||
|
transition: height 0.3s ease, opacity 0.3s ease;
|
||||||
|
padding: 0px 10px;
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 6px;
|
||||||
|
width: 100%;
|
||||||
|
height: max-content;
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
|
||||||
|
p div {
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title2Collapse {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #7D7D7D;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin-bottom: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { RiDeleteBin6Line } from "react-icons/ri";
|
||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import "../CollapseAuto/PozoPublicCollapseAuto.scss";
|
||||||
|
import { PiCaretCircleDownLight, PiCaretCircleUpLight, PiPencilSimpleLight } from "react-icons/pi";
|
||||||
|
|
||||||
|
const PozoPublicCollapseAuto = ({
|
||||||
|
title = "Item description",
|
||||||
|
children,
|
||||||
|
isOpenInitially = false,
|
||||||
|
width = "100%",
|
||||||
|
className = "",
|
||||||
|
isEdit = false,
|
||||||
|
isDelete = false,
|
||||||
|
isToogle = false,
|
||||||
|
isChecked,
|
||||||
|
title2 = "",
|
||||||
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(isOpenInitially);
|
||||||
|
const contentRef = useRef(null);
|
||||||
|
const collapseRef = useRef(null);
|
||||||
|
const [checked, setChecked] = useState(isChecked);
|
||||||
|
|
||||||
|
const toggleCollapsePozo = () => {
|
||||||
|
setIsOpen(prev => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (collapseRef.current && !collapseRef.current.contains(event.target)) {
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleChange = () => {
|
||||||
|
setChecked(prev => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='PozoPublicCollapseAuto-Master'>
|
||||||
|
<div
|
||||||
|
ref={collapseRef}
|
||||||
|
className={`PozoPublicCollapseAuto-Master ${className}`}
|
||||||
|
style={{ width }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`PozoPublicCollapseMain ${isOpen ? 'open' : ''}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="PozoPublicCollapseAuto-Header"
|
||||||
|
onClick={toggleCollapsePozo}
|
||||||
|
>
|
||||||
|
<div>{title} <span>{title2}</span></div>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", columnGap: "3rem" }}>
|
||||||
|
<div className="svgs" onClick={(event) => event.stopPropagation()}>
|
||||||
|
{isEdit && <PiPencilSimpleLight opacity={0.6} strokeWidth={2} />}
|
||||||
|
{isDelete && (
|
||||||
|
<RiDeleteBin6Line opacity={0.5} strokeWidth={0.1} />
|
||||||
|
)}
|
||||||
|
{isToogle &&
|
||||||
|
<div className="switch-container">
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="switch"
|
||||||
|
checked={checked}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
<div className="slider">
|
||||||
|
<div className="handle"></div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
{isOpen ? <PiCaretCircleUpLight size={24} color="#1C1C1CCC" strokeWidth={2} /> :
|
||||||
|
<PiCaretCircleDownLight size={24} color="#1C1C1CCC" strokeWidth={2} />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
ref={contentRef}
|
||||||
|
className="PozoPublicCollapseAuto-Content"
|
||||||
|
style={{
|
||||||
|
maxHeight: isOpen ? `${contentRef.current.scrollHeight}0px` : '0px',
|
||||||
|
opacity: isOpen ? 1 : 0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="childrenmaincollapseAuto" style={{ padding: "1rem 0.5rem" }}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicCollapseAuto;
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
.PozoPublicCollapseAuto-Master {
|
||||||
|
width: 100%;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
max-height: max-content;
|
||||||
|
|
||||||
|
.PozoPublicCollapseMain {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid var(--input-BorderColor);
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
border-color: #0071E3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #0071E3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
border-color: #0071E3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicCollapseAuto-Header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: var(--lightBlue-color);
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
text-transform: capitalize;
|
||||||
|
color: #090909;
|
||||||
|
font-size: 18px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svgs {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 20px;
|
||||||
|
column-gap: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 15;
|
||||||
|
right: 7rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicCollapseAuto-Content {
|
||||||
|
overflow: hidden;
|
||||||
|
transition: max-height 0.3s ease, opacity 0.3s ease;
|
||||||
|
padding: 0px 10px;
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 6px;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 1;
|
||||||
|
height: max-content !important;
|
||||||
|
max-height: 0;
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
|
||||||
|
p div {
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 70px;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"].switch {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
width: 32px;
|
||||||
|
height: 16.5px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: #d7d7d7;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.4s, box-shadow 0.4s;
|
||||||
|
padding: 1px;
|
||||||
|
|
||||||
|
.handle {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: inherit;
|
||||||
|
background: #ffffff;
|
||||||
|
transition: transform 0.4s cubic-bezier(1, 0, 0, 1);
|
||||||
|
margin: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"].switch:checked+.slider {
|
||||||
|
background-color: #0FA958;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"].switch:checked+.slider .handle {
|
||||||
|
transform: translateX(15px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import './customModal.css'; // Import your CSS file
|
||||||
|
|
||||||
|
const CustomModal = () => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [animationClass, setAnimationClass] = useState('');
|
||||||
|
|
||||||
|
const openModal = (animation) => {
|
||||||
|
setAnimationClass(animation);
|
||||||
|
setIsOpen(true);
|
||||||
|
document.body.classList.add('modal-active');
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setAnimationClass(animationClass + ' out');
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsOpen(false);
|
||||||
|
document.body.classList.remove('modal-active');
|
||||||
|
setAnimationClass(''); // Reset animation class after close
|
||||||
|
}, 500); // Duration should match the animation duration
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="content">
|
||||||
|
<h1>Modal Animations</h1>
|
||||||
|
<div className="buttons">
|
||||||
|
{['one', 'two', 'three', 'four', 'five', 'six', 'seven'].map((id) => (
|
||||||
|
<div key={id} className="button" onClick={() => openModal(id)}>
|
||||||
|
{id.charAt(0).toUpperCase() + id.slice(1)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isOpen && (
|
||||||
|
<div id="modal-container" className={animationClass}>
|
||||||
|
<div className="modal-background" onClick={closeModal}>
|
||||||
|
<div className="modal">
|
||||||
|
<h2>I'm a Modal</h2>
|
||||||
|
<p>Hear me roar.</p>
|
||||||
|
<svg className="modal-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none">
|
||||||
|
<rect x="0" y="0" fill="none" width="226" height="162" rx="3" ry="3"></rect>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CustomModal;
|
||||||
|
|
@ -0,0 +1,616 @@
|
||||||
|
/* * {
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,body {
|
||||||
|
min-height:100%;
|
||||||
|
height:100%;
|
||||||
|
background-image:url(http://theartmad.com/wp-content/uploads/Dark-Grey-Texture-Wallpaper-5.jpg);
|
||||||
|
background-size:cover;
|
||||||
|
background-position:top center;
|
||||||
|
font-family:helvetica neue, helvetica, arial, sans-serif;
|
||||||
|
font-weight:200;
|
||||||
|
&.modal-active {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-container {
|
||||||
|
position:fixed;
|
||||||
|
display:table;
|
||||||
|
height:10%;
|
||||||
|
width:100%;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
transform:scale(0);
|
||||||
|
z-index:1;
|
||||||
|
&.one {
|
||||||
|
transform:scaleY(.01) scaleX(0);
|
||||||
|
animation:unfoldIn 1s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal-background {
|
||||||
|
.modal {
|
||||||
|
transform:scale(0);
|
||||||
|
animation: zoomIn .5s .8s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
transform:scale(1);
|
||||||
|
animation:unfoldOut 1s .3s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal-background {
|
||||||
|
.modal {
|
||||||
|
animation: zoomOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.two {
|
||||||
|
transform:scale(1);
|
||||||
|
.modal-background {
|
||||||
|
background:rgba(0,0,0,.0);
|
||||||
|
animation: fadeIn .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
opacity:0;
|
||||||
|
animation: scaleUp .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ .content {
|
||||||
|
animation: scaleBack .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
animation: quickScaleDown 0s .5s linear forwards;
|
||||||
|
.modal-background {
|
||||||
|
animation: fadeOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
animation: scaleDown .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ .content {
|
||||||
|
animation: scaleForward .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.three {
|
||||||
|
z-index:0;
|
||||||
|
transform:scale(1);
|
||||||
|
.modal-background {
|
||||||
|
background:rgba(0,0,0,.6);
|
||||||
|
.modal {
|
||||||
|
animation: moveUp .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ .content {
|
||||||
|
z-index:1;
|
||||||
|
animation: slideUpLarge .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
.modal-background {
|
||||||
|
.modal {
|
||||||
|
animation: moveDown .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ .content {
|
||||||
|
animation: slideDownLarge .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.four {
|
||||||
|
z-index:0;
|
||||||
|
transform:scale(1);
|
||||||
|
.modal-background {
|
||||||
|
background:rgba(0,0,0,.7);
|
||||||
|
.modal {
|
||||||
|
animation: blowUpModal .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ .content {
|
||||||
|
z-index:1;
|
||||||
|
animation:blowUpContent .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
.modal-background {
|
||||||
|
.modal {
|
||||||
|
animation: blowUpModalTwo .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ .content {
|
||||||
|
animation: blowUpContentTwo .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.five {
|
||||||
|
transform:scale(1);
|
||||||
|
.modal-background {
|
||||||
|
background:rgba(0,0,0,.0);
|
||||||
|
animation: fadeIn .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
transform:translateX(-1500px);
|
||||||
|
animation: roadRunnerIn .3s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
animation: quickScaleDown 0s .5s linear forwards;
|
||||||
|
.modal-background {
|
||||||
|
animation: fadeOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
animation: roadRunnerOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.six {
|
||||||
|
transform:scale(1);
|
||||||
|
.modal-background {
|
||||||
|
background:rgba(0,0,0,.0);
|
||||||
|
animation: fadeIn .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
background-color:transparent;
|
||||||
|
animation: modalFadeIn .5s .8s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
h2,p {
|
||||||
|
opacity:0;
|
||||||
|
position:relative;
|
||||||
|
animation: modalContentFadeIn .5s 1s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
.modal-svg {
|
||||||
|
rect {
|
||||||
|
animation: sketchIn .5s .3s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
animation: quickScaleDown 0s .5s linear forwards;
|
||||||
|
.modal-background {
|
||||||
|
animation: fadeOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
animation: modalFadeOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
h2,p {
|
||||||
|
animation: modalContentFadeOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
.modal-svg {
|
||||||
|
rect {
|
||||||
|
animation: sketchOut .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.seven {
|
||||||
|
transform:scale(1);
|
||||||
|
.modal-background {
|
||||||
|
background:rgba(0,0,0,.0);
|
||||||
|
animation: fadeIn .5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
height:75px;
|
||||||
|
width:75px;
|
||||||
|
border-radius:75px;
|
||||||
|
overflow:hidden;
|
||||||
|
animation: bondJamesBond 1.5s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
h2,p {
|
||||||
|
opacity:0;
|
||||||
|
position:relative;
|
||||||
|
animation: modalContentFadeIn .5s 1.4s linear forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.out {
|
||||||
|
animation: slowFade .5s 1.5s linear forwards;
|
||||||
|
.modal-background {
|
||||||
|
background-color:rgba(0,0,0,.7);
|
||||||
|
animation: fadeToRed 2s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
.modal {
|
||||||
|
border-radius:3px;
|
||||||
|
height:162px;
|
||||||
|
width:227px;
|
||||||
|
animation: killShot 1s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
h2,p {
|
||||||
|
animation:modalContentFadeOut .5s .5 cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-background {
|
||||||
|
display:table-cell;
|
||||||
|
background:rgba(0,0,0,.8);
|
||||||
|
text-align:center;
|
||||||
|
vertical-align:middle;
|
||||||
|
.modal {
|
||||||
|
background:white;
|
||||||
|
padding:50px;
|
||||||
|
display:inline-block;
|
||||||
|
border-radius:3px;
|
||||||
|
font-weight:300;
|
||||||
|
position:relative;
|
||||||
|
h2 {
|
||||||
|
font-size:25px;
|
||||||
|
line-height:25px;
|
||||||
|
margin-bottom:15px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size:18px;
|
||||||
|
line-height:22px;
|
||||||
|
}
|
||||||
|
.modal-svg {
|
||||||
|
position:absolute;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
height:100%;
|
||||||
|
width:100%;
|
||||||
|
border-radius:3px;
|
||||||
|
rect {
|
||||||
|
stroke: #fff;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke-dasharray: 778;
|
||||||
|
stroke-dashoffset: 778;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
min-height:100%;
|
||||||
|
height:100%;
|
||||||
|
background:white;
|
||||||
|
position:relative;
|
||||||
|
z-index:0;
|
||||||
|
h1 {
|
||||||
|
padding:75px 0 30px 0;
|
||||||
|
text-align:center;
|
||||||
|
font-size:30px;
|
||||||
|
line-height:30px;
|
||||||
|
}
|
||||||
|
.buttons {
|
||||||
|
max-width:800px;
|
||||||
|
margin:0 auto;
|
||||||
|
padding:0;
|
||||||
|
text-align:center;
|
||||||
|
.button {
|
||||||
|
display:inline-block;
|
||||||
|
text-align:center;
|
||||||
|
padding:10px 15px;
|
||||||
|
margin:10px;
|
||||||
|
background:red;
|
||||||
|
font-size:18px;
|
||||||
|
background-color:#efefef;
|
||||||
|
border-radius:3px;
|
||||||
|
box-shadow:0 1px 2px rgba(0,0,0,.3);
|
||||||
|
cursor:pointer;
|
||||||
|
&:hover {
|
||||||
|
color:white;
|
||||||
|
background:#009bd5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes unfoldIn {
|
||||||
|
0% {
|
||||||
|
transform:scaleY(.005) scaleX(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform:scaleY(.005) scaleX(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scaleY(1) scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes unfoldOut {
|
||||||
|
0% {
|
||||||
|
transform:scaleY(1) scaleX(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform:scaleY(.005) scaleX(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scaleY(.005) scaleX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoomIn {
|
||||||
|
0% {
|
||||||
|
transform:scale(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoomOut {
|
||||||
|
0% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
0% {
|
||||||
|
background:rgba(0,0,0,.0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background:rgba(0,0,0,.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
0% {
|
||||||
|
background:rgba(0,0,0,.7);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background:rgba(0,0,0,.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleUp {
|
||||||
|
0% {
|
||||||
|
transform:scale(.8) translateY(1000px);
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(1) translateY(0px);
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleDown {
|
||||||
|
0% {
|
||||||
|
transform:scale(1) translateY(0px);
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(.8) translateY(1000px);
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleBack {
|
||||||
|
0% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(.85);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleForward {
|
||||||
|
0% {
|
||||||
|
transform:scale(.85);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes quickScaleDown {
|
||||||
|
0% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
99.9% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUpLarge {
|
||||||
|
0% {
|
||||||
|
transform:translateY(0%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateY(-100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideDownLarge {
|
||||||
|
0% {
|
||||||
|
transform:translateY(-100%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateY(0%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes moveUp {
|
||||||
|
0% {
|
||||||
|
transform:translateY(150px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes moveDown {
|
||||||
|
0% {
|
||||||
|
transform:translateY(0px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateY(150px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blowUpContent {
|
||||||
|
0% {
|
||||||
|
transform:scale(1);
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
99.9% {
|
||||||
|
transform:scale(2);
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blowUpContentTwo {
|
||||||
|
0% {
|
||||||
|
transform:scale(2);
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(1);
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blowUpModal {
|
||||||
|
0% {
|
||||||
|
transform:scale(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blowUpModalTwo {
|
||||||
|
0% {
|
||||||
|
transform:scale(1);
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(0);
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes roadRunnerIn {
|
||||||
|
0% {
|
||||||
|
transform:translateX(-1500px) skewX(30deg) scaleX(1.3);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform:translateX(30px) skewX(0deg) scaleX(.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateX(0px) skewX(0deg) scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes roadRunnerOut {
|
||||||
|
0% {
|
||||||
|
transform:translateX(0px) skewX(0deg) scaleX(1);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform:translateX(-30px) skewX(-5deg) scaleX(.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateX(1500px) skewX(30deg) scaleX(1.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes sketchIn {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 778;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes sketchOut {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 778;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalFadeIn {
|
||||||
|
0% {
|
||||||
|
background-color:transparent;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color:white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalFadeOut {
|
||||||
|
0% {
|
||||||
|
background-color:white;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color:transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalContentFadeIn {
|
||||||
|
0% {
|
||||||
|
opacity:0;
|
||||||
|
top:-20px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity:1;
|
||||||
|
top:0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalContentFadeOut {
|
||||||
|
0% {
|
||||||
|
opacity:1;
|
||||||
|
top:0px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity:0;
|
||||||
|
top:-20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bondJamesBond {
|
||||||
|
0% {
|
||||||
|
transform:translateX(1000px);
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform:translateX(0px);
|
||||||
|
border-radius:75px;
|
||||||
|
height:75px;
|
||||||
|
width:75px;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
border-radius:3px;
|
||||||
|
height:182px;
|
||||||
|
width:247px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
border-radius:3px;
|
||||||
|
height:162px;
|
||||||
|
width:227px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes killShot {
|
||||||
|
0% {
|
||||||
|
transform:translateY(0) rotate(0deg);
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:translateY(300px) rotate(45deg);
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeToRed {
|
||||||
|
0% {
|
||||||
|
background-color:rgba(black,.6);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color:rgba(red,.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slowFade {
|
||||||
|
0% {
|
||||||
|
opacity:1;
|
||||||
|
}
|
||||||
|
99.9% {
|
||||||
|
opacity:0;
|
||||||
|
transform:scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform:scale(0);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
import { BiCalendar } from "react-icons/bi";
|
||||||
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import './PozoPublicDatePicker.scss';
|
||||||
|
|
||||||
|
const PozoPublicDatePicker = ({
|
||||||
|
onDateChange,
|
||||||
|
calendarStyle,
|
||||||
|
width = '250px',
|
||||||
|
height = '40px',
|
||||||
|
placeholder = 'Select a date',
|
||||||
|
// borderColor = '#A5A5A5'
|
||||||
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [selectedDate, setSelectedDate] = useState(null);
|
||||||
|
const [currentDate, setCurrentDate] = useState(new Date());
|
||||||
|
const [isFocused, setIsFocused] = useState(false);
|
||||||
|
const pickerRef = useRef(null);
|
||||||
|
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (pickerRef.current && !pickerRef.current.contains(event.target)) {
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleDateClick = (date) => {
|
||||||
|
setSelectedDate(date);
|
||||||
|
if (onDateChange) onDateChange(date);
|
||||||
|
setIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMonthChange = (direction) => {
|
||||||
|
const newDate = new Date(currentDate);
|
||||||
|
newDate.setMonth(currentDate.getMonth() + direction);
|
||||||
|
setCurrentDate(newDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleYearChange = (direction) => {
|
||||||
|
const newDate = new Date(currentDate);
|
||||||
|
newDate.setFullYear(currentDate.getFullYear() + direction);
|
||||||
|
setCurrentDate(newDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDaysInMonth = (year, month) => {
|
||||||
|
const date = new Date(year, month + 1, 0);
|
||||||
|
return Array.from({ length: date.getDate() }, (_, i) => new Date(year, month, i + 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDayHeaders = () => {
|
||||||
|
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||||
|
return (
|
||||||
|
<div className="calendar-headers">
|
||||||
|
{days.map(day => (
|
||||||
|
<div key={day} className="calendar-header-day">
|
||||||
|
{day}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
// console.log(getDaysInMonth(currentDate.getFullYear(), currentDate.getMonth()),"bvyuct7")
|
||||||
|
const renderCalendar = () => {
|
||||||
|
const days = getDaysInMonth(currentDate.getFullYear(), currentDate.getMonth());
|
||||||
|
const startOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDay();
|
||||||
|
const blankDays = Array.from({ length: startOfMonth }, (_, i) => i);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="calendar" style={calendarStyle}>
|
||||||
|
<div className="calendar-header">
|
||||||
|
<button onClick={() => handleYearChange(-1)}><<</button>
|
||||||
|
<button onClick={() => handleMonthChange(-1)}><</button>
|
||||||
|
<span>{currentDate.toLocaleString('default', { month: 'long' })} {currentDate.getFullYear()}</span>
|
||||||
|
<button onClick={() => handleMonthChange(1)}>></button>
|
||||||
|
<button onClick={() => handleYearChange(1)}>>></button>
|
||||||
|
</div>
|
||||||
|
{getDayHeaders()}
|
||||||
|
<div className="calendar-body">
|
||||||
|
{blankDays.map((_, i) => (
|
||||||
|
<div key={`blank-${i}`} className="calendar-day blank"></div>
|
||||||
|
))}
|
||||||
|
{days.map(date => (
|
||||||
|
<div
|
||||||
|
key={date.toString()}
|
||||||
|
className={`calendar-day ${selectedDate && date.toDateString() === selectedDate.toDateString() ? 'selected' : ''}`}
|
||||||
|
onClick={() => handleDateClick(date)}
|
||||||
|
>
|
||||||
|
{date.getDate()}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="date-picker" ref={pickerRef} style={{ width }}>
|
||||||
|
<div
|
||||||
|
className="pickermain"
|
||||||
|
style={{ height }}
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
readOnly
|
||||||
|
value={selectedDate ? selectedDate.toDateString() : placeholder}
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
onFocus={() => setIsFocused(true)}
|
||||||
|
onBlur={() => setIsFocused(false)}
|
||||||
|
className={`date-picker-input ${isFocused || selectedDate ? 'focused' : ''}`}
|
||||||
|
/>
|
||||||
|
<BiCalendar size={18} />
|
||||||
|
</div>
|
||||||
|
{isOpen && renderCalendar()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicDatePicker;
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
.date-picker {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #818181;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickermain {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border: 1px solid var(--input-BorderColor);
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #818181;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 650;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header button {
|
||||||
|
background: #f0f0f0;
|
||||||
|
border: none;
|
||||||
|
padding: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header button:hover {
|
||||||
|
background: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header span {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-headers {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
background: #f0f0f0;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header-day {
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
gap: 4px;
|
||||||
|
padding: 8px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-day {
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-day:hover {
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-day.selected {
|
||||||
|
background: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-day.blank {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
import { BsPlusSquare } from "react-icons/bs";
|
||||||
|
import { IoIosArrowDown } from "react-icons/io";
|
||||||
|
import { useState, useEffect, useRef } from 'react';
|
||||||
|
import "../DropDown/PozoPublicDropDown.scss";
|
||||||
|
import PublicPozoModal from "../PublicPozoModal/PublicPozoModal";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const PozoPublicDropDown = ({
|
||||||
|
placeholder = "Select an option",
|
||||||
|
placeholder2,
|
||||||
|
options,
|
||||||
|
width = "100%",
|
||||||
|
height = "2.5rem",
|
||||||
|
onOptionSelect,
|
||||||
|
className = "",
|
||||||
|
AddModal = false,
|
||||||
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [searchTerm, setSearchTerm] = useState(""); // State to hold the search term
|
||||||
|
const [filteredOptions, setFilteredOptions] = useState(options); // State to hold the filtered options
|
||||||
|
const dropdownRef = useRef(null);
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const toggleDropdown = () => setIsOpen(!isOpen);
|
||||||
|
|
||||||
|
const DropDownModalOpen = () => setIsModalOpen(true);
|
||||||
|
const DropDownModalClose = () => setIsModalOpen(false);
|
||||||
|
|
||||||
|
const handleOptionClick = (option) => {
|
||||||
|
setSearchTerm(option);
|
||||||
|
setIsOpen(false);
|
||||||
|
if (onOptionSelect) {
|
||||||
|
onOptionSelect(option);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleActionClick = () => {
|
||||||
|
console.log('Action button clicked');
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInputChange = (event) => {
|
||||||
|
const searchValue = event.target.value;
|
||||||
|
setSearchTerm(searchValue);
|
||||||
|
|
||||||
|
// Filter options based on the search term
|
||||||
|
const filtered = options.filter(option =>
|
||||||
|
option.toLowerCase().includes(searchValue.toLowerCase())
|
||||||
|
);
|
||||||
|
setFilteredOptions(filtered);
|
||||||
|
setIsOpen(true); // Keep the dropdown open while typing
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// // Update filtered options when the original options change
|
||||||
|
// useEffect(() => {
|
||||||
|
// setFilteredOptions(options);
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={dropdownRef} className={`PozoPublicDropDown-Master ${className}`} style={{ width }} onClick={toggleDropdown}>
|
||||||
|
<div className="PozoPublicDropDownMain" style={{ height, width }}>
|
||||||
|
{placeholder && (
|
||||||
|
<label
|
||||||
|
className={`PozoPublicDropDown-Label ${searchTerm ? "float" : ""}`}
|
||||||
|
htmlFor="dropdown-input">
|
||||||
|
{placeholder}
|
||||||
|
|
||||||
|
</label>
|
||||||
|
|
||||||
|
)}
|
||||||
|
{placeholder2 && (
|
||||||
|
<label
|
||||||
|
className={`PozoPublicDropDown-Label2 ${searchTerm ? "float2" : ""}`}
|
||||||
|
htmlFor="dropdown-input">
|
||||||
|
{placeholder2}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
)}
|
||||||
|
<input
|
||||||
|
id="dropdown-input"
|
||||||
|
type="text"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
onClick={toggleDropdown} // Toggle dropdown when input is clicked
|
||||||
|
/>
|
||||||
|
<div onClick={toggleDropdown}><IoIosArrowDown /></div>
|
||||||
|
|
||||||
|
{AddModal &&
|
||||||
|
<div className="addBTN" onClick={DropDownModalOpen}>
|
||||||
|
<BsPlusSquare opacity={0.6} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{isModalOpen && (
|
||||||
|
<PublicPozoModal
|
||||||
|
style={{ color: "#1c1c1c" }}
|
||||||
|
title="Input With Dropdown"
|
||||||
|
onClose={DropDownModalClose}
|
||||||
|
width="50%"
|
||||||
|
height="40%"
|
||||||
|
handleClick={handleActionClick}
|
||||||
|
>
|
||||||
|
<p> Search also Ad in this Function</p>
|
||||||
|
</PublicPozoModal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isOpen && (
|
||||||
|
<div className="PozoPublicDropDownOptions">
|
||||||
|
{Array.isArray(filteredOptions) && filteredOptions.length > 0 ? (
|
||||||
|
filteredOptions.map((option, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="PozoPublicDropDownOption"
|
||||||
|
onClick={() => handleOptionClick(option)}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="PozoPublicDropDownNoOptions">
|
||||||
|
No options available
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PozoPublicDropDown.propTypes = {
|
||||||
|
placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||||
|
placeholder2: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||||
|
options: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
width: PropTypes.string,
|
||||||
|
height: PropTypes.string,
|
||||||
|
onOptionSelect: PropTypes.func,
|
||||||
|
className: PropTypes.string,
|
||||||
|
AddModal: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
||||||
|
};
|
||||||
|
|
||||||
|
PozoPublicDropDown.defaultProps = {
|
||||||
|
placeholder: "Select an option",
|
||||||
|
placeholder2: "",
|
||||||
|
options: [],
|
||||||
|
width: "100%",
|
||||||
|
height: "2.5rem",
|
||||||
|
AddModal: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default PozoPublicDropDown;
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
.PozoPublicDropDown-Master {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.PozoPublicDropDownMain {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border: 1px solid var(--input-BorderColor);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
border-color: #e33333;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-top: 0;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDown-Label {
|
||||||
|
position: absolute;
|
||||||
|
left: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
color: var(--input-textColor);
|
||||||
|
font-size: 13px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDown-Label2 {
|
||||||
|
position: absolute;
|
||||||
|
left: 14px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
color: var(--input-textColor);
|
||||||
|
font-size: 12px;
|
||||||
|
// background-color: #fff;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDown-Label.float,
|
||||||
|
input:focus+.PozoPublicDropDown-Label,
|
||||||
|
.PozoPublicDropDownMain:focus-within .PozoPublicDropDown-Label {
|
||||||
|
top: -10px;
|
||||||
|
transform: translateY(0);
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--blue-color);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDown-Label2.float2,
|
||||||
|
input:focus+.PozoPublicDropDown-Label2,
|
||||||
|
.PozoPublicDropDownMain:focus-within .PozoPublicDropDown-Label2 {
|
||||||
|
top: -16px;
|
||||||
|
transform: translateY(0);
|
||||||
|
transform: translateX(-17px);
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--blue-color);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Styles for focus state
|
||||||
|
&:focus-within {
|
||||||
|
border-color: var(--input-FocusColor); // Change border color on focus
|
||||||
|
}
|
||||||
|
|
||||||
|
// Styles for hover state
|
||||||
|
&:hover {
|
||||||
|
border-color: #0071e3;
|
||||||
|
color: #0071e3; // Change border color on hover
|
||||||
|
|
||||||
|
.PozoPublicDropDown-Label {
|
||||||
|
color: var(--input-HoverColor); // Change label color on hover
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDown-Label2 {
|
||||||
|
color: var(--input-HoverColor); // Change label color on hover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDownOptions {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
// border: 1px solid var(--input-BorderColor);
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-top: 4px;
|
||||||
|
z-index: 900;
|
||||||
|
height: max-content;
|
||||||
|
max-height: 21vh;
|
||||||
|
// box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
|
||||||
|
overflow-x: scroll;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDownOption {
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
|
border-color: var(--input-HoverColor); // Border color on option hover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicDropDownNoOptions {
|
||||||
|
padding: 10px;
|
||||||
|
color: var(--input-textColor);
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addBTN {
|
||||||
|
display: flex;
|
||||||
|
margin-left: 1rem;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #1c1c1c;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const PozoPublicDropdownAdd = () => {
|
||||||
|
return (
|
||||||
|
<div>PozoPublicDropdownAdd</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicDropdownAdd
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { MdFileDownloadDone } from "react-icons/md";
|
||||||
|
import { AiOutlineCloseCircle } from "react-icons/ai";
|
||||||
|
import { TbCameraPlus } from "react-icons/tb";
|
||||||
|
import { TbUpload } from "react-icons/tb";
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import "../ImagePicker/PozoPublicImagePicker.scss";
|
||||||
|
import PublicPozoModal from "../PublicPozoModal/PublicPozoModal";
|
||||||
|
import PozoPublicButton from "../Button/PozoPublicButton";
|
||||||
|
|
||||||
|
const ImageUploader = ({ width = "100%", height = "100%" }) => {
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [selectedImage, setSelectedImage] = useState(null);
|
||||||
|
const defaultImage = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRtcNX3yxOkc3xIA9tHMsxR_DRuThONLIbPFoeXihVU0XQt1Fxt";
|
||||||
|
|
||||||
|
const handleOpenModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
handleImageUpload
|
||||||
|
setIsModalOpen(false);
|
||||||
|
setSelectedImage(null); // Reset selected image when modal closes
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImageUpload = (event) => {
|
||||||
|
if (event.target.files && event.target.files[0]) {
|
||||||
|
const imageFile = event.target.files[0];
|
||||||
|
setSelectedImage(URL.createObjectURL(imageFile));
|
||||||
|
} else {
|
||||||
|
setSelectedImage(null); // If upload fails, reset to null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='PozoPublicImagePicker-Master'>
|
||||||
|
<div className="PozoPublicImagePickerMain" onClick={handleOpenModal} style={{ width, height }}>
|
||||||
|
<TbUpload size={24} />
|
||||||
|
Image
|
||||||
|
</div>
|
||||||
|
{isModalOpen && (
|
||||||
|
<PublicPozoModal
|
||||||
|
title="Upload Image"
|
||||||
|
onClose={handleCloseModal}
|
||||||
|
width="40%"
|
||||||
|
height="40%"
|
||||||
|
className={"imagemodal"}
|
||||||
|
children={
|
||||||
|
<div className="ImageUploadMain">
|
||||||
|
<div className="imageViwer" >
|
||||||
|
<div className="uploadImage">
|
||||||
|
<div className="imagerUploadsection">
|
||||||
|
<div className="imagerViewer">
|
||||||
|
<img width={100} src={selectedImage || defaultImage} alt="uploaded preview" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="uploadBTN">
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={handleImageUpload}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
id={`imageUploadInput`}
|
||||||
|
/>
|
||||||
|
<label htmlFor={`imageUploadInput`}>
|
||||||
|
<TbUpload size={18} />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <p className="title1">Upload Your Product Image</p> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div style={{ position: "absolute", bottom: "-22px", right: "0" }}>
|
||||||
|
<PozoPublicButton
|
||||||
|
type={"primary"}
|
||||||
|
buttonText={"SUBMIT"} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
</PublicPozoModal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ImageUploader;
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
import { MdFileDownloadDone } from "react-icons/md";
|
||||||
|
import { AiOutlineCloseCircle } from "react-icons/ai";
|
||||||
|
import { TbCameraPlus } from "react-icons/tb";
|
||||||
|
import { TbUpload } from "react-icons/tb";
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import "../ImagePicker/PozoPublicImagePicker.scss";
|
||||||
|
import PublicPozoModal from "../PublicPozoModal/PublicPozoModal";
|
||||||
|
import PozoPublicButton from "../Button/PozoPublicButton";
|
||||||
|
|
||||||
|
const PozoPublicImagePicker = ({ width = "100%", height = "100%" }) => {
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [selectedImages, setSelectedImages] = useState([null, null, null, null, null]);
|
||||||
|
const defaultImage = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRtcNX3yxOkc3xIA9tHMsxR_DRuThONLIbPFoeXihVU0XQt1Fxt";
|
||||||
|
|
||||||
|
const handleOpenModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImageUpload = (event, index) => {
|
||||||
|
if (event.target.files && event.target.files[0]) {
|
||||||
|
const imageFile = event.target.files[0];
|
||||||
|
const updatedImages = [...selectedImages];
|
||||||
|
updatedImages[index] = URL.createObjectURL(imageFile);
|
||||||
|
setSelectedImages(updatedImages);
|
||||||
|
} else {
|
||||||
|
const updatedImages = [...selectedImages];
|
||||||
|
updatedImages[index] = null; // If upload fails, reset to null
|
||||||
|
setSelectedImages(updatedImages);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='PozoPublicImagePicker-Master' >
|
||||||
|
<div className="PozoPublicImagePickerMain" onClick={handleOpenModal} style={{ width, height }}>
|
||||||
|
<TbUpload size={24} />
|
||||||
|
Image
|
||||||
|
</div>
|
||||||
|
{isModalOpen && (
|
||||||
|
<PublicPozoModal
|
||||||
|
title="Upload Images"
|
||||||
|
onClose={handleCloseModal}
|
||||||
|
width="85%"
|
||||||
|
height="max-content"
|
||||||
|
className={"imagemodal"}
|
||||||
|
children={
|
||||||
|
<div className="ImageUploadMain">
|
||||||
|
<div className="imageViwer">
|
||||||
|
|
||||||
|
{[...Array(5)].map((_, index) => (
|
||||||
|
<div className="uploadImage" key={index}>
|
||||||
|
<div className="imagerUploadsection">
|
||||||
|
<div className="imagerViewer">
|
||||||
|
<img width={100} src={selectedImages[index] || defaultImage} alt="uploaded preview" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="uploadBTN">
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={(event) => handleImageUpload(event, index)}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
id={`imageUploadInput-${index}`}
|
||||||
|
/>
|
||||||
|
<label htmlFor={`imageUploadInput-${index}`}>
|
||||||
|
<TbUpload size={18} />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<p className="title1">Upload Your Product Image</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* iframe of video */}
|
||||||
|
<div className="uploadVideo">
|
||||||
|
<p className="title2">Guidline For Image Upload</p>
|
||||||
|
<iframe
|
||||||
|
width="99%"
|
||||||
|
height="200"
|
||||||
|
src="https://www.youtube.com/embed/Rx8n4G4NBZY?si=TSmDh52uyKWIT7x-"
|
||||||
|
title="YouTube video player"
|
||||||
|
frameBorder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
referrerPolicy="strict-origin-when-cross-origin"
|
||||||
|
allowFullScreen
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* guideline for image upload */}
|
||||||
|
<div className="guidlineImage">
|
||||||
|
<div className="imagembFormat">
|
||||||
|
<div style={{ display: "flex", justifyContent: "space-between", columnGap: "5px", width: "100%" }}>
|
||||||
|
<div className="formats">
|
||||||
|
<p>Dimensions:</p>
|
||||||
|
<div>1024 x 768px</div>
|
||||||
|
</div>
|
||||||
|
<div className="formats">
|
||||||
|
<p>Format:</p>
|
||||||
|
<div>JPF , PNG , SVG</div>
|
||||||
|
</div>
|
||||||
|
<div className="formats">
|
||||||
|
<p>File size:</p>
|
||||||
|
<div>Below 5MB</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="picGuide">
|
||||||
|
<img src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
<img src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
<img src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
<img src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
<img src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="blurimages">
|
||||||
|
<img className="blur" src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
<img src="https://img.freepik.com/premium-photo/watch-with-word-time-face_987366-57267.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_hybrid" alt="" />
|
||||||
|
<AiOutlineCloseCircle className="wrong" />
|
||||||
|
<MdFileDownloadDone className="correct" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="imageblur"></div>
|
||||||
|
</div>
|
||||||
|
<div style={{ position: "absolute", bottom: "-22px", right: "0" }}>
|
||||||
|
<PozoPublicButton
|
||||||
|
type={"primary"}
|
||||||
|
buttonText={"SUBMIT"} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
</PublicPozoModal>
|
||||||
|
)}
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicImagePicker;
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
.PozoPublicImagePicker-Master {
|
||||||
|
.PozoPublicImagePickerMain {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 1px solid var(--input-BorderColor);
|
||||||
|
width: max-content;
|
||||||
|
column-gap: 1rem;
|
||||||
|
row-gap: 12px;
|
||||||
|
padding: 20px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--input-textColor);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ImageUploadMain {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem 0rem;
|
||||||
|
column-gap: 10px;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadImage {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
// width: 35%;
|
||||||
|
justify-content: space-around;
|
||||||
|
column-gap: 1rem;
|
||||||
|
row-gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imagerUploadsection {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 1rem;
|
||||||
|
row-gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageViwer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 35%;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 16px;
|
||||||
|
row-gap: 16px;
|
||||||
|
position: relative;
|
||||||
|
top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title1 {
|
||||||
|
position: absolute;
|
||||||
|
top: -36px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadBTN {
|
||||||
|
border: 1px solid var(--input-BorderColor);
|
||||||
|
width: max-content;
|
||||||
|
padding: 26px 38px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 5px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: -7rem;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imagerViewer {
|
||||||
|
width: 100px;
|
||||||
|
height: 85px;
|
||||||
|
border: 2px solid #1292EE;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadVideo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 350px;
|
||||||
|
position: relative;
|
||||||
|
top: 25px;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title2 {
|
||||||
|
position: absolute;
|
||||||
|
top: -33px;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guidlineImage {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formats {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-transform: capitalize;
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #818181;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.imagembFormat {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picGuide {
|
||||||
|
// border: 1px dashed var(--input-BorderColor);
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
column-gap: 5px;
|
||||||
|
row-gap: 5px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 90px;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.blurimages {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 10px;
|
||||||
|
row-gap: 10px;
|
||||||
|
padding: 1rem 0rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrong {
|
||||||
|
position: absolute;
|
||||||
|
position: absolute;
|
||||||
|
font-size: 3rem;
|
||||||
|
color: red;
|
||||||
|
top: 40px;
|
||||||
|
left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur {
|
||||||
|
filter: blur(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.correct {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
font-size: 3rem;
|
||||||
|
color: limegreen;
|
||||||
|
left: 167px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:768px) {
|
||||||
|
.PozoPublicImagePicker-Master .ImageUploadMain {
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 3rem;
|
||||||
|
overflow: scroll;
|
||||||
|
height: 75vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicImagePicker-Master .imageViwer,
|
||||||
|
.PozoPublicImagePicker-Master .guidlineImage {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PublicPozoModal-Master .PublicPozoModalMain {
|
||||||
|
height: 85vh !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicImagePicker-Master .imagerViewer {
|
||||||
|
width: 95px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicImagePicker-Master .picGuide img {
|
||||||
|
width: 100px;
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import "../Input/PozoPublicInput.scss";
|
||||||
|
|
||||||
|
const PozoPublicInput = ({
|
||||||
|
label,
|
||||||
|
type = "text",
|
||||||
|
width = "100%",
|
||||||
|
height = "auto",
|
||||||
|
placeholder,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
onClick,
|
||||||
|
maxLength = 100,
|
||||||
|
disabled = false,
|
||||||
|
className = "",
|
||||||
|
pattern,
|
||||||
|
inputMode,
|
||||||
|
}) => {
|
||||||
|
const [inputValue, setInputValue] = useState(value);
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const newValue = e.target.value;
|
||||||
|
if (newValue.length <= maxLength) {
|
||||||
|
setInputValue(newValue);
|
||||||
|
onChange(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// const testcode = ["pozopublic"]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`PozoPublicInput-Master ${className}`} onClick={onClick} >
|
||||||
|
<div className="PozoPublicInputMain" style={{ width, height }}>
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
placeholder={placeholder || label || ''}
|
||||||
|
name={name}
|
||||||
|
value={inputValue}
|
||||||
|
onChange={handleChange}
|
||||||
|
disabled={disabled}
|
||||||
|
id={name}
|
||||||
|
pattern={pattern}
|
||||||
|
inputMode={inputMode}
|
||||||
|
/>
|
||||||
|
{label && <label className="PozoPublicInput-Label" htmlFor={name}>{label}</label>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicInput;
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
.PozoPublicInputMain {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 12px 16px;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid red;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: transparent;
|
||||||
|
position: relative;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
background-color: #ffffff;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--input-textColor);
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #0071e3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=number]::-webkit-inner-spin-button,
|
||||||
|
input[type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicInput-Label {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px !important;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
font-size: 12px;
|
||||||
|
color: #818181;
|
||||||
|
/* Default label color */
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
background: white;
|
||||||
|
padding: 0 4px;
|
||||||
|
transform-origin: top left;
|
||||||
|
transform: scale(1);
|
||||||
|
text-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus+.PozoPublicInput-Label,
|
||||||
|
input:not(:placeholder-shown)+.PozoPublicInput-Label {
|
||||||
|
top: -10px;
|
||||||
|
left: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #0071e3;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
border-color: #0071e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus::placeholder,
|
||||||
|
input:not(:placeholder-shown)::placeholder {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
border-color: var(--red-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
border-color: var(--green-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { BiChevronDown } from 'react-icons/bi'; // Import a custom icon from React Icons
|
||||||
|
import "../InputDropDown/PozoPublicInputDropdown.scss";
|
||||||
|
|
||||||
|
const PozoPublicInputDropdown = ({
|
||||||
|
width = '100%',
|
||||||
|
height = 'auto',
|
||||||
|
onClick,
|
||||||
|
label,
|
||||||
|
dropdown1Options = [],
|
||||||
|
dropdown2Options = [],
|
||||||
|
select1 = false,
|
||||||
|
select2 = false,
|
||||||
|
select3 = false,
|
||||||
|
}) => {
|
||||||
|
const [dropdown1Value, setDropdown1Value] = useState('');
|
||||||
|
const [dropdown2Value, setDropdown2Value] = useState('');
|
||||||
|
|
||||||
|
const handleDropdown1Change = (e) => {
|
||||||
|
setDropdown1Value(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDropdown2Change = (e) => {
|
||||||
|
setDropdown2Value(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='PozoPublicInputDropdown-Master'
|
||||||
|
style={{ width, height }}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<div className="PozoPublicInputDropdown-Wrapper">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Type something..."
|
||||||
|
className="PozoPublicInputDropdown-Input"
|
||||||
|
/>
|
||||||
|
<span className="PozoPublicInputDropdown-Placeholder">{label}</span>
|
||||||
|
|
||||||
|
{select1 &&
|
||||||
|
<div style={{ position: 'relative', width: '60px' }}>
|
||||||
|
<select
|
||||||
|
value={dropdown1Value}
|
||||||
|
onChange={handleDropdown1Change}
|
||||||
|
className="PozoPublicInputDropdown-Select"
|
||||||
|
style={{ color: dropdown1Value ? 'black' : 'inherit', opacity: "0.8" }}
|
||||||
|
>
|
||||||
|
<option value="">UOM</option>
|
||||||
|
{dropdown1Options.map((option, index) => (
|
||||||
|
<option key={index} value={option} style={{ color: 'black', opacity: "1" }}>
|
||||||
|
{option}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<BiChevronDown className="PozoPublicInputDropdown-Icon" opacity={1} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{select2 &&
|
||||||
|
<div style={{ position: 'relative', width: '60px' }}>
|
||||||
|
<select
|
||||||
|
value={dropdown2Value}
|
||||||
|
onChange={handleDropdown2Change}
|
||||||
|
className="PozoPublicInputDropdown-Select"
|
||||||
|
style={{ color: dropdown2Value ? 'black' : 'inherit', opacity: "0.8" }}
|
||||||
|
>
|
||||||
|
<option value="">SIZE</option>
|
||||||
|
{dropdown2Options.map((option, index) => (
|
||||||
|
<option key={index} value={option} style={{ color: 'black' }}>
|
||||||
|
{option}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<BiChevronDown className="PozoPublicInputDropdown-Icon" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{select3 &&
|
||||||
|
<div style={{ position: 'relative', width: '60px' }}>
|
||||||
|
<select
|
||||||
|
value={dropdown2Value}
|
||||||
|
onChange={handleDropdown2Change}
|
||||||
|
className="PozoPublicInputDropdown-Select"
|
||||||
|
style={{ color: dropdown2Value ? 'black' : 'inherit', opacity: "0.8" }}
|
||||||
|
>
|
||||||
|
<option value="">SIZE</option>
|
||||||
|
{dropdown2Options.map((option, index) => (
|
||||||
|
<option key={index} value={option} style={{ color: 'black' }}>
|
||||||
|
{option}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<BiChevronDown className="PozoPublicInputDropdown-Icon" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PozoPublicInputDropdown.propTypes = {
|
||||||
|
width: PropTypes.string,
|
||||||
|
height: PropTypes.string,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
dropdown1Options: PropTypes.array,
|
||||||
|
dropdown2Options: PropTypes.array
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicInputDropdown;
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
.PozoPublicInputDropdown-Master {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--secondayBTN-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: var(--secondayBTN-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicInputDropdown-Wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
column-gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicInputDropdown-Input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 12px 5px 5px 5px;
|
||||||
|
/* Extra padding-top for placeholder space */
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: transparent;
|
||||||
|
font-size: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus+.PozoPublicInputDropdown-Placeholder,
|
||||||
|
&:not(:placeholder-shown)+.PozoPublicInputDropdown-Placeholder {
|
||||||
|
top: -5px;
|
||||||
|
left: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--secondayBTN-color);
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 1px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicInputDropdown-Placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 5px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: #aaa;
|
||||||
|
transition: 0.3s ease all;
|
||||||
|
pointer-events: none;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.PozoPublicInputDropdown-Select {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px 6px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 13px;
|
||||||
|
appearance: none;
|
||||||
|
/* Hides the default arrow */
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
// padding-right: 30px;
|
||||||
|
opacity: 0.6;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--secondayBTN-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: var(--secondayBTN-color);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
border-color: var(--secondayBTN-color);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicInputDropdown-Icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.PozoPublicInputDropdown-Select option {
|
||||||
|
padding: 10px 12px;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #e33333;
|
||||||
|
font-size: 14px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
transition: background-color 0.2s ease, color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import "../InputSearch/PozoPublicInputSearch.scss";
|
||||||
|
|
||||||
|
const PozoPublicInputSearch = ({
|
||||||
|
label,
|
||||||
|
type = "text",
|
||||||
|
width = "100%",
|
||||||
|
height = "auto",
|
||||||
|
placeholder,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
onClick,
|
||||||
|
disabled = false,
|
||||||
|
className = "",
|
||||||
|
searchResults = [],
|
||||||
|
}) => {
|
||||||
|
const [data, setData] = useState([]);
|
||||||
|
const [Text, setText] = useState([]);
|
||||||
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
||||||
|
const inputRef = useRef(null);
|
||||||
|
|
||||||
|
const OnSearch = (e) => {
|
||||||
|
onChange(e.target.value)
|
||||||
|
const newValue = e.target.value;
|
||||||
|
setText(newValue)
|
||||||
|
const filteredItems = searchResults.filter(item =>
|
||||||
|
item.toLowerCase().includes(newValue.toLowerCase())
|
||||||
|
);
|
||||||
|
setData(filteredItems);
|
||||||
|
setShowSuggestions(newValue.length !== 0);
|
||||||
|
// onChange(e); // Continue to call the passed onChange handler
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (inputRef.current && !inputRef.current.contains(event.target)) {
|
||||||
|
setShowSuggestions(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSuggestionClick = (item) => {
|
||||||
|
setText(item);
|
||||||
|
setShowSuggestions(false);
|
||||||
|
// onChange({ target: { name, value: item } }); // Update the input value
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='PozoPublicInputSearch-Master'>
|
||||||
|
<div className={`PozoPublicInput-Master ${className}`} onClick={onClick} ref={inputRef}>
|
||||||
|
<div className="PozoPublicInputMain" style={{ width, height }}>
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
placeholder={placeholder || label || 'Enter value'}
|
||||||
|
name={name}
|
||||||
|
value={Text}
|
||||||
|
onChange={OnSearch}
|
||||||
|
disabled={disabled}
|
||||||
|
id={name}
|
||||||
|
/>
|
||||||
|
{label && <label className="PozoPublicInput-Label" htmlFor={name}>{label}</label>}
|
||||||
|
|
||||||
|
{showSuggestions && data.length > 0 && (
|
||||||
|
<div className="PozoPublicSearchResults">
|
||||||
|
{data.map((result, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="PozoPublicSearchResultItem"
|
||||||
|
onClick={() => handleSuggestionClick(result)}
|
||||||
|
>
|
||||||
|
{result}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicInputSearch;
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
.PozoPublicInputMain {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 12px 16px;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid var(--input-BorderColor);
|
||||||
|
/* Default border color */
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: transparent;
|
||||||
|
position: relative;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--input-textColor);
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #0071e3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicInput-Label {
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
left: 16px;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
font-size: 14px;
|
||||||
|
color: #818181;
|
||||||
|
/* Default label color */
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
background: white;
|
||||||
|
padding: 0 4px;
|
||||||
|
transform-origin: top left;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus+.PozoPublicInput-Label,
|
||||||
|
input:not(:placeholder-shown)+.PozoPublicInput-Label {
|
||||||
|
top: -10px;
|
||||||
|
left: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #0071e3;
|
||||||
|
font-weight: 600;
|
||||||
|
/* Floating label color */
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
border-color: #0071e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus::placeholder,
|
||||||
|
input:not(:placeholder-shown)::placeholder {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicSearchResults {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 5px 5px;
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.12) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
|
||||||
|
z-index: 99;
|
||||||
|
max-height: 145px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicSearchResultItem {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--light-gray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react';
|
||||||
|
import "../InputWithSearch/InputWithAction.scss"
|
||||||
|
|
||||||
|
const InputWithAction = ({
|
||||||
|
onChange,
|
||||||
|
onClick,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
icon,
|
||||||
|
suffix
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="dropdown-container">
|
||||||
|
<input
|
||||||
|
|
||||||
|
onChange={onChange}
|
||||||
|
onClick={onClick}
|
||||||
|
value={value}
|
||||||
|
placeholder={placeholder}
|
||||||
|
required
|
||||||
|
type='number'
|
||||||
|
icon={icon}
|
||||||
|
suffix={suffix}
|
||||||
|
/>
|
||||||
|
<label>{label}</label>
|
||||||
|
{suffix && (
|
||||||
|
<div className="suffix">
|
||||||
|
{suffix}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InputWithAction
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
.dropdown-container {
|
||||||
|
position: relative;
|
||||||
|
width: 300px;
|
||||||
|
margin: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-input {
|
||||||
|
padding: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container input {
|
||||||
|
width: calc(100% - 3rem);
|
||||||
|
padding: 0.7rem;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
color: rgba(0, 0, 0, 0.7);
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container label {
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
padding: 8px;
|
||||||
|
color: gray;
|
||||||
|
pointer-events: none;
|
||||||
|
font-size: 1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-family: 'poppins';
|
||||||
|
transition: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container input:valid~label,
|
||||||
|
.dropdown-container input:focus~label {
|
||||||
|
color: #007bff;
|
||||||
|
transform: translate(10px, -11px);
|
||||||
|
font-family: 'poppins';
|
||||||
|
font-size: 0.75em;
|
||||||
|
padding: 0 10px;
|
||||||
|
background: white;
|
||||||
|
letter-spacing: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container input:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
box-shadow: 0 0 3px #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container input:focus+label {
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container .suffix {
|
||||||
|
position: relative;
|
||||||
|
right: -11.5rem;
|
||||||
|
top: 0;
|
||||||
|
display: flex;
|
||||||
|
padding: -3rem;
|
||||||
|
width: 100px;
|
||||||
|
height: 73px;
|
||||||
|
flex-direction: column;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import React from 'react';
|
||||||
|
import '../../Styles/Components/PozoPublicLoader.scss';
|
||||||
|
|
||||||
|
const FullPageLoader = () => {
|
||||||
|
return (
|
||||||
|
<div className="loader-container">
|
||||||
|
<div className="loader"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FullPageLoader;
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { CgClose } from "react-icons/cg";
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import "../Modal/PozoPublicModal.scss";
|
||||||
|
|
||||||
|
const PozoPublicModal = ({ isOpen, onClose, children }) => {
|
||||||
|
const handleClose = () => {
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleEscKey = (event) => {
|
||||||
|
if (event.key === "Escape") {
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isOpen) {
|
||||||
|
window.addEventListener("keydown", handleEscKey);
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("keydown", handleEscKey);
|
||||||
|
};
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className={`modal ${isOpen ? "open" : ""}`}>
|
||||||
|
<div className="modal-overlay-pozo" onClick={handleClose}></div>
|
||||||
|
|
||||||
|
<div className="modal-content-pozo">
|
||||||
|
<button className="close-button-pozo" onClick={handleClose}>
|
||||||
|
<span className="material-symbols-outlined" style={{
|
||||||
|
backgroundColor: "#f4f4f4",
|
||||||
|
display: "flex"
|
||||||
|
}}>
|
||||||
|
<CgClose color="#000" />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicModal;
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: rgb(0 0 0 / 53%);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal.open {
|
||||||
|
display: flex;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay-pozo {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content-pozo {
|
||||||
|
min-width: 350px;
|
||||||
|
max-width: 400px;
|
||||||
|
max-height: 76vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 16px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0px 37px 80px rgba(24, 52, 47, 0.028);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button-pozo {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #092b247a;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { IoMdArrowDropdown } from "react-icons/io";
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { BsFillExclamationCircleFill } from 'react-icons/bs';
|
||||||
|
import './Popconfirm.scss'; // Ensure the path is correct
|
||||||
|
|
||||||
|
const Popconfirm = ({ title, onConfirm, onCancel, isVisible, onClose }) => {
|
||||||
|
const [isAnimating, setIsAnimating] = useState(isVisible);
|
||||||
|
const popconfirmRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isVisible) {
|
||||||
|
setIsAnimating(true);
|
||||||
|
} else {
|
||||||
|
setIsAnimating(false);
|
||||||
|
}
|
||||||
|
}, [isVisible]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isVisible && !isAnimating) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
}, [isAnimating, isVisible, onClose]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (popconfirmRef.current && !popconfirmRef.current.contains(event.target)) {
|
||||||
|
onCancel(); // Trigger cancel when clicking outside
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isVisible) {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [isVisible, onCancel]);
|
||||||
|
|
||||||
|
const animationClass = isAnimating ? 'fade-in' : 'fade-out';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`Popconfirm-Master ${animationClass}`} ref={popconfirmRef}>
|
||||||
|
<IoMdArrowDropdown className="arrowicons" />
|
||||||
|
<div className="popconfirm-main">
|
||||||
|
<div className="header">
|
||||||
|
<BsFillExclamationCircleFill color="rgb(255, 122, 0)" size={20} />
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<div className="button">
|
||||||
|
<div className="cancel-button" onClick={onCancel}>No</div>
|
||||||
|
<div className="confirm-button" onClick={onConfirm}>Yes</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Popconfirm.propTypes = {
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
onConfirm: PropTypes.func.isRequired,
|
||||||
|
onCancel: PropTypes.func.isRequired,
|
||||||
|
isVisible: PropTypes.bool.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Popconfirm;
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
.Popconfirm-Master {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: scale(0.8);
|
||||||
|
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out, visibility 0.3s ease-in-out;
|
||||||
|
top: -80px;
|
||||||
|
// left: 74px;
|
||||||
|
right: 0;
|
||||||
|
width: 12rem;
|
||||||
|
|
||||||
|
.arrowicons {
|
||||||
|
position: absolute;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px !important;
|
||||||
|
right: 17px;
|
||||||
|
bottom: -10px;
|
||||||
|
box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.Popconfirm-Master.fade-in {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Popconfirm-Master.fade-out {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popconfirm-main {
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 10px;
|
||||||
|
font-family: 'Gilroy', sans-serif;
|
||||||
|
/* Ensure the font is available */
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-button,
|
||||||
|
.confirm-button {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-button {
|
||||||
|
background-color: #f0f0f0b7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button {
|
||||||
|
background-color: rgb(255, 240, 240);
|
||||||
|
color: #000;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgb(255, 220, 220);
|
||||||
|
/* Slightly different hover color */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:499px) {
|
||||||
|
.Popconfirm-Master {
|
||||||
|
top: -80px;
|
||||||
|
// left: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { IoMdArrowDropdown } from "react-icons/io";
|
||||||
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import "../Popover/PopOver.scss";
|
||||||
|
|
||||||
|
const PopOver = ({ children, content, placement = 'bottom', trigger = 'click', openDelay = 300, closeDelay = 300 }) => {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [timeoutId, setTimeoutId] = useState(null);
|
||||||
|
const popoverRef = useRef(null);
|
||||||
|
const targetRef = useRef(null);
|
||||||
|
|
||||||
|
const handleToggle = () => {
|
||||||
|
if (trigger === 'click') {
|
||||||
|
setVisible(prevVisible => !prevVisible);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
if (trigger === 'hover') {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
setTimeoutId(setTimeout(() => setVisible(true), openDelay));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
if (trigger === 'hover') {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
setTimeoutId(setTimeout(() => setVisible(false), closeDelay));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClickOutside = (e) => {
|
||||||
|
if (popoverRef.current && !popoverRef.current.contains(e.target) &&
|
||||||
|
targetRef.current && !targetRef.current.contains(e.target)) {
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [timeoutId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={targetRef} className="popover-container"
|
||||||
|
onClick={trigger === 'click' ? handleToggle : null}
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
<div ref={popoverRef} className={`popover-content ${visible ? 'visible' : 'hidden'}`} style={{ top: placement === 'bottom' ? '100%' : 'auto', bottom: placement === 'top' ? '100%' : 'auto' }}>
|
||||||
|
{content}
|
||||||
|
<IoMdArrowDropdown size={20} color="#FFF" className="iconarrow" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PopOver;
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
.popover-container {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-content {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 9999;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px 10px;
|
||||||
|
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9);
|
||||||
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 700px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 14px !important;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) scale(0.9);
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconarrow {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -12px;
|
||||||
|
left: calc(50% - 16px);
|
||||||
|
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.popover-content.visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-content.hidden {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Media queries for responsiveness
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.popover-content {
|
||||||
|
max-width: 400px;
|
||||||
|
width: max-content;
|
||||||
|
font-size: 12px !important;
|
||||||
|
margin-left: 8rem;
|
||||||
|
white-space: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconarrow {
|
||||||
|
left: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.popover-content {
|
||||||
|
max-width: 300px;
|
||||||
|
width: max-content;
|
||||||
|
font-size: 12px !important;
|
||||||
|
margin-left: 4.5rem;
|
||||||
|
white-space: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconarrow {
|
||||||
|
left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
|
import "../../Styles/Components/PozoCarousel.scss";
|
||||||
|
import Slide from "../../Images/slide.png";
|
||||||
|
|
||||||
|
const PozoCarousel = () => {
|
||||||
|
const [currentIndex, setCurrentIndex] = useState(0);
|
||||||
|
const [images, setImages] = useState([Slide]);
|
||||||
|
|
||||||
|
const loadDynamicImages = useCallback(() => {
|
||||||
|
try {
|
||||||
|
const customCarousel = JSON.parse(localStorage.getItem('carouselImages'));
|
||||||
|
|
||||||
|
if (customCarousel && Array.isArray(customCarousel) && customCarousel.length > 0) {
|
||||||
|
const dynamicImages = customCarousel
|
||||||
|
.map(item => (typeof item === 'string' ? item : item.image))
|
||||||
|
.filter(Boolean);
|
||||||
|
if (dynamicImages.length > 0) {
|
||||||
|
setImages(dynamicImages);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default: only slide.png
|
||||||
|
setImages([Slide]);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error reading carousel images from localStorage:", err);
|
||||||
|
setImages([Slide]);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadDynamicImages();
|
||||||
|
window.addEventListener("storage", loadDynamicImages);
|
||||||
|
window.addEventListener("carouselImagesUpdated", loadDynamicImages);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("storage", loadDynamicImages);
|
||||||
|
window.removeEventListener("carouselImagesUpdated", loadDynamicImages);
|
||||||
|
};
|
||||||
|
}, [loadDynamicImages]);
|
||||||
|
|
||||||
|
const nextSlide = useCallback(() => {
|
||||||
|
setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length);
|
||||||
|
}, [images.length]);
|
||||||
|
|
||||||
|
const prevSlide = () => {
|
||||||
|
setCurrentIndex((prevIndex) => (prevIndex - 1 + images.length) % images.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
const goToSlide = (index) => {
|
||||||
|
setCurrentIndex(index);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (images.length === 0) return;
|
||||||
|
const interval = setInterval(nextSlide, 6000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [nextSlide, images.length]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="carousel">
|
||||||
|
<button onClick={prevSlide} className="carousel-button prev-button" style={{ fontSize: "1.1rem" }}>❮</button>
|
||||||
|
<div className="carousel-slides" style={{ transform: `translateX(-${currentIndex * 100}%)` }}>
|
||||||
|
{images.map((image, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`carousel-slide ${index === currentIndex ? 'active' : ''}`}
|
||||||
|
>
|
||||||
|
<img src={image} alt={`Slide ${index + 1}`} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<button onClick={nextSlide} className="carousel-button next-button" style={{ fontSize: "1.1rem" }}>❯</button>
|
||||||
|
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||||
|
<div className="carousel-indicators">
|
||||||
|
{images.map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`indicator-bar ${index === currentIndex ? 'active' : ''}`}
|
||||||
|
onClick={() => goToSlide(index)}
|
||||||
|
></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoCarousel;
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import {
|
||||||
|
breadCrumbSelector,
|
||||||
|
changeBreadCrumb,
|
||||||
|
emptyBreadCrumb,
|
||||||
|
} from "../../Features/LandingPage/landingPage.js";
|
||||||
|
import FullPageLoader from "../../Components/Loader/PozoPublicLoader.jsx";
|
||||||
|
import "../../Styles/Components/PozoPublicBreadCrumb.scss";
|
||||||
|
const subDirectory = import.meta.env.BASE_URL;
|
||||||
|
|
||||||
|
const Breadcrumbs = () => {
|
||||||
|
|
||||||
|
const breadCrumb = useSelector(breadCrumbSelector);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const handleBreadcrumbClick = (url) => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
dispatch(emptyBreadCrumb());
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
navigate(url);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{loading && <FullPageLoader />}
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol className="breadcrumb">
|
||||||
|
{breadCrumb.map((item, index) => (
|
||||||
|
<li key={index} className="breadcrumb-item">
|
||||||
|
{index !== 0 && <span className="separator">{">"}</span>}
|
||||||
|
{item.link ? (
|
||||||
|
<a onClick={() => handleBreadcrumbClick(item.link)}>
|
||||||
|
{item.name}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<span>{item.name}</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Breadcrumbs;
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { IoCloseSharp } from 'react-icons/io5';
|
||||||
|
// import Button from '../PozoForm/ButtonPozo';
|
||||||
|
import { PiArrowRightBold } from 'react-icons/pi';
|
||||||
|
import "../../Styles/Components/ModalPozoPublic.scss"
|
||||||
|
|
||||||
|
const ModalPozoPublic = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
button,
|
||||||
|
maxWidth,
|
||||||
|
maxHeight,
|
||||||
|
top,
|
||||||
|
right,
|
||||||
|
left,
|
||||||
|
bottom,
|
||||||
|
closeIcon,
|
||||||
|
title,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const modalRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (event) => {
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (modalRef.current && !modalRef.current.contains(event.target)) {
|
||||||
|
// onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isOpen) {
|
||||||
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', handleKeyDown);
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [isOpen, onClose]);
|
||||||
|
|
||||||
|
if (closeIcon === undefined) {
|
||||||
|
closeIcon = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isOpen) return null;
|
||||||
|
|
||||||
|
const modalStyle = {
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
maxWidth: maxWidth,
|
||||||
|
maxHeight: maxHeight,
|
||||||
|
top: top,
|
||||||
|
right: right,
|
||||||
|
left: left,
|
||||||
|
bottom: bottom,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='modalpozo-overlay'>
|
||||||
|
<div className='modalpozo' style={modalStyle} ref={modalRef}>
|
||||||
|
<div className='modalpozo-inner'>
|
||||||
|
{title && (
|
||||||
|
<div className='modalpozo-title'>
|
||||||
|
<h1>{title}</h1>
|
||||||
|
{closeIcon && (
|
||||||
|
<IoCloseSharp className='close-icon' onClick={onClose} color='black' />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className='modalpozo-content'>{children}</div>
|
||||||
|
{button && (
|
||||||
|
<div className='modalpozo-footer'>
|
||||||
|
<button className='submit-button' onClick={onClose}>
|
||||||
|
Submit <PiArrowRightBold />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalPozoPublic;
|
||||||
|
|
@ -0,0 +1,942 @@
|
||||||
|
import { HiLocationMarker, HiOutlineBadgeCheck } from "react-icons/hi";
|
||||||
|
import { TbTruckDelivery } from "react-icons/tb";
|
||||||
|
import { BsLightningChargeFill } from "react-icons/bs";
|
||||||
|
import { TbShare3 } from "react-icons/tb";
|
||||||
|
import { RiDeleteBinLine } from "react-icons/ri";
|
||||||
|
import { BiBookmark } from "react-icons/bi";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { RiArrowDownSFill } from "react-icons/ri";
|
||||||
|
import { BiRupee, BiStopwatch } from "react-icons/bi";
|
||||||
|
import { AiOutlineHeart, AiFillStar } from "react-icons/ai";
|
||||||
|
import { CiShop } from "react-icons/ci";
|
||||||
|
import { GiScooter } from "react-icons/gi";
|
||||||
|
import { IoCloseSharp } from "react-icons/io5";
|
||||||
|
import ModalPozoPublic from "./ModalPozoPublic.jsx";
|
||||||
|
// import ShopCardQuantity from "./ShopCardQuantity";
|
||||||
|
import HeartSvg from "../../Images/Assets/HeartSvg";
|
||||||
|
import "../../Styles/Components/ShopCard.scss";
|
||||||
|
import pozologoimg from "../../Images/PozoStore.svg";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import FullPageLoader from "../../Components/Loader/PozoPublicLoader.jsx";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { changeCartShow } from "../../Features/Cart/GlobalPublicBooking.js";
|
||||||
|
const subDirectory = import.meta.env.BASE_URL;
|
||||||
|
const ShopCard = ({
|
||||||
|
id,
|
||||||
|
shopName,
|
||||||
|
dishName,
|
||||||
|
imageUrl,
|
||||||
|
price,
|
||||||
|
deliveryTime,
|
||||||
|
deliveryDistance,
|
||||||
|
offer,
|
||||||
|
isVeg,
|
||||||
|
isNonVeg,
|
||||||
|
isFavorite,
|
||||||
|
addToCartBtn,
|
||||||
|
showCartShopName,
|
||||||
|
showQuantityModal,
|
||||||
|
showChangeQuantity,
|
||||||
|
offerValue,
|
||||||
|
deliveryAvailable,
|
||||||
|
MRP,
|
||||||
|
Buy,
|
||||||
|
QuantityPrice,
|
||||||
|
Review,
|
||||||
|
buyNow,
|
||||||
|
direction,
|
||||||
|
cartSDS,
|
||||||
|
deliveryStatus,
|
||||||
|
Cartoffer,
|
||||||
|
shopNameShow,
|
||||||
|
CartMRP,
|
||||||
|
Color,
|
||||||
|
Size,
|
||||||
|
Accredited,
|
||||||
|
showSize,
|
||||||
|
showColor,
|
||||||
|
youSave,
|
||||||
|
SDSIcon,
|
||||||
|
multiQty,
|
||||||
|
HomePrice,
|
||||||
|
ShowPinCodecheck,
|
||||||
|
ProductDescription,
|
||||||
|
InfoReview,
|
||||||
|
SingleImage,
|
||||||
|
ImageForwad,
|
||||||
|
Imagebackward,
|
||||||
|
imageChangeButtons,
|
||||||
|
imgwidth,
|
||||||
|
imgheight,
|
||||||
|
ShopCardDetailswidth,
|
||||||
|
Type,
|
||||||
|
favchecked,
|
||||||
|
data
|
||||||
|
}) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const [fillColor, setFillColor] = useState(isFavorite ? "white" : "#D42527");
|
||||||
|
const [quantity, setQuantity] = useState(0);
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [isCartVisible, setIsCartVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (favchecked == "Y") {
|
||||||
|
setFillColor('#D42527')
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const openModal2 = () => setIsOpen(true);
|
||||||
|
const closeModal2 = () => setIsOpen(false);
|
||||||
|
const handleHeartClick = () => {
|
||||||
|
setFillColor((prevColor) => (prevColor === "white" ? "#D42527" : "white"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddToCartClick = () => {
|
||||||
|
setIsVisible(true);
|
||||||
|
setIsCartVisible(true);
|
||||||
|
setQuantity((prevQuantity) => prevQuantity + 1);
|
||||||
|
dispatch(changeCartShow(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleQuantityChange = (change) => {
|
||||||
|
setQuantity((prevQuantity) => {
|
||||||
|
const newQuantity = Math.max(prevQuantity + change, 0);
|
||||||
|
if (newQuantity === 0) {
|
||||||
|
setIsVisible(false);
|
||||||
|
dispatch(changeCartShow(false));
|
||||||
|
}
|
||||||
|
return newQuantity;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageNavigate = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`${subDirectory}app-page/store`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageIndividualNavigate = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`${subDirectory}app-page/IndividualCard`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [currentImage, setCurrentImage] = useState(imageUrl);
|
||||||
|
const [fade, setFade] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
changeImage(imageUrl);
|
||||||
|
}, [imageUrl]);
|
||||||
|
const changeImage = (newImage) => {
|
||||||
|
setFade(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCurrentImage(newImage);
|
||||||
|
setFade(true);
|
||||||
|
}, 300); // Duration of the fade-out effect
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigateToCheckout = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`${subDirectory}app-page/checkout`);
|
||||||
|
setLoading(false);
|
||||||
|
}, 700);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{loading && <FullPageLoader />}
|
||||||
|
{isOpen && (
|
||||||
|
<div className="modal-overlay" onClick={closeModal2}>
|
||||||
|
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<button className="close-button" onClick={closeModal2}>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<img
|
||||||
|
className={`slider-image ${fade ? "fade-in" : "fade-out"}`}
|
||||||
|
src={imageUrl}
|
||||||
|
alt="large"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
Imagebackward();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-left-big"
|
||||||
|
>
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
ImageForwad();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-right-big"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div style={{ width: "inherit" }}>
|
||||||
|
<div className="ShopCard-Master">
|
||||||
|
<div
|
||||||
|
className="ShopCard-main"
|
||||||
|
key={id}
|
||||||
|
style={{ flexDirection: `${direction}` }}
|
||||||
|
>
|
||||||
|
{Type == "individualCard" ? (
|
||||||
|
<div className="ShopCard-img-parrent">
|
||||||
|
<div className="ShopCard-img">
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button onClick={() => { Imagebackward(); }} className="Shopcard-carosel-left" >
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
width: imgwidth ? imgwidth : "",
|
||||||
|
height: imgheight ? imgheight : imgwidth ? imgwidth : "",
|
||||||
|
}}
|
||||||
|
// className={`slider-image ${fade ? "fade-in" : "fade-out"}`}
|
||||||
|
src={imageUrl}
|
||||||
|
alt={dishName}
|
||||||
|
onClick={
|
||||||
|
SingleImage == "Y" ? openModal2 : PageIndividualNavigate
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
ImageForwad();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-right"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isFavorite == "Y" && (
|
||||||
|
<p onClick={handleHeartClick}>
|
||||||
|
<HeartSvg
|
||||||
|
fillColor={fillColor}
|
||||||
|
strokeColor="gray"
|
||||||
|
height="20px"
|
||||||
|
width="20px"
|
||||||
|
position="absolute"
|
||||||
|
top="0"
|
||||||
|
left="-5"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{offer == "Y" && (
|
||||||
|
<span>{offerValue ? `${offerValue} % OFF` : ""}</span>
|
||||||
|
)}
|
||||||
|
{isVeg == "veg" && (
|
||||||
|
<div className="veg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#007E1C",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isNonVeg == "Y" && (
|
||||||
|
<div className="nonveg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#BD0606",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="ShopCard-img">
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
Imagebackward();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-left"
|
||||||
|
>
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
width: imgwidth ? imgwidth : "",
|
||||||
|
height: imgheight ? imgheight : imgwidth ? imgwidth : "",
|
||||||
|
}}
|
||||||
|
className={`slider-image ${fade ? "fade-in" : "fade-out"}`}
|
||||||
|
src={imageUrl}
|
||||||
|
alt={dishName}
|
||||||
|
onClick={
|
||||||
|
SingleImage == "Y" ? openModal2 : PageIndividualNavigate
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
ImageForwad();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-right"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isFavorite == "Y" && (
|
||||||
|
<p onClick={handleHeartClick}>
|
||||||
|
<HeartSvg
|
||||||
|
fillColor={fillColor}
|
||||||
|
strokeColor="gray"
|
||||||
|
height="20px"
|
||||||
|
width="20px"
|
||||||
|
position="absolute"
|
||||||
|
top="0"
|
||||||
|
left="-3"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{offer == "Y" && (
|
||||||
|
<span>{offerValue ? `${offerValue} % OFF` : ""}</span>
|
||||||
|
)}
|
||||||
|
{isVeg == "veg" && (
|
||||||
|
<div className="veg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#007E1C",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isNonVeg == "Y" && (
|
||||||
|
<div className="nonveg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#BD0606",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="ShopCard-details"
|
||||||
|
style={{
|
||||||
|
width:
|
||||||
|
direction == "row"
|
||||||
|
? ShopCardDetailswidth
|
||||||
|
? ShopCardDetailswidth
|
||||||
|
: "80vw"
|
||||||
|
: "",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{showQuantityModal == "Y" && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="add-quantity-modal">
|
||||||
|
400 g <RiArrowDownSFill size={18} />
|
||||||
|
</div>
|
||||||
|
{QuantityPrice && (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "Green",
|
||||||
|
fontSize: "19px",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BiRupee size={17} style={{ marginRight: "-3px" }} />
|
||||||
|
{QuantityPrice}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ShopCard-review" style={{ fontSize: "12px" }}>
|
||||||
|
<p>
|
||||||
|
<AiFillStar color="#FF7A00" /> <span>4.5</span>
|
||||||
|
</p>
|
||||||
|
<div className="reviewHover">(1 Review)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{shopNameShow == "Y" && (
|
||||||
|
<div className="ShopCard-shopName" onClick={PageNavigate}>
|
||||||
|
{Type == "PozoCart" ? "From" : "Visit"} <CiShop style={{ fontSize: '14px' }} />
|
||||||
|
<small className="scroll-shop">{shopName}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="ShopCard-dishName-review">
|
||||||
|
<div className="ShopCard-dishName">
|
||||||
|
<p
|
||||||
|
onClick={PageIndividualNavigate}
|
||||||
|
className="Shoopcard-productName"
|
||||||
|
style={{ paddingRight: "2rem !important", cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
{dishName}
|
||||||
|
</p>
|
||||||
|
{deliveryAvailable == "Y" && (
|
||||||
|
<div className="delivery">
|
||||||
|
<GiScooter size={18} style={{ marginBottom: "-3px" }} />{" "}
|
||||||
|
Delivery Available
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{ProductDescription == "Y" && (
|
||||||
|
<div>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontSize: "12px",
|
||||||
|
lineHeight: "1rem",
|
||||||
|
color: "#515151",
|
||||||
|
padding: "15px 10px 15px 0 ",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Bluetooth Soundbar w/ 500W RMS Signature Sound,5.1
|
||||||
|
Channel Surround Sound,BTv5.3, Wall Mountable
|
||||||
|
Design,Bass&Treble Controls&Master Remote
|
||||||
|
Control(Premium Black)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showCartShopName == "Y" && (
|
||||||
|
<div onClick={PageNavigate} className="ShopCard-shopName2">
|
||||||
|
From <CiShop size={15} />
|
||||||
|
<small className="scroll-shop">{shopName}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{Accredited == "Y" && (
|
||||||
|
<div className="Accredited">
|
||||||
|
<img src={pozologoimg} alt="pozologoimg" width={40} />
|
||||||
|
<span>
|
||||||
|
{" "}
|
||||||
|
<HiOutlineBadgeCheck
|
||||||
|
color="white"
|
||||||
|
size={15}
|
||||||
|
style={{ marginBottom: "-4px" }}
|
||||||
|
/>
|
||||||
|
Accredited
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{InfoReview == "Y" && (
|
||||||
|
<div>
|
||||||
|
<div className="ShopCard-review">
|
||||||
|
<p>
|
||||||
|
<AiFillStar
|
||||||
|
style={{ fontSize: "20px" }}
|
||||||
|
color="#FF7A00"
|
||||||
|
/>{" "}
|
||||||
|
<span style={{ fontSize: "20px" }}>4.5</span>
|
||||||
|
</p>
|
||||||
|
<div className="reviewHover">(1 Review)</div>
|
||||||
|
<span className="review-modal">
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing
|
||||||
|
elit. At quas eius quaerat rerum, accusantium quis
|
||||||
|
maxime reiciendis
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="ShopCard-prize-btn">
|
||||||
|
{Type == "individualCard" && (
|
||||||
|
<div className="ShopCard-prize">
|
||||||
|
<div style={{ display: "flex", columnGap: "10px" }}>
|
||||||
|
{price && (
|
||||||
|
<p className="shopcard-price-p">
|
||||||
|
<BiRupee
|
||||||
|
size={13}
|
||||||
|
style={{
|
||||||
|
marginBottom: "2px",
|
||||||
|
marginRight: "-3px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{price}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{HomePrice && (
|
||||||
|
<p>
|
||||||
|
From{" "}
|
||||||
|
<BiRupee
|
||||||
|
size={16}
|
||||||
|
style={{
|
||||||
|
marginBottom: "-1px",
|
||||||
|
marginRight: "-3px",
|
||||||
|
}}
|
||||||
|
/>{" "}
|
||||||
|
{HomePrice} /-
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{CartMRP == "Y" && (
|
||||||
|
<span
|
||||||
|
className="shop-cart-mrp"
|
||||||
|
style={{ fontSize: "10px" }}
|
||||||
|
>
|
||||||
|
M.R.P.: <s>₹1,0099.00</s>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Cartoffer == "Y" && (
|
||||||
|
<span
|
||||||
|
className="shopcard-offertag"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#D42527",
|
||||||
|
borderRadius: "50px",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
padding: "5px 10px",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{offerValue ? `${offerValue} % OFF` : ""}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{youSave && (
|
||||||
|
<div className="you-save">You Save ₹{youSave}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deliveryTime && (
|
||||||
|
<div className="ShopCard-stopwatch">
|
||||||
|
<BiStopwatch size={16} /> {deliveryTime}{" "}
|
||||||
|
{deliveryDistance && " • " + deliveryDistance}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ShowPinCodecheck == "Y" && (
|
||||||
|
<div className="ShopCard-pincode">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "0.3rem",
|
||||||
|
backgroundColor: "#f4f4f4",
|
||||||
|
padding: "4px 10px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HiLocationMarker
|
||||||
|
style={{ color: "#E33333", fontSize: "20px" }}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
placeholder="Enter Pincode"
|
||||||
|
type="number"
|
||||||
|
maxLength={5}
|
||||||
|
style={{
|
||||||
|
width: "6rem",
|
||||||
|
outline: "none",
|
||||||
|
border: "none",
|
||||||
|
padding: "3px 0px",
|
||||||
|
backgroundColor: "#f4f4f4",
|
||||||
|
}}
|
||||||
|
onInput={(e) => {
|
||||||
|
if (e.target.value.length > 6) {
|
||||||
|
e.target.value = e.target.value.slice(0, 6);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p style={{ fontSize: "12px", cursor: "pointer" }}>
|
||||||
|
Check Delivery
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
rowGap: "2px",
|
||||||
|
marginTop: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{showSize == "Y" && (
|
||||||
|
<div className="size">
|
||||||
|
Size : <div> {Size}
|
||||||
|
<select className="sizeOption" name="Size" id="Size" style={{
|
||||||
|
width: "maxContent", fontFamily: "Gilroy",
|
||||||
|
fontWeight: "500", padding: "2px 2px",
|
||||||
|
marginTop: "-2px",
|
||||||
|
border: "none",
|
||||||
|
borderRadius: "6px",
|
||||||
|
backgroundColor: "rgb(255,240,240)",
|
||||||
|
width: "5rem",
|
||||||
|
cursor: "pointer"
|
||||||
|
|
||||||
|
|
||||||
|
}}>
|
||||||
|
<option className="SizeOptions" value="L">XS</option>
|
||||||
|
<option className="SizeOptions" value="L">S</option>
|
||||||
|
<option className="SizeOptions" value="L">M</option>
|
||||||
|
<option className="SizeOptions" value="L">L</option>
|
||||||
|
<option className="SizeOptions" value="L">XL</option>
|
||||||
|
<option className="SizeOptions" value="L">XXL</option>
|
||||||
|
<option className="SizeOptions" value="L">3-XL</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showColor == "Y" && (
|
||||||
|
<div className="color">
|
||||||
|
Color : <div> {Color}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{Review == "Y" && (
|
||||||
|
<div className="ShopCard-review">
|
||||||
|
<p style={{ display: "flex" }}>
|
||||||
|
<AiFillStar color="#FF7A00" /> <span>4.5</span>
|
||||||
|
</p>
|
||||||
|
<div className="reviewHover">(1 Review)</div>
|
||||||
|
<span className="review-modal">
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
At quas eius quaerat rerum, accusantium quis maxime
|
||||||
|
reiciendis
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{cartSDS == "Y" && (
|
||||||
|
<div className="cart-sds">
|
||||||
|
<p>
|
||||||
|
<BiBookmark
|
||||||
|
size={14}
|
||||||
|
color="#1C1C1C"
|
||||||
|
style={{ marginBottom: "-2px" }}
|
||||||
|
/>{" "}
|
||||||
|
Save for later
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<RiDeleteBinLine
|
||||||
|
size={15}
|
||||||
|
style={{ marginBottom: "-2px" }}
|
||||||
|
/>{" "}
|
||||||
|
delete
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<TbShare3 size={15} style={{ marginBottom: "-2px" }} />{" "}
|
||||||
|
share
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{SDSIcon == "Y" && (
|
||||||
|
<div className="SDSIcon">
|
||||||
|
<p style={{ display: "flex", columnGap: "10px" }}>
|
||||||
|
{Type !== "individualCard" && <BiBookmark
|
||||||
|
size={20}
|
||||||
|
color="#1C1C1C"
|
||||||
|
style={{ marginBottom: "-2px", strokeWidth: "0.1" }}
|
||||||
|
/>}
|
||||||
|
{Type !== "individualCard" && <RiDeleteBinLine
|
||||||
|
size={20}
|
||||||
|
strokeWidth={0.7}
|
||||||
|
style={{ marginBottom: "-2px", strokeWidth: "0.1" }}
|
||||||
|
/>}
|
||||||
|
<TbShare3
|
||||||
|
className="share-icon"
|
||||||
|
size={30}
|
||||||
|
style={{ marginBottom: "-2px", strokeWidth: "0.7" }}
|
||||||
|
/>{" "}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="ShopCard-quantity-button">
|
||||||
|
{MRP && <s>M.R.P.:₹{MRP}</s>}
|
||||||
|
{Buy == "Y" && <p>BUY</p>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ShopCard-prize-btn">
|
||||||
|
{Type !== "individualCard" && (
|
||||||
|
<div className="ShopCard-prize">
|
||||||
|
<div style={{ display: 'flex', columnGap: "10px" }}>
|
||||||
|
{price && (
|
||||||
|
<p className="shopcard-price-p">
|
||||||
|
<BiRupee size={14} style={{ marginTop: "2px", marginRight: "-3px" }} />{price}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{HomePrice && (
|
||||||
|
<p>
|
||||||
|
From <BiRupee size={16} style={{ marginBottom: "-1px", marginRight: "-3px" }} /> {HomePrice} /-
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/*================== cart MRP ============= */}
|
||||||
|
{CartMRP == "Y" && (
|
||||||
|
<span className="shop-cart-mrp" style={{ fontSize: "10px", }}>M.R.P.: <s>₹1,0099.00</s></span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Cartoffer == "Y" && (
|
||||||
|
<span
|
||||||
|
className="shopcard-offertag"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#D42527",
|
||||||
|
borderRadius: "50px",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
padding: "5px 10px",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontFamily: "Gilroy"
|
||||||
|
}}>
|
||||||
|
{offerValue ? `${offerValue} % OFF` : ""}
|
||||||
|
</span>)}
|
||||||
|
{youSave && (
|
||||||
|
<div className="you-save">
|
||||||
|
You Save ₹{youSave}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deliveryTime && (
|
||||||
|
<div className="ShopCard-stopwatch">
|
||||||
|
<BiStopwatch size={16} /> {deliveryTime} {deliveryDistance && " • " + deliveryDistance}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
<div className="shopcard-delivery-parent">
|
||||||
|
|
||||||
|
{deliveryStatus == "Y" && (
|
||||||
|
<div className="delivery-status">
|
||||||
|
<TbTruckDelivery
|
||||||
|
size={14}
|
||||||
|
style={{ marginBottom: "-3px" }}
|
||||||
|
/>
|
||||||
|
<span> DELIVERY </span>Free •{" "}
|
||||||
|
<span>6 | Jul | Saturday </span>
|
||||||
|
{" "}
|
||||||
|
|
||||||
|
<span style={{
|
||||||
|
backgroundColor: "#e33333", padding: "2px 8px",
|
||||||
|
borderRadius: "6px", color: "#fff", cursor: 'pointer'
|
||||||
|
}}><BsLightningChargeFill
|
||||||
|
color="#fff"
|
||||||
|
size={12}
|
||||||
|
style={{ marginBottom: "-2px" }}
|
||||||
|
/> Fast</span> <span> • Today</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="ShopCard-btn">
|
||||||
|
{showChangeQuantity == "Y" && (
|
||||||
|
<div className="add-quantity" onClick={openModal}>
|
||||||
|
400 g <RiArrowDownSFill size={18} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{buyNow == "Y" && <p onClick={navigateToCheckout} className="buy-now">BUY NOW </p>}
|
||||||
|
{isVisible ? (
|
||||||
|
<div className="add-minus">
|
||||||
|
<span onClick={() => handleQuantityChange(-1)}>-</span>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontSize: "17px",
|
||||||
|
}}
|
||||||
|
|
||||||
|
>
|
||||||
|
{quantity}
|
||||||
|
</p>
|
||||||
|
<span onClick={() => handleQuantityChange(1)}>+</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
addToCartBtn == "Y" && (
|
||||||
|
<>
|
||||||
|
<div className="buy" onClick={handleAddToCartClick}>
|
||||||
|
Add to Cart
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalPozoPublic
|
||||||
|
onClose={closeModal}
|
||||||
|
width="700px"
|
||||||
|
height="400px"
|
||||||
|
maxWidth="90%"
|
||||||
|
maxHeight="90%"
|
||||||
|
top="auto"
|
||||||
|
right="auto"
|
||||||
|
left="auto"
|
||||||
|
bottom="auto"
|
||||||
|
closeIcon={<IoCloseSharp />}
|
||||||
|
title="Select your Quantity"
|
||||||
|
isOpen={isModalOpen}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{multiQty?.map((data) => (
|
||||||
|
<ShopCard
|
||||||
|
imageUrl={data.imageUrl}
|
||||||
|
Buy="Y"
|
||||||
|
isFavorite="Y"
|
||||||
|
offer="Y"
|
||||||
|
offerValue="30"
|
||||||
|
showQuantityModal="Y"
|
||||||
|
QuantityPrice="35.00"
|
||||||
|
isNonVeg={data?.continental == "NonVeg" && "Y"}
|
||||||
|
isVeg={data?.continental == "Veg" && "Y"}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ModalPozoPublic>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
// console.log(ShopCard.propTypes, "ShopCardShopCard");
|
||||||
|
ShopCard.propTypes = {
|
||||||
|
id: PropTypes.number.isRequired,
|
||||||
|
shopName: PropTypes.string.isRequired,
|
||||||
|
dishName: PropTypes.string.isRequired,
|
||||||
|
imageUrl: PropTypes.string.isRequired,
|
||||||
|
price: PropTypes.string.isRequired,
|
||||||
|
deliveryTime: PropTypes.string.isRequired,
|
||||||
|
deliveryDistance: PropTypes.string.isRequired,
|
||||||
|
direction: PropTypes.string.isRequired,
|
||||||
|
QuantityPrice: PropTypes.string.isRequired,
|
||||||
|
Color: PropTypes.string.isRequired,
|
||||||
|
Size: PropTypes.string.isRequired,
|
||||||
|
youSave: PropTypes.string.isRequired,
|
||||||
|
HomePrice: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
offer: PropTypes.bool,
|
||||||
|
isVeg: PropTypes.bool,
|
||||||
|
isNonVeg: PropTypes.bool,
|
||||||
|
isFavorite: PropTypes.bool,
|
||||||
|
addToCartBtn: PropTypes.bool,
|
||||||
|
showCartShopName: PropTypes.bool,
|
||||||
|
showQuantityModal: PropTypes.bool,
|
||||||
|
showChangeQuantity: PropTypes.bool,
|
||||||
|
deliveryAvailable: PropTypes.bool,
|
||||||
|
Buy: PropTypes.bool,
|
||||||
|
Review: PropTypes.bool,
|
||||||
|
buyNow: PropTypes.bool,
|
||||||
|
cartSDS: PropTypes.bool,
|
||||||
|
deliveryStatus: PropTypes.bool,
|
||||||
|
Cartoffer: PropTypes.bool,
|
||||||
|
shopNameShow: PropTypes.bool,
|
||||||
|
CartMRP: PropTypes.bool,
|
||||||
|
Accredited: PropTypes.bool,
|
||||||
|
showSize: PropTypes.bool,
|
||||||
|
showColor: PropTypes.bool,
|
||||||
|
youSave: PropTypes.bool,
|
||||||
|
SDSIcon: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
ShopCard.defaultProps = {
|
||||||
|
offer: true,
|
||||||
|
isVeg: false,
|
||||||
|
isNonVeg: false,
|
||||||
|
isFavorite: true,
|
||||||
|
addToCartBtn: true,
|
||||||
|
showCartShopName: true,
|
||||||
|
showQuantityModal: true,
|
||||||
|
showChangeQuantity: true,
|
||||||
|
deliveryAvailable: true,
|
||||||
|
Buy: true,
|
||||||
|
Review: true,
|
||||||
|
buyNow: true,
|
||||||
|
cartSDS: true,
|
||||||
|
deliveryStatus: true,
|
||||||
|
Cartoffer: true,
|
||||||
|
shopNameShow: true,
|
||||||
|
CartMRP: true,
|
||||||
|
Accredited: true,
|
||||||
|
showSize: true,
|
||||||
|
showColor: true,
|
||||||
|
SDSIcon: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShopCard;
|
||||||
|
|
@ -0,0 +1,902 @@
|
||||||
|
import { HiLocationMarker, HiOutlineBadgeCheck } from "react-icons/hi";
|
||||||
|
import { TbTruckDelivery } from "react-icons/tb";
|
||||||
|
import { BsLightningChargeFill } from "react-icons/bs";
|
||||||
|
import { TbShare3 } from "react-icons/tb";
|
||||||
|
import { RiDeleteBinLine } from "react-icons/ri";
|
||||||
|
import { BiBookmark } from "react-icons/bi";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { RiArrowDownSFill } from "react-icons/ri";
|
||||||
|
import { BiRupee, BiStopwatch } from "react-icons/bi";
|
||||||
|
import { AiOutlineHeart, AiFillStar } from "react-icons/ai";
|
||||||
|
import { CiShop } from "react-icons/ci";
|
||||||
|
import { GiScooter } from "react-icons/gi";
|
||||||
|
import { IoCloseSharp } from "react-icons/io5";
|
||||||
|
import ModalPozoPublic from "../../Components/PozoPublicCard/ModalPozoPublic.jsx";
|
||||||
|
// import ShopCardQuantity from "./ShopCardQuantity";
|
||||||
|
import HeartSvg from "../../Images/Assets/HeartSvg";
|
||||||
|
import "../../Styles/Components/ShopCard.scss";
|
||||||
|
import pozologoimg from "../../Images/PozoStore.svg";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import FullPageLoader from "../../Components/Loader/PozoPublicLoader.jsx";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { changeCartShow } from "../../Features/Cart/GlobalPublicBooking.js";
|
||||||
|
|
||||||
|
const ShopCard = ({
|
||||||
|
id,
|
||||||
|
shopName,
|
||||||
|
dishName,
|
||||||
|
imageUrl,
|
||||||
|
price,
|
||||||
|
deliveryTime,
|
||||||
|
deliveryDistance,
|
||||||
|
offer,
|
||||||
|
isVeg,
|
||||||
|
isNonVeg,
|
||||||
|
isFavorite,
|
||||||
|
addToCartBtn,
|
||||||
|
showCartShopName,
|
||||||
|
showQuantityModal,
|
||||||
|
showChangeQuantity,
|
||||||
|
offerValue,
|
||||||
|
deliveryAvailable,
|
||||||
|
MRP,
|
||||||
|
Buy,
|
||||||
|
QuantityPrice,
|
||||||
|
Review,
|
||||||
|
buyNow,
|
||||||
|
direction,
|
||||||
|
cartSDS,
|
||||||
|
deliveryStatus,
|
||||||
|
Cartoffer,
|
||||||
|
shopNameShow,
|
||||||
|
CartMRP,
|
||||||
|
Color,
|
||||||
|
Size,
|
||||||
|
Accredited,
|
||||||
|
showSize,
|
||||||
|
showColor,
|
||||||
|
youSave,
|
||||||
|
SDSIcon,
|
||||||
|
multiQty,
|
||||||
|
HomePrice,
|
||||||
|
ShowPinCodecheck,
|
||||||
|
ProductDescription,
|
||||||
|
InfoReview,
|
||||||
|
SingleImage,
|
||||||
|
ImageForwad,
|
||||||
|
Imagebackward,
|
||||||
|
imageChangeButtons,
|
||||||
|
imgwidth,
|
||||||
|
imgheight,
|
||||||
|
ShopCardDetailswidth,
|
||||||
|
Type,
|
||||||
|
}) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const [fillColor, setFillColor] = useState(isFavorite ? "white" : "#D42527");
|
||||||
|
const [quantity, setQuantity] = useState(0);
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [isCartVisible, setIsCartVisible] = useState(false);
|
||||||
|
|
||||||
|
const openModal2 = () => setIsOpen(true);
|
||||||
|
const closeModal2 = () => setIsOpen(false);
|
||||||
|
const handleHeartClick = () => {
|
||||||
|
setFillColor((prevColor) => (prevColor === "white" ? "#D42527" : "white"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddToCartClick = () => {
|
||||||
|
setIsVisible(true);
|
||||||
|
setIsCartVisible(true);
|
||||||
|
setQuantity((prevQuantity) => prevQuantity + 1);
|
||||||
|
dispatch(changeCartShow(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleQuantityChange = (change) => {
|
||||||
|
setQuantity((prevQuantity) => {
|
||||||
|
const newQuantity = Math.max(prevQuantity + change, 0);
|
||||||
|
if (newQuantity === 0) {
|
||||||
|
setIsVisible(false);
|
||||||
|
dispatch(changeCartShow(false));
|
||||||
|
}
|
||||||
|
return newQuantity;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setIsModalOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageNavigate = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate("/Store");
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageIndividualNavigate = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate("/IndividualCard");
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [currentImage, setCurrentImage] = useState(imageUrl);
|
||||||
|
const [fade, setFade] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
changeImage(imageUrl);
|
||||||
|
}, [imageUrl]);
|
||||||
|
const changeImage = (newImage) => {
|
||||||
|
setFade(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCurrentImage(newImage);
|
||||||
|
setFade(true);
|
||||||
|
}, 300); // Duration of the fade-out effect
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{loading && <FullPageLoader />}
|
||||||
|
{isOpen && (
|
||||||
|
<div className="modal-overlay" onClick={closeModal2}>
|
||||||
|
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<button className="close-button" onClick={closeModal2}>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<img
|
||||||
|
className={`slider-image ${fade ? "fade-in" : "fade-out"}`}
|
||||||
|
src={imageUrl}
|
||||||
|
alt="large"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
Imagebackward();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-left-big"
|
||||||
|
>
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
ImageForwad();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-right-big"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div style={{ width: "inherit" }}>
|
||||||
|
<div className="ShopCard-Master">
|
||||||
|
<div
|
||||||
|
className="ShopCard-main"
|
||||||
|
key={id}
|
||||||
|
style={{ flexDirection: `${direction}` }}
|
||||||
|
>
|
||||||
|
{Type == "individualCard" ? (
|
||||||
|
<div className="ShopCard-img-parrent">
|
||||||
|
<div className="ShopCard-img">
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
Imagebackward();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-left"
|
||||||
|
>
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
width: imgwidth ? imgwidth : "",
|
||||||
|
height: imgheight ? imgheight : imgwidth ? imgwidth : "",
|
||||||
|
}}
|
||||||
|
// className={`slider-image ${fade ? "fade-in" : "fade-out"}`}
|
||||||
|
src={imageUrl}
|
||||||
|
alt={dishName}
|
||||||
|
onClick={
|
||||||
|
SingleImage == "Y" ? openModal2 : PageIndividualNavigate
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
ImageForwad();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-right"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isFavorite == "Y" && (
|
||||||
|
<p onClick={handleHeartClick}>
|
||||||
|
<HeartSvg
|
||||||
|
fillColor={fillColor}
|
||||||
|
strokeColor="gray"
|
||||||
|
height="20px"
|
||||||
|
width="20px"
|
||||||
|
position="absolute"
|
||||||
|
top="0"
|
||||||
|
left="-3"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{offer == "Y" && (
|
||||||
|
<span>{offerValue ? `${offerValue} % OFF` : ""}</span>
|
||||||
|
)}
|
||||||
|
{isVeg == "veg" && (
|
||||||
|
<div className="veg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#007E1C",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isNonVeg == "Y" && (
|
||||||
|
<div className="nonveg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#BD0606",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="ShopCard-img">
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
Imagebackward();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-left"
|
||||||
|
>
|
||||||
|
❮
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
width: imgwidth ? imgwidth : "",
|
||||||
|
height: imgheight ? imgheight : imgwidth ? imgwidth : "",
|
||||||
|
}}
|
||||||
|
className={`slider-image ${fade ? "fade-in" : "fade-out"}`}
|
||||||
|
src={imageUrl}
|
||||||
|
alt={dishName}
|
||||||
|
onClick={
|
||||||
|
SingleImage == "Y" ? openModal2 : PageIndividualNavigate
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{imageChangeButtons && (
|
||||||
|
<div style={{ position: "unset" }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
ImageForwad();
|
||||||
|
}}
|
||||||
|
className="Shopcard-carosel-right"
|
||||||
|
>
|
||||||
|
❯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isFavorite == "Y" && (
|
||||||
|
<p onClick={handleHeartClick}>
|
||||||
|
<HeartSvg
|
||||||
|
fillColor={fillColor}
|
||||||
|
strokeColor="gray"
|
||||||
|
height="20px"
|
||||||
|
width="20px"
|
||||||
|
position="absolute"
|
||||||
|
top="0"
|
||||||
|
left="-3"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{offer == "Y" && (
|
||||||
|
<span>{offerValue ? `${offerValue} % OFF` : ""}</span>
|
||||||
|
)}
|
||||||
|
{isVeg == "veg" && (
|
||||||
|
<div className="veg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#007E1C",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isNonVeg == "Y" && (
|
||||||
|
<div className="nonveg">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "#BD0606",
|
||||||
|
fontSize: "26px",
|
||||||
|
paddingBottom: "3px",
|
||||||
|
paddingRight: "1px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
●
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="ShopCard-details"
|
||||||
|
style={{
|
||||||
|
width:
|
||||||
|
direction == "row"
|
||||||
|
? ShopCardDetailswidth
|
||||||
|
? ShopCardDetailswidth
|
||||||
|
: "80vw"
|
||||||
|
: "",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{showQuantityModal == "Y" && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="add-quantity-modal">
|
||||||
|
400 g <RiArrowDownSFill size={18} />
|
||||||
|
</div>
|
||||||
|
{QuantityPrice && (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
color: "Green",
|
||||||
|
fontSize: "19px",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BiRupee size={17} style={{ marginRight: "-3px" }} />
|
||||||
|
{QuantityPrice}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ShopCard-review" style={{ fontSize: "12px" }}>
|
||||||
|
<p>
|
||||||
|
<AiFillStar color="#FF7A00" /> <span>4.5</span>
|
||||||
|
</p>
|
||||||
|
<div className="reviewHover">(1 Review)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{shopNameShow == "Y" && (
|
||||||
|
<div className="ShopCard-shopName" onClick={PageNavigate}>
|
||||||
|
{Type == "PozoCart" ? "From" : "Visit"} <CiShop size={15} />
|
||||||
|
<small className="scroll-shop">{shopName}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="ShopCard-dishName-review">
|
||||||
|
<div className="ShopCard-dishName">
|
||||||
|
<p
|
||||||
|
className="Shoopcard-productName"
|
||||||
|
style={{ paddingRight: "2rem !important" }}
|
||||||
|
>
|
||||||
|
{dishName}
|
||||||
|
</p>
|
||||||
|
{deliveryAvailable == "Y" && (
|
||||||
|
<div className="delivery">
|
||||||
|
<GiScooter size={18} style={{ marginBottom: "-3px" }} />{" "}
|
||||||
|
Delivery Available
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{ProductDescription == "Y" && (
|
||||||
|
<div>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontSize: "12px",
|
||||||
|
lineHeight: "1rem",
|
||||||
|
color: "#515151",
|
||||||
|
padding: "15px 10px 15px 0 ",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Bluetooth Soundbar w/ 500W RMS Signature Sound,5.1
|
||||||
|
Channel Surround Sound,BTv5.3, Wall Mountable
|
||||||
|
Design,Bass&Treble Controls&Master Remote
|
||||||
|
Control(Premium Black)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showCartShopName == "Y" && (
|
||||||
|
<div className="ShopCard-shopName2">
|
||||||
|
From <CiShop size={15} />
|
||||||
|
<small className="scroll-shop">{shopName}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{Accredited == "Y" && (
|
||||||
|
<div className="Accredited">
|
||||||
|
<img src={pozologoimg} alt="pozologoimg" width={40} />
|
||||||
|
<span>
|
||||||
|
{" "}
|
||||||
|
<HiOutlineBadgeCheck
|
||||||
|
color="white"
|
||||||
|
size={15}
|
||||||
|
style={{ marginBottom: "-4px" }}
|
||||||
|
/>
|
||||||
|
Accredited
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{InfoReview == "Y" && (
|
||||||
|
<div>
|
||||||
|
<div className="ShopCard-review">
|
||||||
|
<p>
|
||||||
|
<AiFillStar
|
||||||
|
style={{ fontSize: "20px" }}
|
||||||
|
color="#FF7A00"
|
||||||
|
/>{" "}
|
||||||
|
<span style={{ fontSize: "20px" }}>4.5</span>
|
||||||
|
</p>
|
||||||
|
<div className="reviewHover">(1 Review)</div>
|
||||||
|
<span className="review-modal">
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing
|
||||||
|
elit. At quas eius quaerat rerum, accusantium quis
|
||||||
|
maxime reiciendis
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="ShopCard-prize-btn">
|
||||||
|
{Type == "individualCard" && (
|
||||||
|
<div className="ShopCard-prize">
|
||||||
|
<div style={{ display: "flex", columnGap: "10px" }}>
|
||||||
|
{price && (
|
||||||
|
<p className="shopcard-price-p">
|
||||||
|
<BiRupee
|
||||||
|
size={13}
|
||||||
|
style={{
|
||||||
|
marginBottom: "2px",
|
||||||
|
marginRight: "-3px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{price}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{HomePrice && (
|
||||||
|
<p>
|
||||||
|
From{" "}
|
||||||
|
<BiRupee
|
||||||
|
size={16}
|
||||||
|
style={{
|
||||||
|
marginBottom: "-1px",
|
||||||
|
marginRight: "-3px",
|
||||||
|
}}
|
||||||
|
/>{" "}
|
||||||
|
{HomePrice} /-
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{CartMRP == "Y" && (
|
||||||
|
<span
|
||||||
|
className="shop-cart-mrp"
|
||||||
|
style={{ fontSize: "10px" }}
|
||||||
|
>
|
||||||
|
M.R.P.: <s>₹1,0099.00</s>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Cartoffer == "Y" && (
|
||||||
|
<span
|
||||||
|
className="shopcard-offertag"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#D42527",
|
||||||
|
borderRadius: "50px",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
padding: "5px 10px",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{offerValue ? `${offerValue} % OFF` : ""}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{youSave && (
|
||||||
|
<div className="you-save">You Save ₹{youSave}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deliveryTime && (
|
||||||
|
<div className="ShopCard-stopwatch">
|
||||||
|
<BiStopwatch size={16} /> {deliveryTime}{" "}
|
||||||
|
{deliveryDistance && " • " + deliveryDistance}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ShowPinCodecheck == "Y" && (
|
||||||
|
<div className="ShopCard-pincode">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "0.3rem",
|
||||||
|
backgroundColor: "#f4f4f4",
|
||||||
|
padding: "4px 10px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HiLocationMarker
|
||||||
|
style={{ color: "#E33333", fontSize: "20px" }}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
placeholder="Enter Pincode"
|
||||||
|
type="number"
|
||||||
|
maxLength={5}
|
||||||
|
style={{
|
||||||
|
width: "6rem",
|
||||||
|
outline: "none",
|
||||||
|
border: "none",
|
||||||
|
padding: "3px 0px",
|
||||||
|
backgroundColor: "#f4f4f4",
|
||||||
|
}}
|
||||||
|
onInput={(e) => {
|
||||||
|
if (e.target.value.length > 6) {
|
||||||
|
e.target.value = e.target.value.slice(0, 6);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p style={{ fontSize: "12px", cursor: "pointer" }}>
|
||||||
|
Check Delivery
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
rowGap: "2px",
|
||||||
|
marginTop: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{showSize == "Y" && (
|
||||||
|
<div className="size">
|
||||||
|
Size : <div> {Size}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showColor == "Y" && (
|
||||||
|
<div className="color">
|
||||||
|
Color : <div> {Color}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{Review == "Y" && (
|
||||||
|
<div className="ShopCard-review">
|
||||||
|
<p style={{ display: "flex" }}>
|
||||||
|
<AiFillStar color="#FF7A00" /> <span>4.5</span>
|
||||||
|
</p>
|
||||||
|
<div className="reviewHover">(1 Review)</div>
|
||||||
|
<span className="review-modal">
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
At quas eius quaerat rerum, accusantium quis maxime
|
||||||
|
reiciendis
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{cartSDS == "Y" && (
|
||||||
|
<div className="cart-sds">
|
||||||
|
<p>
|
||||||
|
<BiBookmark
|
||||||
|
size={14}
|
||||||
|
color="#1C1C1C"
|
||||||
|
style={{ marginBottom: "-2px" }}
|
||||||
|
/>{" "}
|
||||||
|
Save for later
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<RiDeleteBinLine
|
||||||
|
size={15}
|
||||||
|
style={{ marginBottom: "-2px" }}
|
||||||
|
/>{" "}
|
||||||
|
delete
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<TbShare3 size={15} style={{ marginBottom: "-2px" }} />{" "}
|
||||||
|
share
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{SDSIcon == "Y" && (
|
||||||
|
<div className="SDSIcon">
|
||||||
|
<p style={{ display: "flex", columnGap: "10px" }}>
|
||||||
|
<BiBookmark
|
||||||
|
size={20}
|
||||||
|
color="#1C1C1C"
|
||||||
|
style={{ marginBottom: "-2px", strokeWidth: "0.1" }}
|
||||||
|
/>
|
||||||
|
<RiDeleteBinLine
|
||||||
|
size={20}
|
||||||
|
strokeWidth={0.7}
|
||||||
|
style={{ marginBottom: "-2px", strokeWidth: "0.1" }}
|
||||||
|
/>
|
||||||
|
<TbShare3
|
||||||
|
className="share-icon"
|
||||||
|
size={30}
|
||||||
|
style={{ marginBottom: "-2px", strokeWidth: "0.7" }}
|
||||||
|
/>{" "}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="ShopCard-quantity-button">
|
||||||
|
{MRP && <s>M.R.P.:₹{MRP}</s>}
|
||||||
|
{Buy == "Y" && <p>BUY</p>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ShopCard-prize-btn">
|
||||||
|
{Type !== "individualCard" && (
|
||||||
|
<div className="ShopCard-prize">
|
||||||
|
<div style={{ display: 'flex', columnGap: "10px" }}>
|
||||||
|
{price && (
|
||||||
|
<p className="shopcard-price-p">
|
||||||
|
<BiRupee size={13} style={{ marginBottom: "2px", marginRight: "-3px" }} />{price}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{HomePrice && (
|
||||||
|
<p>
|
||||||
|
From <BiRupee size={16} style={{ marginBottom: "-1px", marginRight: "-3px" }} /> {HomePrice} /-
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/*================== cart MRP ============= */}
|
||||||
|
{CartMRP == "Y" && (
|
||||||
|
<span className="shop-cart-mrp" style={{ fontSize: "10px", }}>M.R.P.: <s>₹1,0099.00</s></span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Cartoffer == "Y" && (
|
||||||
|
<span
|
||||||
|
className="shopcard-offertag"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#D42527",
|
||||||
|
borderRadius: "50px",
|
||||||
|
color: "#FFFFFF",
|
||||||
|
padding: "5px 10px",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontFamily: "Gilroy"
|
||||||
|
}}>
|
||||||
|
{offerValue ? `${offerValue} % OFF` : ""}
|
||||||
|
</span>)}
|
||||||
|
{youSave && (
|
||||||
|
<div className="you-save">
|
||||||
|
You Save ₹{youSave}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deliveryTime && (
|
||||||
|
<div className="ShopCard-stopwatch">
|
||||||
|
<BiStopwatch size={16} /> {deliveryTime} {deliveryDistance && " • " + deliveryDistance}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
<div style={{ display: "flex" }}>
|
||||||
|
|
||||||
|
{deliveryStatus == "Y" && (
|
||||||
|
<div className="delivery-status">
|
||||||
|
<TbTruckDelivery
|
||||||
|
size={14}
|
||||||
|
style={{ marginBottom: "-3px" }}
|
||||||
|
/>
|
||||||
|
<span> DELIVERY </span>Free •{" "}
|
||||||
|
<span>6 | Jul | Saturday </span>
|
||||||
|
{" "}
|
||||||
|
<BsLightningChargeFill
|
||||||
|
color="#FA9600"
|
||||||
|
size={12}
|
||||||
|
style={{ marginBottom: "-2px" }}
|
||||||
|
/>
|
||||||
|
Fast • <span>Today</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="ShopCard-btn">
|
||||||
|
{showChangeQuantity == "Y" && (
|
||||||
|
<div className="add-quantity" onClick={openModal}>
|
||||||
|
400 g <RiArrowDownSFill size={18} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{buyNow == "Y" && <p className="buy-now">BUY NOW </p>}
|
||||||
|
{isVisible ? (
|
||||||
|
<div className="add-minus">
|
||||||
|
<span onClick={() => handleQuantityChange(-1)}>-</span>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontFamily: "Gilroy",
|
||||||
|
fontWeight: "600",
|
||||||
|
fontSize: "17px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{quantity}
|
||||||
|
</p>
|
||||||
|
<span onClick={() => handleQuantityChange(1)}>+</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
addToCartBtn == "Y" && (
|
||||||
|
<>
|
||||||
|
<div className="buy" onClick={handleAddToCartClick}>
|
||||||
|
Add to Cart
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalPozoPublic
|
||||||
|
onClose={closeModal}
|
||||||
|
width="700px"
|
||||||
|
height="400px"
|
||||||
|
maxWidth="90%"
|
||||||
|
maxHeight="90%"
|
||||||
|
top="auto"
|
||||||
|
right="auto"
|
||||||
|
left="auto"
|
||||||
|
bottom="auto"
|
||||||
|
closeIcon={<IoCloseSharp />}
|
||||||
|
title="Select your Quantity"
|
||||||
|
isOpen={isModalOpen}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{multiQty?.map((data) => (
|
||||||
|
<ShopCard
|
||||||
|
imageUrl={data.imageUrl}
|
||||||
|
Buy="Y"
|
||||||
|
isFavorite="Y"
|
||||||
|
offer="Y"
|
||||||
|
offerValue="30"
|
||||||
|
showQuantityModal="Y"
|
||||||
|
QuantityPrice="35.00"
|
||||||
|
isNonVeg={data?.continental == "NonVeg" && "Y"}
|
||||||
|
isVeg={data?.continental == "Veg" && "Y"}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ModalPozoPublic>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
// console.log(ShopCard.propTypes, "ShopCardShopCard");
|
||||||
|
ShopCard.propTypes = {
|
||||||
|
id: PropTypes.number.isRequired,
|
||||||
|
shopName: PropTypes.string.isRequired,
|
||||||
|
dishName: PropTypes.string.isRequired,
|
||||||
|
imageUrl: PropTypes.string.isRequired,
|
||||||
|
price: PropTypes.string.isRequired,
|
||||||
|
deliveryTime: PropTypes.string.isRequired,
|
||||||
|
deliveryDistance: PropTypes.string.isRequired,
|
||||||
|
direction: PropTypes.string.isRequired,
|
||||||
|
QuantityPrice: PropTypes.string.isRequired,
|
||||||
|
Color: PropTypes.string.isRequired,
|
||||||
|
Size: PropTypes.string.isRequired,
|
||||||
|
youSave: PropTypes.string.isRequired,
|
||||||
|
HomePrice: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
offer: PropTypes.bool,
|
||||||
|
isVeg: PropTypes.bool,
|
||||||
|
isNonVeg: PropTypes.bool,
|
||||||
|
isFavorite: PropTypes.bool,
|
||||||
|
addToCartBtn: PropTypes.bool,
|
||||||
|
showCartShopName: PropTypes.bool,
|
||||||
|
showQuantityModal: PropTypes.bool,
|
||||||
|
showChangeQuantity: PropTypes.bool,
|
||||||
|
deliveryAvailable: PropTypes.bool,
|
||||||
|
Buy: PropTypes.bool,
|
||||||
|
Review: PropTypes.bool,
|
||||||
|
buyNow: PropTypes.bool,
|
||||||
|
cartSDS: PropTypes.bool,
|
||||||
|
deliveryStatus: PropTypes.bool,
|
||||||
|
Cartoffer: PropTypes.bool,
|
||||||
|
shopNameShow: PropTypes.bool,
|
||||||
|
CartMRP: PropTypes.bool,
|
||||||
|
Accredited: PropTypes.bool,
|
||||||
|
showSize: PropTypes.bool,
|
||||||
|
showColor: PropTypes.bool,
|
||||||
|
youSave: PropTypes.bool,
|
||||||
|
SDSIcon: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
ShopCard.defaultProps = {
|
||||||
|
offer: true,
|
||||||
|
isVeg: false,
|
||||||
|
isNonVeg: false,
|
||||||
|
isFavorite: true,
|
||||||
|
addToCartBtn: true,
|
||||||
|
showCartShopName: true,
|
||||||
|
showQuantityModal: true,
|
||||||
|
showChangeQuantity: true,
|
||||||
|
deliveryAvailable: true,
|
||||||
|
Buy: true,
|
||||||
|
Review: true,
|
||||||
|
buyNow: true,
|
||||||
|
cartSDS: true,
|
||||||
|
deliveryStatus: true,
|
||||||
|
Cartoffer: true,
|
||||||
|
shopNameShow: true,
|
||||||
|
CartMRP: true,
|
||||||
|
Accredited: true,
|
||||||
|
showSize: true,
|
||||||
|
showColor: true,
|
||||||
|
SDSIcon: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShopCard;
|
||||||
|
|
@ -0,0 +1,683 @@
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import "../../Styles/Components/PozoCategory.scss";
|
||||||
|
import MobilePng from "../../Images/mobilepng.png";
|
||||||
|
|
||||||
|
const PozoCategory = () => {
|
||||||
|
const categories = [
|
||||||
|
{
|
||||||
|
"category": "Mobile & Accessories",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Mobile Phones",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Smartphones",
|
||||||
|
"products": ["iPhone 12", "Samsung Galaxy S21", "OnePlus 9"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Feature Phones",
|
||||||
|
"products": ["Nokia 3310", "Samsung Guru", "Micromax Joy"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Rugged Phones",
|
||||||
|
"products": ["CAT S62 Pro", "Ulefone Armor 9", "Doogee S96 Pro"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Foldable Phones",
|
||||||
|
"products": ["Samsung Galaxy Z Fold 2", "Huawei Mate Xs", "Motorola Razr"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mobile Accessories",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Chargers",
|
||||||
|
"products": ["Anker Charger", "Belkin Charger", "Apple MagSafe"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Cables",
|
||||||
|
"products": ["Anker Cable", "Belkin Cable", "Amazon Basics Cable"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Power Banks",
|
||||||
|
"products": ["Anker PowerCore", "Mi Power Bank", "RavPower Power Bank"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Headphones & Earphones",
|
||||||
|
"products": ["Sony WH-1000XM4", "Bose QC35", "Apple AirPods"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Cases & Covers",
|
||||||
|
"products": ["Spigen Case", "OtterBox Case", "Caseology Cover"]
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Furniture",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Living Room",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Sofas",
|
||||||
|
"products": ["Ikea Sofa", "Ashley Sofa", "West Elm Sofa"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Coffee Tables",
|
||||||
|
"products": ["Ikea Coffee Table", "West Elm Coffee Table", "Ashley Coffee Table"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "TV Stands",
|
||||||
|
"products": ["Ikea TV Stand", "Ashley TV Stand", "West Elm TV Stand"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Bookshelves",
|
||||||
|
"products": ["Ikea Bookshelf", "West Elm Bookshelf", "Ashley Bookshelf"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bedroom",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Beds",
|
||||||
|
"products": ["Ikea Bed", "Ashley Bed", "West Elm Bed"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Wardrobes",
|
||||||
|
"products": ["Ikea Wardrobe", "Ashley Wardrobe", "West Elm Wardrobe"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Dressers",
|
||||||
|
"products": ["Ikea Dresser", "Ashley Dresser", "West Elm Dresser"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Nightstands",
|
||||||
|
"products": ["Ikea Nightstand", "Ashley Nightstand", "West Elm Nightstand"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dining Room",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Dining Tables",
|
||||||
|
"products": ["Ikea Dining Table", "Ashley Dining Table", "West Elm Dining Table"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Dining Chairs",
|
||||||
|
"products": ["Ikea Dining Chair", "Ashley Dining Chair", "West Elm Dining Chair"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Sideboards",
|
||||||
|
"products": ["Ikea Sideboard", "Ashley Sideboard", "West Elm Sideboard"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Bar Stools",
|
||||||
|
"products": ["Ikea Bar Stool", "Ashley Bar Stool", "West Elm Bar Stool"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Office",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Desks",
|
||||||
|
"products": ["Ikea Desk", "Ashley Desk", "West Elm Desk"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Office Chairs",
|
||||||
|
"products": ["Ikea Office Chair", "Ashley Office Chair", "West Elm Office Chair"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "File Cabinets",
|
||||||
|
"products": ["Ikea File Cabinet", "Ashley File Cabinet", "West Elm File Cabinet"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Bookcases",
|
||||||
|
"products": ["Ikea Bookcase", "West Elm Bookcase", "Ashley Bookcase"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Outdoor",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Patio Furniture",
|
||||||
|
"products": ["Ikea Patio Furniture", "Ashley Patio Furniture", "West Elm Patio Furniture"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Garden Chairs",
|
||||||
|
"products": ["Ikea Garden Chair", "Ashley Garden Chair", "West Elm Garden Chair"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Outdoor Tables",
|
||||||
|
"products": ["Ikea Outdoor Table", "Ashley Outdoor Table", "West Elm Outdoor Table"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Hammocks",
|
||||||
|
"products": ["Ikea Hammock", "Ashley Hammock", "West Elm Hammock"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Healthcare & Pharma",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Medicines",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Prescription Medicines",
|
||||||
|
"products": ["Medicine A", "Medicine B", "Medicine C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Over-the-Counter Medicines",
|
||||||
|
"products": ["Medicine D", "Medicine E", "Medicine F"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Supplements",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Vitamins",
|
||||||
|
"products": ["Vitamin A", "Vitamin B", "Vitamin C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Minerals",
|
||||||
|
"products": ["Mineral A", "Mineral B", "Mineral C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Herbal Supplements",
|
||||||
|
"products": ["Herb A", "Herb B", "Herb C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Personal Care",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Skincare",
|
||||||
|
"products": ["Skincare Product A", "Skincare Product B", "Skincare Product C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Haircare",
|
||||||
|
"products": ["Haircare Product A", "Haircare Product B", "Haircare Product C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Oral Care",
|
||||||
|
"products": ["Oral Care Product A", "Oral Care Product B", "Oral Care Product C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Medical Devices",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Thermometers",
|
||||||
|
"products": ["Thermometer A", "Thermometer B", "Thermometer C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Blood Pressure Monitors",
|
||||||
|
"products": ["BP Monitor A", "BP Monitor B", "BP Monitor C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Glucose Monitors",
|
||||||
|
"products": ["Glucose Monitor A", "Glucose Monitor B", "Glucose Monitor C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Life Style & Fashion",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Clothing",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Men's Clothing",
|
||||||
|
"products": ["Men's Shirt A", "Men's Pants B", "Men's Jacket C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Women's Clothing",
|
||||||
|
"products": ["Women's Dress A", "Women's Top B", "Women's Skirt C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Children's Clothing",
|
||||||
|
"products": ["Children's Shirt A", "Children's Pants B", "Children's Jacket C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Footwear",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Men's Footwear",
|
||||||
|
"products": ["Men's Shoes A", "Men's Boots B", "Men's Sandals C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Women's Footwear",
|
||||||
|
"products": ["Women's Shoes A", "Women's Boots B", "Women's Sandals C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Children's Footwear",
|
||||||
|
"products": ["Children's Shoes A", "Children's Boots B", "Children's Sandals C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Accessories",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Watches",
|
||||||
|
"products": ["Watch A", "Watch B", "Watch C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Bags",
|
||||||
|
"products": ["Bag A", "Bag B", "Bag C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Jewelry",
|
||||||
|
"products": ["Jewelry A", "Jewelry B", "Jewelry C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Hats",
|
||||||
|
"products": ["Hat A", "Hat B", "Hat C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Restaurant",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Cuisine Type",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Italian",
|
||||||
|
"products": ["Dish A", "Dish B", "Dish C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Chinese",
|
||||||
|
"products": ["Dish D", "Dish E", "Dish F"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Indian",
|
||||||
|
"products": ["Dish G", "Dish H", "Dish I"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Mexican",
|
||||||
|
"products": ["Dish J", "Dish K", "Dish L"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dining Experience",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Fine Dining",
|
||||||
|
"products": ["Restaurant A", "Restaurant B", "Restaurant C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Casual Dining",
|
||||||
|
"products": ["Restaurant D", "Restaurant E", "Restaurant F"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Fast Food",
|
||||||
|
"products": ["Restaurant G", "Restaurant H", "Restaurant I"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Cafes",
|
||||||
|
"products": ["Cafe A", "Cafe B", "Cafe C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Special Services",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Takeout",
|
||||||
|
"products": ["Takeout Service A", "Takeout Service B", "Takeout Service C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Delivery",
|
||||||
|
"products": ["Delivery Service A", "Delivery Service B", "Delivery Service C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Catering",
|
||||||
|
"products": ["Catering Service A", "Catering Service B", "Catering Service C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Bakery",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Bakery Products",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Bread",
|
||||||
|
"products": ["Bread A", "Bread B", "Bread C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Cakes",
|
||||||
|
"products": ["Cake A", "Cake B", "Cake C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Cookies",
|
||||||
|
"products": ["Cookie A", "Cookie B", "Cookie C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Pastries",
|
||||||
|
"products": ["Pastry A", "Pastry B", "Pastry C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Specialty Items",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Gluten-Free",
|
||||||
|
"products": ["Gluten-Free Item A", "Gluten-Free Item B", "Gluten-Free Item C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Vegan",
|
||||||
|
"products": ["Vegan Item A", "Vegan Item B", "Vegan Item C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Sugar-Free",
|
||||||
|
"products": ["Sugar-Free Item A", "Sugar-Free Item B", "Sugar-Free Item C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Beverages",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Coffee",
|
||||||
|
"products": ["Coffee A", "Coffee B", "Coffee C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Tea",
|
||||||
|
"products": ["Tea A", "Tea B", "Tea C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Juices",
|
||||||
|
"products": ["Juice A", "Juice B", "Juice C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "Toys & Gifts",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Toys",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Educational Toys",
|
||||||
|
"products": ["Toy A", "Toy B", "Toy C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Action Figures",
|
||||||
|
"products": ["Action Figure A", "Action Figure B", "Action Figure C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Dolls",
|
||||||
|
"products": ["Doll A", "Doll B", "Doll C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Board Games",
|
||||||
|
"products": ["Board Game A", "Board Game B", "Board Game C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gifts",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Gift Cards",
|
||||||
|
"products": ["Gift Card A", "Gift Card B", "Gift Card C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Personalized Gifts",
|
||||||
|
"products": ["Personalized Gift A", "Personalized Gift B", "Personalized Gift C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Gift Baskets",
|
||||||
|
"products": ["Gift Basket A", "Gift Basket B", "Gift Basket C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Flowers",
|
||||||
|
"products": ["Flower A", "Flower B", "Flower C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "HARDWARES",
|
||||||
|
"subcategories": [
|
||||||
|
{
|
||||||
|
"name": "Tools",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Hand Tools",
|
||||||
|
"products": ["Hand Tool A", "Hand Tool B", "Hand Tool C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Power Tools",
|
||||||
|
"products": ["Power Tool A", "Power Tool B", "Power Tool C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Garden Tools",
|
||||||
|
"products": ["Garden Tool A", "Garden Tool B", "Garden Tool C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Building Materials",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Lumber",
|
||||||
|
"products": ["Lumber A", "Lumber B", "Lumber C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Concrete",
|
||||||
|
"products": ["Concrete A", "Concrete B", "Concrete C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Roofing",
|
||||||
|
"products": ["Roofing A", "Roofing B", "Roofing C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Paint",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"typesName": "Interior Paint",
|
||||||
|
"products": ["Interior Paint A", "Interior Paint B", "Interior Paint C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Exterior Paint",
|
||||||
|
"products": ["Exterior Paint A", "Exterior Paint B", "Exterior Paint C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Primers",
|
||||||
|
"products": ["Primer A", "Primer B", "Primer C"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"typesName": "Spray Paint",
|
||||||
|
"products": ["Spray Paint A", "Spray Paint B", "Spray Paint C"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const scrollContainerRef = useRef(null);
|
||||||
|
const isDownRef = useRef(false);
|
||||||
|
const startXRef = useRef(0);
|
||||||
|
const scrollLeftRef = useRef(0);
|
||||||
|
const [hovered, setHovered] = useState(false);
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState(null);
|
||||||
|
const [clientWidth, setClientWidth] = useState(0);
|
||||||
|
const category = categories.find(c => c.category === selectedCategory);
|
||||||
|
const subcategories = category?.subcategories || [];
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const updateClientWidth = () => {
|
||||||
|
if (scrollContainerRef.current) {
|
||||||
|
setClientWidth(scrollContainerRef.current.clientWidth);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateClientWidth();
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
|
updateClientWidth();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (scrollContainerRef.current) {
|
||||||
|
resizeObserver.observe(scrollContainerRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (scrollContainerRef.current) {
|
||||||
|
resizeObserver.unobserve(scrollContainerRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
const handleMouseDown = (event) => {
|
||||||
|
isDownRef.current = true;
|
||||||
|
startXRef.current = event.pageX - scrollContainerRef.current.offsetLeft;
|
||||||
|
scrollLeftRef.current = scrollContainerRef.current.scrollLeft;
|
||||||
|
scrollContainerRef.current.style.cursor = "grabbing";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
isDownRef.current = false;
|
||||||
|
scrollContainerRef.current.style.cursor = "grab";
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
isDownRef.current = false;
|
||||||
|
scrollContainerRef.current.style.cursor = "grab";
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseMove = (event) => {
|
||||||
|
if (!isDownRef.current) return;
|
||||||
|
event.preventDefault();
|
||||||
|
const x = event.pageX - scrollContainerRef.current.offsetLeft;
|
||||||
|
const walk = (x - startXRef.current) * 1; // Scroll-fast
|
||||||
|
scrollContainerRef.current.scrollLeft = scrollLeftRef.current - walk;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const OnchangeCategoryHover = (event) => {
|
||||||
|
setHovered(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCategoryClick = (categoryName) => {
|
||||||
|
|
||||||
|
if (clientWidth >= 768) {
|
||||||
|
setSelectedCategory(categoryName);
|
||||||
|
} else {
|
||||||
|
// Based On categoryName API Call For Mobile Screen and redirection for the page
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const categoryimages = [
|
||||||
|
MobilePng,
|
||||||
|
"https://img.freepik.com/premium-photo/retro-vinyl-club-chair-vibrant-yellow-color-isolated-solid-white-background_943617-35916.jpg?ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
"https://img.freepik.com/premium-photo/brown-medical-bottles-pills-isolated-white-background_185193-8416.jpg?ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
"https://img.freepik.com/free-photo/top-view-clothing_1203-8177.jpg?size=626&ext=jpg&ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
"https://img.freepik.com/free-photo/view-building-with-cartoon-style-architecture_23-2151154879.jpg?ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
"https://img.freepik.com/premium-photo/basket-full-baked-delights-generative-ai_356545-457.jpg?ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
"https://img.freepik.com/premium-photo/toy-bear-present-box-red-bow-isolated-white-birthday-christmas-holiday-party-celebration_474717-7138.jpg?ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
"https://img.freepik.com/premium-photo/heap-computer-hardware-isolated-white_266732-23923.jpg?ga=GA1.1.1052249002.1710723563&semt=ais_user",
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: 'relative', zIndex: "3", top: "0rem" }}>
|
||||||
|
|
||||||
|
|
||||||
|
{clientWidth >= 768 && < div
|
||||||
|
className="Cascading-Div"
|
||||||
|
onMouseEnter={() => { OnchangeCategoryHover(true) }}
|
||||||
|
onMouseLeave={() => { OnchangeCategoryHover(false) }}
|
||||||
|
style={hovered ? { display: "flex" } : { display: "none" }}
|
||||||
|
>
|
||||||
|
{subcategories?.map((item, idx) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<div>{item.name}</div>
|
||||||
|
{item.types?.map((sub, sIdx) => (<div key={sIdx}>{sub.typesName}</div>))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>}
|
||||||
|
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="PozoCategory-master-div"
|
||||||
|
ref={scrollContainerRef}
|
||||||
|
onMouseDown={handleMouseDown}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
onMouseUp={handleMouseUp}
|
||||||
|
onMouseMove={handleMouseMove}>
|
||||||
|
<div className="PozoCategory-datas">
|
||||||
|
{categories.map((cat, index) => (
|
||||||
|
<div
|
||||||
|
key={cat.category}
|
||||||
|
className="PozoCategory-name"
|
||||||
|
style={
|
||||||
|
hovered && cat.category === selectedCategory
|
||||||
|
? { borderBottom: "3px solid #E33333" }
|
||||||
|
: { borderBottom: "3px solid #fff" }
|
||||||
|
|
||||||
|
}
|
||||||
|
onMouseEnter={() => { OnchangeCategoryHover(true), handleCategoryClick(cat.category) }}
|
||||||
|
onMouseLeave={() => { OnchangeCategoryHover(false) }}
|
||||||
|
|
||||||
|
>
|
||||||
|
<div className="CategoryVariants" >
|
||||||
|
<div style={{ display: "flex", flexDirection: 'column', rowGap: "5px" }}>
|
||||||
|
{clientWidth < 768 &&
|
||||||
|
|
||||||
|
<div className="CategoryVariantsImage">
|
||||||
|
<img src={categoryimages[index]} width={100} height={100} />
|
||||||
|
</div>}
|
||||||
|
<div> {cat.category}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoCategory;
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import React from 'react'
|
||||||
|
import "./PozoPublicFooter.scss"
|
||||||
|
import pozologo from "../../Images/PozoStore.svg"
|
||||||
|
import playstoreIcon from "../../Images/playstore.png"
|
||||||
|
import applestoreIcon from "../../Images/applestore.png"
|
||||||
|
import { IoIosHelpCircleOutline, IoLogoLinkedin } from 'react-icons/io'
|
||||||
|
import { FaInstagramSquare } from 'react-icons/fa'
|
||||||
|
import { FaFacebook, FaXTwitter, FaYoutube } from 'react-icons/fa6'
|
||||||
|
import { PiShootingStar, PiStorefront } from 'react-icons/pi'
|
||||||
|
import { GoGift } from 'react-icons/go'
|
||||||
|
|
||||||
|
const PozoPublicFooter = () => {
|
||||||
|
return (
|
||||||
|
<div className='PozoPublicFooter-master'>
|
||||||
|
<div className="PozoPublicFooter-container">
|
||||||
|
<div className='PozoPublicFooter-img-div'>
|
||||||
|
<img src={pozologo} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className='PozoPublicFooter-content'>
|
||||||
|
<div>
|
||||||
|
<p className='PozoPublicFooter-content-header'>ABOUT </p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Contact Us</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>About Us</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Pozo Stories</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Press</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className='PozoPublicFooter-content-header'>Help </p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Track Your Order</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Warranty & Support</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Return Policy</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Service Centers</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Bulk Orders</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Why Buy Direct</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className='PozoPublicFooter-content-header'>LEARN MORE </p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Privacy</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Security</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Terms</p>
|
||||||
|
<p className='PozoPublicFooter-content-data'>Sitemap</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className='PozoPublicFooter-content-header'>SOCIAL MEDIA </p>
|
||||||
|
<div className='PozoPublicFooter-socialmedia-icons'>
|
||||||
|
<IoLogoLinkedin size={24} />
|
||||||
|
<FaInstagramSquare size={20} />
|
||||||
|
<FaXTwitter size={20} />
|
||||||
|
<FaYoutube size={24} />
|
||||||
|
<FaFacebook size={20} />
|
||||||
|
</div>
|
||||||
|
<div className='PozoPublicFooter-download-options'>
|
||||||
|
<div className='PozoPublicFooter-download-div'>
|
||||||
|
<img src={playstoreIcon} alt="" />
|
||||||
|
<p className='PozoPublicFooter-content-data'>Play Store</p>
|
||||||
|
</div>
|
||||||
|
<div className='PozoPublicFooter-download-div'>
|
||||||
|
<img src={applestoreIcon} alt="" />
|
||||||
|
<p className='PozoPublicFooter-content-data'>App Store</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="PozoPublicFooter-copyrights">
|
||||||
|
<div className="extera-option-container">
|
||||||
|
<div className='extera-option'>
|
||||||
|
<PiStorefront />
|
||||||
|
<p className='PozoPublicFooter-content-data'>Become a Seller</p>
|
||||||
|
</div>
|
||||||
|
<div className='extera-option'>
|
||||||
|
<PiShootingStar />
|
||||||
|
<p className='PozoPublicFooter-content-data'>Advertise</p>
|
||||||
|
</div>
|
||||||
|
<div className='extera-option'>
|
||||||
|
<GoGift />
|
||||||
|
<p className='PozoPublicFooter-content-data'>Become a Seller</p>
|
||||||
|
</div>
|
||||||
|
<div className='extera-option'>
|
||||||
|
<IoIosHelpCircleOutline />
|
||||||
|
<p className='PozoPublicFooter-content-data'>Become a Seller</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr style={{ width: "90%", margin: "auto" }} />
|
||||||
|
<p className='PozoPublicFooter-copyrights-text'> <span>@</span>copyright 2021, rights reserved</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicFooter
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
.PozoPublicFooter-master {
|
||||||
|
width: 100vw;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-container {
|
||||||
|
display: flex;
|
||||||
|
background-color: #F0F5FF;
|
||||||
|
// height: 40vh;
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding: 2rem 2rem 1rem 2rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-img-div {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-img-div img {
|
||||||
|
width: 7rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-content {
|
||||||
|
display: flex;
|
||||||
|
width: 80%;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1.5rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-content-header {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
padding-bottom: 0.8rem;
|
||||||
|
// color: #000001C1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-content-data {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 3px 0;
|
||||||
|
color: #000001C1;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-socialmedia-icons {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 15px;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-download-options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-download-div {
|
||||||
|
display: flex;
|
||||||
|
// border: 1px solid #000001C1;
|
||||||
|
padding: 7px 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 5px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-download-options div img {
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-copyrights {
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
background-color: #F0F5FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extera-option-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
column-gap: 2rem;
|
||||||
|
row-gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extera-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-copyrights-text {
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 1rem 0 0 0;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width:768px) {
|
||||||
|
.PozoPublicFooter-content {
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-master {
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
padding-bottom: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-container {
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-content-header {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-content-data {
|
||||||
|
font-size: 11.5px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-copyrights-text {
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-download-options {
|
||||||
|
flex-direction: row;
|
||||||
|
column-gap: 1rem;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-download-div {
|
||||||
|
width: max-content;
|
||||||
|
|
||||||
|
padding: 3px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicFooter-download-div .PozoPublicFooter-content-data {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,699 @@
|
||||||
|
import { MdOutlineWatchLater } from "react-icons/md";
|
||||||
|
import { FiSearch } from "react-icons/fi";
|
||||||
|
import { IoIosArrowDown, IoMdClose } from "react-icons/io";
|
||||||
|
import { MdOutlineMyLocation } from "react-icons/md";
|
||||||
|
import { AiOutlineClose } from "react-icons/ai";
|
||||||
|
import { useState, useEffect, useRef } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
|
import pozologo from "../../Images/PozoStore.svg";
|
||||||
|
import { HiLocationMarker } from "react-icons/hi";
|
||||||
|
import {
|
||||||
|
PiShoppingCartLight,
|
||||||
|
PiStorefrontLight,
|
||||||
|
PiUserCircleLight,
|
||||||
|
} from "react-icons/pi";
|
||||||
|
import { FaChevronDown } from "react-icons/fa6";
|
||||||
|
import { GoHeart } from "react-icons/go";
|
||||||
|
import { RxHamburgerMenu } from "react-icons/rx";
|
||||||
|
import "../../Styles/HomePage/PozoPublicNavbar.scss";
|
||||||
|
|
||||||
|
import PozoPublicSearch from "./PozoPublicSearch/PozoPublicSearch";
|
||||||
|
import { CiViewList } from "react-icons/ci";
|
||||||
|
import FullPageLoader from "../Loader/PozoPublicLoader";
|
||||||
|
import samplepic from "../../Images/Restaurant.png";
|
||||||
|
import { LuChevronDownCircle, LuChevronUpCircle } from "react-icons/lu";
|
||||||
|
import { breadCrumbSelector, changeBreadCrumb } from "../../Features/LandingPage/landingPage";
|
||||||
|
const subDirectory = import.meta.env.BASE_URL;
|
||||||
|
|
||||||
|
const PozoPublicNavbar = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [Searchquery, setSearchquery] = useState('');
|
||||||
|
const breadCrumb = useSelector(breadCrumbSelector);
|
||||||
|
const dropdownRef = useRef(null);
|
||||||
|
const ref = useRef(null);
|
||||||
|
const PageName = breadCrumb?.[breadCrumb.length - 1]?.name
|
||||||
|
const [profile, setProfile] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||||
|
const [isCollapsedbook, setIsCollapsedbook] = useState(true);
|
||||||
|
const [sidedrawer, setSidedrawer] = useState(true);
|
||||||
|
const [locationDropdown, setLocationDropdown] = useState(false);
|
||||||
|
const [dropdownClosing, setDropdownClosing] = useState(false);
|
||||||
|
const [showLocationList, setShowLocationList] = useState(false);
|
||||||
|
const [Locationdata, setLocationdata] = useState([]);
|
||||||
|
const [currentLocation, setCurrentLocation] = useState(
|
||||||
|
localStorage.getItem("currentLocation") || "Hosur,, PRPH+33F, Hamumanth..."
|
||||||
|
);
|
||||||
|
|
||||||
|
const selectLocation = (locName) => {
|
||||||
|
if (locName) {
|
||||||
|
setCurrentLocation(locName);
|
||||||
|
localStorage.setItem("currentLocation", locName);
|
||||||
|
}
|
||||||
|
toggleLocationDropdown();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTrackCurrentLocation = () => {
|
||||||
|
if (navigator.geolocation) {
|
||||||
|
setCurrentLocation("Detecting location...");
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
async (position) => {
|
||||||
|
const { latitude, longitude } = position.coords;
|
||||||
|
try {
|
||||||
|
const res = await fetch(
|
||||||
|
`https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json`
|
||||||
|
);
|
||||||
|
const data = await res.json();
|
||||||
|
if (data && data.display_name) {
|
||||||
|
const address = data.display_name;
|
||||||
|
setCurrentLocation(address);
|
||||||
|
localStorage.setItem("currentLocation", address);
|
||||||
|
} else {
|
||||||
|
const fallback = `${latitude.toFixed(4)}, ${longitude.toFixed(4)}`;
|
||||||
|
setCurrentLocation(fallback);
|
||||||
|
localStorage.setItem("currentLocation", fallback);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Reverse geocoding error:", err);
|
||||||
|
const fallback = `Lat: ${latitude.toFixed(2)}, Lon: ${longitude.toFixed(2)}`;
|
||||||
|
setCurrentLocation(fallback);
|
||||||
|
localStorage.setItem("currentLocation", fallback);
|
||||||
|
}
|
||||||
|
if (locationDropdown) {
|
||||||
|
toggleLocationDropdown();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error("Geolocation error:", error);
|
||||||
|
alert("Location permission denied. Please allow location access in your browser.");
|
||||||
|
setCurrentLocation(localStorage.getItem("currentLocation") || "Hosur,, PRPH+33F, Hamumanth...");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
alert("Geolocation is not supported by your browser.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const GotoHomepage = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toSignIn = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/signin`);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
const toMyProfile = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "My Profile",
|
||||||
|
link: `${subDirectory}app-page/myprofile`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/myprofile`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toFavOrder = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "My Orders",
|
||||||
|
link: `${subDirectory}app-page/order`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/order`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toFavShop = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fav Shop",
|
||||||
|
link: `${subDirectory}app-page/favshop`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/favshop`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toFavList = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Favourite List",
|
||||||
|
link: `${subDirectory}app-page/favlist`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/favlist`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toStore = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Stores",
|
||||||
|
link: `${subDirectory}app-page/Stores`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/Stores`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigatetoCart = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: `${subDirectory}app-page`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Cart",
|
||||||
|
link: `${subDirectory}app-page/cart`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`${subDirectory}app-page/cart`);
|
||||||
|
dispatch(changeBreadCrumb({ items: items }));
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (Searchquery.length > 0) {
|
||||||
|
setShowLocationList(true)
|
||||||
|
}
|
||||||
|
else if (Searchquery.length == 0) {
|
||||||
|
setShowLocationList(false)
|
||||||
|
}
|
||||||
|
}, [Searchquery])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (ref.current && !ref.current.contains(event.target)) {
|
||||||
|
setProfile(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handleClickOutside);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleLoginClick = () => {
|
||||||
|
setProfile(!profile);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleCollapse = () => {
|
||||||
|
setIsCollapsed(!isCollapsed);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleCollapsebook = () => {
|
||||||
|
setIsCollapsedbook(!isCollapsedbook);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleHamburger = () => {
|
||||||
|
setSidedrawer(!sidedrawer);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInputClick = () => {
|
||||||
|
setShowLocationList((prevShowLocationList) => !prevShowLocationList);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmitLocation = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!Searchquery.trim()) return;
|
||||||
|
|
||||||
|
let items = JSON.parse(localStorage.getItem('Locationdata')) || [];
|
||||||
|
|
||||||
|
const isDuplicate = items.some(item => item.ShopLocation.toLowerCase() === Searchquery.trim().toLowerCase());
|
||||||
|
|
||||||
|
if (!isDuplicate) {
|
||||||
|
items.push({ ShopLocation: Searchquery.trim() });
|
||||||
|
localStorage.setItem('Locationdata', JSON.stringify(items));
|
||||||
|
}
|
||||||
|
|
||||||
|
setLocationdata(items);
|
||||||
|
setSearchquery('');
|
||||||
|
setShowLocationList(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let items = JSON.parse(localStorage.getItem('Locationdata')) || [];
|
||||||
|
setLocationdata(items);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const deleteRecentSearch = (locationToDelete) => {
|
||||||
|
let items = JSON.parse(localStorage.getItem('Locationdata')) || [];
|
||||||
|
const updatedItems = items.filter(item => item.ShopLocation !== locationToDelete);
|
||||||
|
localStorage.setItem('Locationdata', JSON.stringify(updatedItems));
|
||||||
|
setLocationdata(updatedItems);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setSearchquery(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleLocationDropdown = () => {
|
||||||
|
if (locationDropdown) {
|
||||||
|
setDropdownClosing(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLocationDropdown(false);
|
||||||
|
setDropdownClosing(false);
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
setLocationDropdown(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
||||||
|
setDropdownClosing(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setLocationDropdown(false);
|
||||||
|
setDropdownClosing(false);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (locationDropdown) {
|
||||||
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
|
} else {
|
||||||
|
document.removeEventListener("mousedown", handleClickOutside);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [locationDropdown]);
|
||||||
|
|
||||||
|
const handlerSearchFuntion = () => {
|
||||||
|
if (!Searchquery.trim()) return;
|
||||||
|
|
||||||
|
let items = JSON.parse(localStorage.getItem('Locationdata')) || [];
|
||||||
|
|
||||||
|
const isDuplicate = items.some(item => item.ShopLocation.toLowerCase() === Searchquery.trim().toLowerCase());
|
||||||
|
|
||||||
|
if (!isDuplicate) {
|
||||||
|
items.push({ ShopLocation: Searchquery.trim() });
|
||||||
|
localStorage.setItem('Locationdata', JSON.stringify(items));
|
||||||
|
}
|
||||||
|
|
||||||
|
setLocationdata(items);
|
||||||
|
setSearchquery('');
|
||||||
|
setShowLocationList(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const StoreLocation = [
|
||||||
|
{ ShopLocationName: "Pochampalli" },
|
||||||
|
{ ShopLocationName: "Hosur" },
|
||||||
|
{ ShopLocationName: "Mathur" },
|
||||||
|
{ ShopLocationName: "Dharmapuri" },
|
||||||
|
{ ShopLocationName: "Coimbatore" },
|
||||||
|
{ ShopLocationName: "Salem" },
|
||||||
|
{ ShopLocationName: "Chennai" },
|
||||||
|
{ ShopLocationName: "Namakkal" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const ShopLocationLists = [
|
||||||
|
{ location: "Hosur" },
|
||||||
|
{ location: "Pochampalli" },
|
||||||
|
{ location: "Mathur" },
|
||||||
|
{ location: "Dharmapuri" },
|
||||||
|
{ location: "Coimbatore" },
|
||||||
|
{ location: "Salem" },
|
||||||
|
{ location: "Chennai" },
|
||||||
|
{ location: "Namakkal" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const filteredData2 = Array.isArray(ShopLocationLists)
|
||||||
|
? ShopLocationLists?.filter((item) => item?.location?.toLowerCase()?.includes(Searchquery?.toLowerCase()))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="PozoPublicNavbarMaster">
|
||||||
|
{loading && <FullPageLoader />}
|
||||||
|
|
||||||
|
<div className="PozoPublicNavbar">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
columnGap: "1.5rem",
|
||||||
|
fontSize: "22px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RxHamburgerMenu
|
||||||
|
className="hambicon"
|
||||||
|
onClick={toggleHamburger}
|
||||||
|
style={{ position: "relative" }}
|
||||||
|
/>
|
||||||
|
<img src={pozologo} alt="pozologo" onClick={GotoHomepage} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Collapse Menu code area */}
|
||||||
|
{!sidedrawer && (
|
||||||
|
<div className="CollapseMenu">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="CollapseMenu-header">
|
||||||
|
<div className="CollapseMenu-user">
|
||||||
|
<PiUserCircleLight size={38} />
|
||||||
|
<div>
|
||||||
|
<div className="CollapseMenu-username">Hello, Guest</div>
|
||||||
|
<div className="CollapseMenu-subtext">Sign in to your account</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="CollapseMenu-close" onClick={toggleHamburger}>
|
||||||
|
<AiOutlineClose size={14} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="CollapseMenu-divider" />
|
||||||
|
|
||||||
|
<div className="collapse-button" onClick={toggleCollapse}>
|
||||||
|
Categories
|
||||||
|
{isCollapsed ? <LuChevronUpCircle style={{ strokeWidth: "1.5" }} /> : <LuChevronDownCircle style={{ strokeWidth: "1.5" }} />}
|
||||||
|
</div>
|
||||||
|
<div className={`collapse ${isCollapsed ? "collapsed" : "expanded"}`}>
|
||||||
|
<div className="sidedrawer-content">
|
||||||
|
{["Restaurant", "Electrical, Electronic & Computers", "Bakery", "Groceries", "Lifestyle & Fashion", "Medicines & Pharma equips", "Dairy Delights"].map((cat, idx) => (
|
||||||
|
<div className="sidedrawer-direct" key={idx}>
|
||||||
|
<img src={samplepic} alt={cat} />
|
||||||
|
<p>{cat}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="CollapseMenu-divider" />
|
||||||
|
|
||||||
|
{/* Booking */}
|
||||||
|
<div className="collapse-button" onClick={toggleCollapsebook}>
|
||||||
|
Booking
|
||||||
|
{isCollapsedbook ? <LuChevronUpCircle style={{ strokeWidth: "1.5" }} /> : <LuChevronDownCircle style={{ strokeWidth: "1.5" }} />}
|
||||||
|
</div>
|
||||||
|
<div className={`collapse ${isCollapsedbook ? "collapsed" : "expanded"}`}>
|
||||||
|
<div className="sidedrawer-content">
|
||||||
|
{["Restaurant", "Electrical, Electronic & Computers"].map((cat, idx) => (
|
||||||
|
<div className="sidedrawer-direct" key={idx}>
|
||||||
|
<img src={samplepic} alt={cat} />
|
||||||
|
<p>{cat}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="CollapseMenu-divider" />
|
||||||
|
|
||||||
|
{/* Quick Links */}
|
||||||
|
<div className="trackMyOrder" onClick={toStore}>Stores</div>
|
||||||
|
<div className="trackMyOrder" onClick={toFavList}>Favourite List</div>
|
||||||
|
<div className="trackMyOrder">Track My Order</div>
|
||||||
|
|
||||||
|
<div className="CollapseMenu-divider" />
|
||||||
|
|
||||||
|
{/* Login Button */}
|
||||||
|
<div className="CollapseMenu-loginbtn" onClick={toSignIn}>Login / Sign Up</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{PageName != "checkout" && <div className="searchbar">
|
||||||
|
<div>
|
||||||
|
<div className="locatmark" onClick={toggleLocationDropdown}>
|
||||||
|
<HiLocationMarker style={{ color: "#E33333", fontSize: "25px", flexShrink: 0 }} />
|
||||||
|
<div className="location-text-group">
|
||||||
|
<div className="location-main-title">
|
||||||
|
Location <FaChevronDown style={{ fontSize: "10px", marginLeft: "4px", color: "#666" }} />
|
||||||
|
</div>
|
||||||
|
<div className="location-sub-text" title={currentLocation}>
|
||||||
|
{currentLocation}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{locationDropdown && (
|
||||||
|
<div
|
||||||
|
className={`location-dropdown ${dropdownClosing ? "closing" : ""}`}
|
||||||
|
ref={dropdownRef}>
|
||||||
|
|
||||||
|
<div className="locationSearch">
|
||||||
|
<p className="locationTitle"> Select Delivery location <span>
|
||||||
|
<IoMdClose onClick={toggleLocationDropdown} style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
backgroundColor: "#f0f5ff",
|
||||||
|
height: "18px",
|
||||||
|
width: "18px"
|
||||||
|
}} />
|
||||||
|
</span></p>
|
||||||
|
|
||||||
|
{/* SEARCH INPUT FOR LOCATION */}
|
||||||
|
<div className="serachMap">
|
||||||
|
<form style={{
|
||||||
|
width: "100%",
|
||||||
|
padding: "0px 5px",
|
||||||
|
borderRadius: "6px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
backgroundColor: "#F0F5FF",
|
||||||
|
}} className="search-bar" onSubmit={handleSubmitLocation}>
|
||||||
|
<FiSearch color="rgb(227,51,51)" />
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={Searchquery}
|
||||||
|
onChange={handleChange}
|
||||||
|
onClick={handleInputClick}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter")
|
||||||
|
handlerSearchFuntion();
|
||||||
|
}}
|
||||||
|
placeholder="Search Your Location..."
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* location list in search bar */}
|
||||||
|
{showLocationList && (
|
||||||
|
<div className="locationListDropDown">
|
||||||
|
{filteredData2.length > 0 ? filteredData2.map((item, idx) =>
|
||||||
|
(
|
||||||
|
<div className="locationList" key={idx} onClick={() => selectLocation(item?.location)}>
|
||||||
|
{item?.location}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
: <p>Location Not Found</p>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
{/* DETECT CURRENT LOCATION */}
|
||||||
|
<div className="DetectLocation" onClick={handleTrackCurrentLocation}>
|
||||||
|
<span>
|
||||||
|
<MdOutlineMyLocation size={15} /> Track Current Location
|
||||||
|
</span>
|
||||||
|
<div>Using ( GPS )</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{/* STORE LOCATION CODE AREA */}
|
||||||
|
<div className="StoreLocationHeader">
|
||||||
|
<p> # Store Location</p>
|
||||||
|
<span> <IoIosArrowDown size={16} /></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="StoreLocationMain">
|
||||||
|
{StoreLocation.map((e, idx) => {
|
||||||
|
return (
|
||||||
|
<div className="ShopLocationName" key={idx} onClick={() => selectLocation(e?.ShopLocationName)}>
|
||||||
|
<span><HiLocationMarker size={15} color="rgb(227,51,51)" /></span>
|
||||||
|
<div>
|
||||||
|
{e?.ShopLocationName}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RECENT LOCATION CODE HERE */}
|
||||||
|
<div className="RecentLocation">
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: "#FFF", width: "100%",
|
||||||
|
position: "sticky", top: "0", padding: "5px 0px"
|
||||||
|
}}>
|
||||||
|
<p style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: "2px 5px ",
|
||||||
|
columnGap: "5px"
|
||||||
|
}}>
|
||||||
|
<MdOutlineWatchLater size={14} /> Recent Search</p>
|
||||||
|
</div>
|
||||||
|
{(Locationdata?.map((e, idx) => (
|
||||||
|
<div className="RecentLocation-Area" key={idx} onClick={() => selectLocation(e?.ShopLocation)}>
|
||||||
|
<div>
|
||||||
|
<p style={{
|
||||||
|
borderRadius: "4px", padding: "2px 10px",
|
||||||
|
backgroundColor: "rgb(255, 240, 240)",
|
||||||
|
color: "rgb(227,51,51)"
|
||||||
|
}}>
|
||||||
|
{e?.ShopLocation}
|
||||||
|
<span
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
deleteRecentSearch(e?.ShopLocation);
|
||||||
|
}}> ⨉</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)))}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div style={{ color: "#616161" }}> | </div>
|
||||||
|
<div>
|
||||||
|
<PozoPublicSearch />
|
||||||
|
</div>
|
||||||
|
</div>}
|
||||||
|
|
||||||
|
<div className="NavIcons">
|
||||||
|
<div className="formob">
|
||||||
|
<div className="cart" onClick={navigatetoCart}>
|
||||||
|
<PiShoppingCartLight
|
||||||
|
className="carticon"
|
||||||
|
style={{
|
||||||
|
fontSize: "26px",
|
||||||
|
fontWeight: "200",
|
||||||
|
strokeWidth: "2",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className="login-container"
|
||||||
|
onClick={handleLoginClick}
|
||||||
|
>
|
||||||
|
<div className="login">
|
||||||
|
<div className="login-btn" onMouseEnter={() => { setProfile(true) }}>
|
||||||
|
Login
|
||||||
|
<FaChevronDown
|
||||||
|
style={{
|
||||||
|
fontSize: "13px",
|
||||||
|
fontWeight: "100",
|
||||||
|
strokeWidth: "2",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{profile && (
|
||||||
|
<div
|
||||||
|
className={`profile-details ${profile ? "open" : "closed"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="profile-content">
|
||||||
|
<div className="profile-header">
|
||||||
|
<span className="new-cust-text">New customer?</span>
|
||||||
|
<span className="signup-link" onClick={toSignIn}>Sign Up</span>
|
||||||
|
</div>
|
||||||
|
<div className="profile-list">
|
||||||
|
<div className="profile-items" onClick={toMyProfile}>
|
||||||
|
<PiUserCircleLight className="profile-item-icon" />
|
||||||
|
<span>My Profile</span>
|
||||||
|
</div>
|
||||||
|
<div className="profile-items" onClick={toFavOrder}>
|
||||||
|
<CiViewList className="profile-item-icon" />
|
||||||
|
<span>My Orders</span>
|
||||||
|
</div>
|
||||||
|
<div className="profile-items" onClick={toFavShop}>
|
||||||
|
<PiStorefrontLight className="profile-item-icon" />
|
||||||
|
<span>Fav Shop</span>
|
||||||
|
</div>
|
||||||
|
<div className="profile-items" onClick={toFavList}>
|
||||||
|
<GoHeart className="profile-item-icon" />
|
||||||
|
<span>Fav List</span>
|
||||||
|
</div>
|
||||||
|
<div className="profile-items" onClick={toStore}>
|
||||||
|
<PiStorefrontLight className="profile-item-icon" />
|
||||||
|
<span>Stores</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="loginout-btn" onClick={toSignIn}> Sign In / Login </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicNavbar;
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,78 @@
|
||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { AiOutlineClose } from "react-icons/ai";
|
||||||
|
import './PublicPozoModal.scss';
|
||||||
|
|
||||||
|
const PublicPozoModal = ({ title, children, onClose, width, height, className, onClick, handleClick, style }) => {
|
||||||
|
const modalRef = useRef(null);
|
||||||
|
|
||||||
|
// Handle click outside modal
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (modalRef.current && !modalRef.current.contains(event.target)) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle ESC key press
|
||||||
|
const handleEscKey = (event) => {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
document.addEventListener('keydown', handleEscKey);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
document.removeEventListener('keydown', handleEscKey);
|
||||||
|
};
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`PublicPozoModal-Master ${className}`}>
|
||||||
|
<div
|
||||||
|
className="PublicPozoModalMain"
|
||||||
|
ref={modalRef}
|
||||||
|
style={{ width: width || '80%', height: height || '80%', ...style }}
|
||||||
|
>
|
||||||
|
<div className="headerModal">
|
||||||
|
<h2>{title}</h2>
|
||||||
|
<AiOutlineClose onClick={onClose} />
|
||||||
|
</div>
|
||||||
|
<div className="contentModal">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
{/* <button className="modal-action-button" onClick={handleClick}>
|
||||||
|
Action
|
||||||
|
</button> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PublicPozoModal.propTypes = {
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
width: PropTypes.string,
|
||||||
|
height: PropTypes.string,
|
||||||
|
className: PropTypes.string,
|
||||||
|
style: PropTypes.object,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
handleClick: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
PublicPozoModal.defaultProps = {
|
||||||
|
width: '80%',
|
||||||
|
height: '80%',
|
||||||
|
className: '',
|
||||||
|
onClick: () => { },
|
||||||
|
handleClick: () => { },
|
||||||
|
style: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PublicPozoModal;
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
.PublicPozoModal-Master {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #00000070;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeIn 0.3s forwards;
|
||||||
|
z-index: 1000;
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
|
||||||
|
&.fade-out {
|
||||||
|
animation: fadeOut 0.3s forwards;
|
||||||
|
/* Fade out on unmount */
|
||||||
|
}
|
||||||
|
|
||||||
|
.PublicPozoModalMain {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #FFF;
|
||||||
|
padding: 1rem;
|
||||||
|
row-gap: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
/* Start slightly above */
|
||||||
|
animation: slideIn 0.3s forwards;
|
||||||
|
/* Slide in on mount */
|
||||||
|
|
||||||
|
.headerModal {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.contentModal {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-button {
|
||||||
|
background: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideIn {
|
||||||
|
from {
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,399 @@
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import Logo from "./../../../../Images/PozoWhite.svg";
|
||||||
|
import "./AdminNavbar.scss";
|
||||||
|
import { IoIosMore } from "react-icons/io";
|
||||||
|
import { IoIosArrowDown } from "react-icons/io";
|
||||||
|
import { PiReceipt, PiUsersThreeLight } from "react-icons/pi";
|
||||||
|
import { FiMenu } from "react-icons/fi";
|
||||||
|
import { IoNotificationsOutline, IoSettingsOutline } from "react-icons/io5";
|
||||||
|
import { RxDashboard } from "react-icons/rx";
|
||||||
|
import { RiPlayListAddFill } from "react-icons/ri";
|
||||||
|
import { BsBarChartLine } from "react-icons/bs";
|
||||||
|
import { AiOutlineSetting } from "react-icons/ai";
|
||||||
|
import { MdOutlineLiveHelp, MdOutlineQueryStats } from "react-icons/md";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import FullPageLoader from "../../../Loader/PozoPublicLoader";
|
||||||
|
import { HiOutlineSpeakerphone } from "react-icons/hi";
|
||||||
|
|
||||||
|
const AdminNavbar = () => {
|
||||||
|
const [dropdownData, setDropdownData] = useState({
|
||||||
|
dashboard: [],
|
||||||
|
orders: [],
|
||||||
|
products: [],
|
||||||
|
users: [],
|
||||||
|
reports: [],
|
||||||
|
settings: [],
|
||||||
|
queries: [],
|
||||||
|
customercare: [],
|
||||||
|
});
|
||||||
|
const [sideNav, setsideNav] = useState(true);
|
||||||
|
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||||
|
useEffect(() => {
|
||||||
|
if (windowWidth > 768) {
|
||||||
|
setsideNav(true);
|
||||||
|
} else if (windowWidth <= 768) {
|
||||||
|
setsideNav(false);
|
||||||
|
}
|
||||||
|
}, [windowWidth]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
setWindowWidth(window.innerWidth);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
|
||||||
|
// Cleanup listener on unmount
|
||||||
|
return () => window.removeEventListener("resize", handleResize);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Mock API data for each dropdown
|
||||||
|
const fetchData = async () => {
|
||||||
|
const data = {
|
||||||
|
dashboard: ["Overview", "Statistics", "Performance"],
|
||||||
|
orders: ["Received Orders","Pending Orders", "Completed Orders", "Cancelled Orders"],
|
||||||
|
products: ["Add Product", "My Product", "Product Categories", "Product Reviews", "Inventory Management"],
|
||||||
|
users: ["SAdmin Dashboard","Active Users", "Inactive Users", "New Users"],
|
||||||
|
adsmanagement: ["Ads Management","Add New Ads" ],
|
||||||
|
reports: ["Sales Report", "User Report", "Revenue Report", "Payment Report"],
|
||||||
|
settings: ["Account Settings", "Notifications", "Privacy"],
|
||||||
|
queries: [ "Open Queries", "Resolved Queries", "Pending Queries", "All Queries"],
|
||||||
|
customercare: ["Phone", "Request Quries"],
|
||||||
|
SAdmin_Dashboard: ["Phone", "Request Quries"],
|
||||||
|
};
|
||||||
|
setDropdownData(data);
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const PageNavigate = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/setting`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
const PageNavigatetoproduct = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/product`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const PageNavigatetoAdsManagement = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/adsmanagement`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const NavigatetoDashboard = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/dashboard`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
const NavigatetoMyProduct = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/myproduct`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavigatetoOrders = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/admin-page/orders`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavigatetoSadminUsers = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/admin-page/SadminUsers`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
const NavigatetoSadminDashboard = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/admin-page/sadmindashboard`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavigatetoReports = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/admin-page/sadminreport`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
const NavigatetoSalesReports = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/admin-page/salesreport`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
const NavigatetoPaymentReports = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/admin-page/paymentreport`);
|
||||||
|
}, 700);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavigatetoQueries = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/querymanagement`);
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const NavigatetoContact = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/querycontact`);
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavigatetoQueryRequest = () => {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
navigate(`/admin-page/qryrqst`);
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{loading && <FullPageLoader />}
|
||||||
|
<div className="AdminNavBarMaster">
|
||||||
|
<div className="Navoptinfos">
|
||||||
|
<div className="NavContent">
|
||||||
|
<div className="NavLogowName">
|
||||||
|
<FiMenu
|
||||||
|
className="hamMenu"
|
||||||
|
onClick={() => setsideNav(!sideNav)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img onClick={NavigatetoDashboard} src={Logo} width={60} alt="PozoLogo" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p> Sri Krishna Silks & Readymades </p>
|
||||||
|
<a> Palacode, Tamilnadu, India </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="Navmoreinfo">
|
||||||
|
<div>
|
||||||
|
<IoNotificationsOutline />
|
||||||
|
</div>
|
||||||
|
<div onClick={PageNavigate}>
|
||||||
|
<IoSettingsOutline />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<IoIosMore />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{sideNav && (
|
||||||
|
<div className="NavOptions">
|
||||||
|
<div className="navDrpdwn">
|
||||||
|
{/* Dashboard Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div >
|
||||||
|
<RxDashboard size={17} /> Dashboard
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.dashboard.map((option, index) => (
|
||||||
|
<div key={index} className="dropdown-option" onClick= { option == "Overview" && NavigatetoDashboard} >
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Orders Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div onClick={NavigatetoOrders}>
|
||||||
|
<PiReceipt size={17} /> Orders <IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.orders.map((option, index) => (
|
||||||
|
<div key={index} className="dropdown-option" onClick= { option == "Received Orders" && NavigatetoOrders} >
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Product Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
{" "}
|
||||||
|
<RiPlayListAddFill size={17} /> Products{" "}
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.products.map((option, index) => (
|
||||||
|
<div
|
||||||
|
onClick={option === "Add Product" ? PageNavigatetoproduct : option === "My Product" ? NavigatetoMyProduct : undefined}
|
||||||
|
key={index}
|
||||||
|
className="dropdown-option"
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Users Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
{" "}
|
||||||
|
<PiUsersThreeLight size={20} /> User Mangement{" "}
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.users.map((option, index) => (
|
||||||
|
<div key={index} className="dropdown-option"
|
||||||
|
onClick={option === "Active Users" ? NavigatetoSadminUsers : option === "SAdmin Dashboard" ? NavigatetoSadminDashboard : undefined}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Reports Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
{" "}
|
||||||
|
<BsBarChartLine size={17} /> Reports{" "}
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.reports.map((option, index) => (
|
||||||
|
<div
|
||||||
|
onClick={option === "Revenue Report" ? NavigatetoReports : option === "Sales Report" ? NavigatetoSalesReports : option === "Payment Report" ? NavigatetoPaymentReports : undefined}
|
||||||
|
key={index}
|
||||||
|
className="dropdown-option"
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ads Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
<HiOutlineSpeakerphone size={17} /> Ads Management
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData?.adsmanagement?.map((option, index) => (
|
||||||
|
<div
|
||||||
|
onClick={option === "Add New Ads" ? PageNavigatetoAdsManagement : undefined}
|
||||||
|
key={index}
|
||||||
|
className="dropdown-option"
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Settings Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
<AiOutlineSetting size={17} /> Settings
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.settings.map((option, index) => (
|
||||||
|
<div key={index} className="dropdown-option">
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Query Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
<MdOutlineQueryStats size={17} /> Queries
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.queries.map((option, index) => (
|
||||||
|
<div key={index} className="dropdown-option"
|
||||||
|
onClick={option === "All Queries" ? NavigatetoQueries : undefined}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* CustomerCare Dropdown */}
|
||||||
|
<div className="noption">
|
||||||
|
<div>
|
||||||
|
<MdOutlineLiveHelp size={17} /> Customer Care
|
||||||
|
<IoIosArrowDown size={10} />
|
||||||
|
</div>
|
||||||
|
<div className="dropdown-content">
|
||||||
|
{dropdownData.customercare.map((option, index) => (
|
||||||
|
<div key={index} className="dropdown-option"
|
||||||
|
onClick={option == "Request Quries" ? NavigatetoQueryRequest:option == "Phone"?NavigatetoContact:"" }
|
||||||
|
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AdminNavbar;
|
||||||
|
|
@ -0,0 +1,150 @@
|
||||||
|
.AdminNavBarMaster {
|
||||||
|
.Navoptinfos {
|
||||||
|
height: 45px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #23282d;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.NavOptions {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
.NavContent {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
|
||||||
|
.hamMenu {
|
||||||
|
display: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.NavLogowName {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
p {
|
||||||
|
font-size: clamp(10px, 2.5vw, 12px);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
font-size: clamp(7px, 2.5vw, 9px);
|
||||||
|
font-family: "gilroy";
|
||||||
|
font-weight: 100 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Navmoreinfo {
|
||||||
|
display: flex;
|
||||||
|
font-size: clamp(17px, 2.5vw, 18px);
|
||||||
|
gap: 0.7rem;
|
||||||
|
div {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.NavOptions {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #3e4750;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navDrpdwn {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.2rem;
|
||||||
|
font-family: "Gilroy";
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noption {
|
||||||
|
position: relative;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
min-width: 160px;
|
||||||
|
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1;
|
||||||
|
opacity: 0;
|
||||||
|
transition:
|
||||||
|
opacity 0.3s ease-in-out,
|
||||||
|
transform 0.3s ease-in-out;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-option {
|
||||||
|
padding: 8px 16px;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-option:hover {
|
||||||
|
background-color: #e3333313;
|
||||||
|
color: #e33333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .dropdown-content {
|
||||||
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.hamMenu {
|
||||||
|
display: block !important;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
.NavOptions {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
display: block !important;
|
||||||
|
background-color: #3e4750 !important;
|
||||||
|
height: 100vh !important;
|
||||||
|
z-index: 12;
|
||||||
|
width: 12rem !important;
|
||||||
|
padding: 1rem 0.7rem;
|
||||||
|
.navDrpdwn {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.dropdown-content {
|
||||||
|
position: relative !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,483 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { CiGlobe } from "react-icons/ci";
|
||||||
|
import { IoChevronDown } from "react-icons/io5";
|
||||||
|
import "./SadminPanel.scss"
|
||||||
|
import PozoPublicDropDown from '../../DropDown/PozoPublicDropDown';
|
||||||
|
import PozoPublicDatePicker from '../../DatePicker/PozoPublicDatePicker';
|
||||||
|
import { IoIosRefresh } from 'react-icons/io';
|
||||||
|
import { RxDownload } from "react-icons/rx";
|
||||||
|
import { HiOutlinePrinter } from "react-icons/hi2";
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { changeglobalModuleTabColor } from '../../../Features/AdminPanel/AdminPanel';
|
||||||
|
|
||||||
|
const SadminPanel = () => {
|
||||||
|
const dispach= useDispatch()
|
||||||
|
const [selectedCountry, setSelectedCountry] = useState('');
|
||||||
|
const [selectedYear, setSelectedYear] = useState('');
|
||||||
|
const [isYear, setIsYear] = useState(false);
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const [activeTab, setActiveTab] = useState('All Categories');
|
||||||
|
|
||||||
|
const [selectedMonthYear, setSelectedMonthYear] = useState('');
|
||||||
|
const [selectedMYear, setSelectedMYear] = useState('');
|
||||||
|
const [isMonthYear, setIsMonthYear] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
const tabs = ['All Categories', 'Grocery', 'Food Delivery', 'Meat', 'Book'];
|
||||||
|
|
||||||
|
const tabColors = {
|
||||||
|
'All Categories': {
|
||||||
|
// background: '#FFD700',
|
||||||
|
background: '#EFF7FD',
|
||||||
|
color: '#000000',
|
||||||
|
activeBackground: '#60B0E9',
|
||||||
|
activeColor: '#fff',
|
||||||
|
tabBgColor:"#C2D9EA"
|
||||||
|
|
||||||
|
},
|
||||||
|
'Grocery': {
|
||||||
|
// background: '#32CD32',
|
||||||
|
background: '#f8fff3',
|
||||||
|
color: '#000',
|
||||||
|
activeBackground: '#3D9315',
|
||||||
|
activeColor: '#FFFFFF',
|
||||||
|
tabBgColor:"#BDE2AC"
|
||||||
|
|
||||||
|
},
|
||||||
|
'Food Delivery': {
|
||||||
|
// background: '#FA5353',
|
||||||
|
background: '#FFEFEF',
|
||||||
|
color: '#000',
|
||||||
|
activeBackground: '#F06565',
|
||||||
|
activeColor: '#FFFFFF',
|
||||||
|
tabBgColor:"#FFD6D6"
|
||||||
|
|
||||||
|
},
|
||||||
|
// 'Food Delivery': {
|
||||||
|
// background: '#FA5353',
|
||||||
|
// background: '#f1f1ff',
|
||||||
|
// color: '#000',
|
||||||
|
// activeBackground: '#978FF4',
|
||||||
|
// activeColor: '#FFFFFF',
|
||||||
|
// tabBgColor:"#C8C4ED"
|
||||||
|
|
||||||
|
// },
|
||||||
|
'Meat': {
|
||||||
|
// background: '#B7532E',
|
||||||
|
background: '#fff5f3',
|
||||||
|
color: '#000',
|
||||||
|
activeBackground: '#CF7213',
|
||||||
|
activeColor: '#FFFFFF',
|
||||||
|
tabBgColor:"#EAD6C2"
|
||||||
|
|
||||||
|
},
|
||||||
|
'Book': {
|
||||||
|
// background: '#A486FF',
|
||||||
|
background: '#F7F1F3',
|
||||||
|
color: '#000',
|
||||||
|
activeBackground: '#AC7882',
|
||||||
|
activeColor: '#FFFFFF',
|
||||||
|
tabBgColor:"#F4CBD9"
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const countries = [
|
||||||
|
{ name: 'UAE', flag: 'https://uxwing.com/wp-content/themes/uxwing/download/flags-landmarks/united-arab-emirates-flag-icon.png', fullName: 'United Arab Emirates' },
|
||||||
|
{ name: 'India', flag: 'https://uxwing.com/wp-content/themes/uxwing/download/flags-landmarks/india-flag-icon.png', fullName: 'Republic of India' },
|
||||||
|
{ name: 'UK', flag: 'https://uxwing.com/wp-content/themes/uxwing/download/flags-landmarks/united-kingdom-flag-icon.png', fullName: 'United Kingdom' },
|
||||||
|
{ name: 'USA', flag: 'https://uxwing.com/wp-content/themes/uxwing/download/flags-landmarks/united-states-flag-icon.png', fullName: 'United States of America' },
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleSelect = (country) => {
|
||||||
|
setSelectedCountry(country);
|
||||||
|
setIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
|
|
||||||
|
const selectedFlag = countries.find(c => c.name === selectedCountry)?.flag;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Define a range of years
|
||||||
|
const startYear = 2000;
|
||||||
|
const endYear = new Date().getFullYear();
|
||||||
|
const years = Array.from({ length: endYear - startYear + 1 }, (v, i) => startYear + i);
|
||||||
|
|
||||||
|
const handleSelectYr = (year) => {
|
||||||
|
setSelectedYear(year);
|
||||||
|
setIsYear(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Define month names
|
||||||
|
const months = [
|
||||||
|
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||||
|
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleSelectMonthYear = (month, year) => {
|
||||||
|
setSelectedMonthYear(`${month}, ${year}`);
|
||||||
|
setIsMonthYear(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectYear = (year) => {
|
||||||
|
setSelectedMYear(year); // Set the selected year
|
||||||
|
};
|
||||||
|
|
||||||
|
const categoryClick = async(tab,color,background,activeBackground,tabBgColor)=>{
|
||||||
|
setActiveTab(tab)
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
categorry:tab,
|
||||||
|
color:color,
|
||||||
|
background: background,
|
||||||
|
activeBackground:activeBackground,
|
||||||
|
tabBgColor:tabBgColor,
|
||||||
|
}
|
||||||
|
await dispach(changeglobalModuleTabColor(data))
|
||||||
|
console.log(data,"checkdata")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='SadminPanelDiv'>
|
||||||
|
<div className='panelFilterhead'>
|
||||||
|
|
||||||
|
<div className='pnlfltrlftPart'>
|
||||||
|
<div><CiGlobe style={{ fontSize: '21px' }} /></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div style={{ position: 'relative', width: '55px' }}>
|
||||||
|
<div
|
||||||
|
className="dropdown"
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
|
style={{
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
padding: '5px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
height: "2rem ",
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
borderRadius: "6px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedFlag ? (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={selectedFlag}
|
||||||
|
alt={`${selectedCountry} flag`}
|
||||||
|
style={{ width: '23px', marginRight: '8px' }}
|
||||||
|
/>
|
||||||
|
{/* <span style={{ fontSize: "11px" }}>{selectedCountry}</span> */}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<span style={{ fontSize: "11px", fontWeight: "600", }}>Country</span>
|
||||||
|
)}
|
||||||
|
<IoChevronDown style={{ marginLeft: 'auto', fontSize: "11px" }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tooltip for selected country with full name */}
|
||||||
|
{isHovered && selectedCountry && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: '100%', // Position above the dropdown
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translateX(-50%)',
|
||||||
|
backgroundColor: '#23282D',
|
||||||
|
fontSize: "11px",
|
||||||
|
color: '#fff',
|
||||||
|
textAlign: 'center',
|
||||||
|
borderRadius: '5px',
|
||||||
|
padding: '5px',
|
||||||
|
zIndex: 1,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
opacity: 0.9,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{countries.find(c => c.name === selectedCountry)?.fullName}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isOpen && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
marginTop: '5px',
|
||||||
|
maxHeight: '150px',
|
||||||
|
overflowY: 'auto',
|
||||||
|
position: 'absolute',
|
||||||
|
width: '80px',
|
||||||
|
background: '#fff'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{countries.map((country) => (
|
||||||
|
<div
|
||||||
|
key={country.name}
|
||||||
|
onClick={() => handleSelect(country.name)}
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={country.flag}
|
||||||
|
alt={`${country.name} flag`}
|
||||||
|
style={{ width: '20px', marginRight: '8px' }}
|
||||||
|
/>
|
||||||
|
<a style={{ fontSize: "12.5px", }}> {country.name}</a>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='Statre-drp-dwn'>
|
||||||
|
<PozoPublicDropDown
|
||||||
|
height="2.0rem"
|
||||||
|
width="8rem"
|
||||||
|
options={["Tamilnadu", "Karnataka", "Andhra", "Kerala", "Maharastra"]}
|
||||||
|
placeholder={false}
|
||||||
|
placeholder2={"Select State"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='Statre-drp-dwn'>
|
||||||
|
<PozoPublicDropDown
|
||||||
|
height="2.0rem"
|
||||||
|
width="8rem"
|
||||||
|
options={["Salem", "Coimbatore", "Madurai", "Thirunelveli", "Chennai"]}
|
||||||
|
placeholder={false}
|
||||||
|
placeholder2={"Select District"}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='Statre-drp-dwn'>
|
||||||
|
<PozoPublicDropDown
|
||||||
|
height="2rem"
|
||||||
|
width="8rem"
|
||||||
|
options={["Salem", "Coimbatore", "Madurai", "Thirunelveli", "Chennai"]}
|
||||||
|
placeholder={false}
|
||||||
|
placeholder2={"Select District"}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='Statre-drp-dwn'>
|
||||||
|
<PozoPublicDropDown
|
||||||
|
height="2rem"
|
||||||
|
width="14rem"
|
||||||
|
options={["SHS Bakery", "JS Restaurant", "Madurai Munis", "Hotel Gani", "Thoppivaapa"]}
|
||||||
|
placeholder={false}
|
||||||
|
placeholder2={" Branch / Shop"}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='rptCalnder'>
|
||||||
|
<div className='yrdiv' style={{ position: 'relative', width: '55px' }}>
|
||||||
|
<div
|
||||||
|
|
||||||
|
onClick={() => setIsYear(!isYear)}
|
||||||
|
style={{
|
||||||
|
padding: '5px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
display: 'flex',
|
||||||
|
fontSize: "11.5px",
|
||||||
|
alignItems: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
borderRadius: "6px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedYear ? (
|
||||||
|
<span style={{ fontSize: "11px" }}>{selectedYear}</span>
|
||||||
|
) : (
|
||||||
|
<span style={{ fontSize: "11px" }}> Year</span>
|
||||||
|
)}
|
||||||
|
<IoChevronDown style={{ marginLeft: 'auto', fontSize: "11px" }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isYear && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginTop: '5px',
|
||||||
|
maxHeight: '190px',
|
||||||
|
overflowY: 'auto',
|
||||||
|
fontSize: "11.5px", border: '1px solid #ccc',
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: "2",
|
||||||
|
width: '100%',
|
||||||
|
background: '#fff'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{years.map((year) => (
|
||||||
|
<div
|
||||||
|
key={year}
|
||||||
|
onClick={() => handleSelectYr(year)}
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{year}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='yrdiv' style={{ position: 'relative', width: '90px' }}>
|
||||||
|
<div
|
||||||
|
// className="dropdown"
|
||||||
|
onClick={() => setIsMonthYear(!isMonthYear)}
|
||||||
|
style={{
|
||||||
|
// border: '1px solid #ccc',
|
||||||
|
padding: '10px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
borderRadius: "6px",
|
||||||
|
textWrap: "nowrap",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{ fontSize: "11px" }}>
|
||||||
|
{selectedMonthYear || 'Month'}
|
||||||
|
</span>
|
||||||
|
<IoChevronDown style={{ marginLeft: 'auto', fontSize: "11px" }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Dropdown showing the year and then the corresponding months */}
|
||||||
|
{isMonthYear && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
marginTop: '5px',
|
||||||
|
maxHeight: '300px',
|
||||||
|
overflowY: 'auto',
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100px',
|
||||||
|
zIndex: '2',
|
||||||
|
fontSize: "11px",
|
||||||
|
background: '#fff',
|
||||||
|
right: "0.1rem",
|
||||||
|
display: 'flex' // Flexbox for layout
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Year Section on the left */}
|
||||||
|
<div style={{ width: '35', borderRight: '1px solid #ccc', padding: '5px', height: '50vh', overflow: 'scroll' }}>
|
||||||
|
{years.map((year) => (
|
||||||
|
<div
|
||||||
|
key={year}
|
||||||
|
onClick={() => setSelectedMYear(year)}
|
||||||
|
style={{
|
||||||
|
padding: '5px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
zIndex: '2',
|
||||||
|
backgroundColor: year === selectedMYear ? '#f0f0f0' : 'transparent' // Highlight selected year
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<strong>{year}</strong>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Month Section on the right (shown only after selecting a year) */}
|
||||||
|
{selectedMYear && (
|
||||||
|
<div style={{ width: '50%', padding: '4px', height: '50vh', overflow: 'scroll' }}>
|
||||||
|
{months.map((month) => (
|
||||||
|
<div
|
||||||
|
key={`${month}-${selectedMYear}`}
|
||||||
|
onClick={() => handleSelectMonthYear(month, selectedMYear)}
|
||||||
|
style={{ padding: '5px', cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
{month}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className='YrMntdatepicker'>
|
||||||
|
<PozoPublicDatePicker
|
||||||
|
// width="8.5rem"
|
||||||
|
placeholder="Date"
|
||||||
|
height="2.5rem"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<div className='PanelTabSwitchHead'>
|
||||||
|
{/* Tab Switch Section */}
|
||||||
|
<div className='TabSwitch' style={{ display: 'flex', gap: '0.2rem', cursor: 'pointer' }}>
|
||||||
|
{tabs.map((tab) => (
|
||||||
|
<div
|
||||||
|
key={tab}
|
||||||
|
onClick={() =>categoryClick(tab,tabColors[tab].activeBackground ,tabColors[tab].background,tabColors[tab].tabBgColor) }
|
||||||
|
style={{
|
||||||
|
padding: '5px 10px ',
|
||||||
|
fontSize: "12px",
|
||||||
|
textTransform: "uppercase",
|
||||||
|
// borderBottom: activeTab === tab ? '2px solid #000' : 'none',
|
||||||
|
borderRadius:'3px',
|
||||||
|
backgroundColor: activeTab === tab ? tabColors[tab].activeBackground : tabColors[tab].background,
|
||||||
|
color: activeTab === tab ? tabColors[tab].activeColor : tabColors[tab].color,
|
||||||
|
// color:"#000",
|
||||||
|
|
||||||
|
// color: activeTab === tab ? '#000' : '#A6A6A6',
|
||||||
|
fontWeight: activeTab === tab ? '600' :"600",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tab}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='Othractns'>
|
||||||
|
<div> <IoIosRefresh /> REFRESH</div>
|
||||||
|
<div> <RxDownload /> DOWNLOAD</div>
|
||||||
|
<div> <HiOutlinePrinter /> PRINT</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SadminPanel
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
.SadminPanelDiv{
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 0.5rem;
|
||||||
|
padding: 0.5rem 0.2rem;
|
||||||
|
|
||||||
|
.panelFilterhead{
|
||||||
|
display: flex;
|
||||||
|
padding: 0rem 0.5rem;
|
||||||
|
column-gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.pnlfltrlftPart{
|
||||||
|
display: flex;
|
||||||
|
column-gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Statre-drp-dwn{
|
||||||
|
.PozoPublicDropDown-Master {
|
||||||
|
.PozoPublicDropDownMain{
|
||||||
|
svg{
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
input{
|
||||||
|
font-size: 11.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.PozoPublicDropDownOption{
|
||||||
|
font-size: 11.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.rptCalnder{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.yrdiv{
|
||||||
|
color: #575757;
|
||||||
|
|
||||||
|
:hover{
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.YrMntdatepicker{
|
||||||
|
.date-picker{
|
||||||
|
width: unset !important;
|
||||||
|
}
|
||||||
|
.date-picker .pickermain{
|
||||||
|
border: none !important;
|
||||||
|
width: min-content;
|
||||||
|
}
|
||||||
|
.calendar{
|
||||||
|
left: unset;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
.date-picker input{
|
||||||
|
width: 50px;
|
||||||
|
// min-width: 50px;
|
||||||
|
// max-width: max-content;
|
||||||
|
font-size: 11.6px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.PanelTabSwitchHead {
|
||||||
|
// border-bottom: 1px solid #ccc;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 0.5rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 10.5px;
|
||||||
|
padding-right: 1rem;
|
||||||
|
// background-color: #dddddde0;
|
||||||
|
// border-radius: 6px;
|
||||||
|
align-items: center;
|
||||||
|
.TabSwitch div {
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TabSwitch div:hover {
|
||||||
|
color: #007BFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Othractns{
|
||||||
|
display:flex ;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size:9.7px;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
column-gap: 0.7rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
div{
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3rem ;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:hover{
|
||||||
|
color: #007BFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.PozoPublicSadminReportMaster .CommonFltrhd {
|
||||||
|
height: unset !important;
|
||||||
|
}
|
||||||
|
.SadminPanelDiv .PanelTabSwitchHead{
|
||||||
|
text-wrap: nowrap;
|
||||||
|
}
|
||||||
|
.TabSwitch {
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Statre-drp-dwn{
|
||||||
|
.PozoPublicDropDown-Master {
|
||||||
|
width: 5rem !important;
|
||||||
|
|
||||||
|
.PozoPublicDropDownMain{
|
||||||
|
width: 5rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { FiSearch } from "react-icons/fi"; // Importing search icon from react-icons
|
||||||
|
import "../../Components/SearchInput/PozoPublicSearchInput.scss";
|
||||||
|
|
||||||
|
const PozoPublicSearchInput = ({
|
||||||
|
label = "Search",
|
||||||
|
placeholder = "Search...",
|
||||||
|
value = "",
|
||||||
|
onChange,
|
||||||
|
width = "100%",
|
||||||
|
height = "auto",
|
||||||
|
searchIcon = <FiSearch />, // Default search icon using React Icons
|
||||||
|
disabled = false,
|
||||||
|
className = ""
|
||||||
|
}) => {
|
||||||
|
const [inputValue, setInputValue] = useState(value);
|
||||||
|
|
||||||
|
const handleInputChange = (e) => {
|
||||||
|
setInputValue(e.target.value);
|
||||||
|
if (onChange) onChange(e.target.value); // Call onChange from parent
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`PozoPublicSearchInput ${className}`}
|
||||||
|
style={{ width: width, height: height }}
|
||||||
|
>
|
||||||
|
<div className="PozoPublicSearchInput-main" style={{ width: '100%' }}>
|
||||||
|
<span className="PozoPublicSearchInput-icon">
|
||||||
|
{searchIcon}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder={placeholder}
|
||||||
|
value={inputValue}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
disabled={disabled}
|
||||||
|
className="PozoPublicSearchInput-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PozoPublicSearchInput;
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
.PozoPublicSearchInput {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #0071e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicSearchInput-main {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicSearchInput-icon {
|
||||||
|
color: #818181;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.PozoPublicSearchInput-input {
|
||||||
|
flex: 1;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font-family: var(--Pozo-Fontfamily);
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 1px;
|
||||||
|
background: transparent;
|
||||||
|
letter-spacing: 0.7px;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #818181;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { FaTimes } from 'react-icons/fa';
|
||||||
|
import '../../Styles/Components/Toast.scss';
|
||||||
|
import { IoCloseOutline } from 'react-icons/io5';
|
||||||
|
|
||||||
|
const Toast = ({ children, duration, isVisible, onClose, position = 'bottom-right' }) => {
|
||||||
|
const [timeLeft, setTimeLeft] = useState(duration / 1000);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isVisible) {
|
||||||
|
setTimeLeft(duration / 1000);
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setTimeLeft((prev) => prev - 1);
|
||||||
|
}, 1000);
|
||||||
|
const autoClose = setTimeout(onClose, duration);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(timer);
|
||||||
|
clearTimeout(autoClose);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [isVisible, duration, onClose]);
|
||||||
|
|
||||||
|
const positionStyles = {
|
||||||
|
'bottom-right': { bottom: '20px', right: '20px' },
|
||||||
|
'bottom-left': { bottom: '20px', left: '20px' },
|
||||||
|
'top-right': { top: '20px', right: '20px' },
|
||||||
|
'top-left': { top: '20px', left: '20px' },
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
isVisible && (
|
||||||
|
<div className="toast-container" style={positionStyles[position]}>
|
||||||
|
<div className="toast-content">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
<div className="toast-timer">{timeLeft}s</div>
|
||||||
|
<IoCloseOutline className="toast-close-icon" onClick={onClose} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Toast;
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import Toast from './Toast'; // Adjust the import path accordingly
|
||||||
|
|
||||||
|
const ToastManager = ({ messages, duration, interval, position }) => {
|
||||||
|
const [isToastVisible, setIsToastVisible] = useState(false);
|
||||||
|
const [currentMessage, setCurrentMessage] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let messageIndex = 0;
|
||||||
|
|
||||||
|
const showNextToast = () => {
|
||||||
|
setCurrentMessage(messages[messageIndex]);
|
||||||
|
setIsToastVisible(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsToastVisible(false);
|
||||||
|
}, duration);
|
||||||
|
|
||||||
|
messageIndex = (messageIndex + 1) % messages.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
const intervalId = setInterval(showNextToast, interval);
|
||||||
|
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
}, [messages, duration, interval]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Toast
|
||||||
|
duration={duration}
|
||||||
|
isVisible={isToastVisible}
|
||||||
|
onClose={() => setIsToastVisible(false)}
|
||||||
|
position={position}
|
||||||
|
>
|
||||||
|
{currentMessage}
|
||||||
|
</Toast>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ToastManager;
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { FaCheck, FaExclamation, FaTimes } from "react-icons/fa";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import "../ToastMessage/ToastMessage.scss";
|
||||||
|
|
||||||
|
const ToastMessage = ({ type, message, onClose }) => {
|
||||||
|
const renderIcon = () => {
|
||||||
|
switch (type) {
|
||||||
|
case 'success':
|
||||||
|
return <div className="dynamic-island-badge success"><FaCheck size={10} /></div>;
|
||||||
|
case 'warning':
|
||||||
|
return <div className="dynamic-island-badge warning"><FaExclamation size={10} /></div>;
|
||||||
|
case 'error':
|
||||||
|
return <div className="dynamic-island-badge error"><FaTimes size={10} /></div>;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
if (onClose) onClose();
|
||||||
|
}, 2800);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="dynamic-island-wrapper">
|
||||||
|
<div className={`dynamic-island-pill ${type}`}>
|
||||||
|
{renderIcon()}
|
||||||
|
<span className="dynamic-island-text">{message}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ToastMessage.propTypes = {
|
||||||
|
type: PropTypes.oneOf(['success', 'warning', 'error']).isRequired,
|
||||||
|
message: PropTypes.string.isRequired,
|
||||||
|
onClose: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ToastMessage;
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
.dynamic-island-wrapper {
|
||||||
|
position: fixed;
|
||||||
|
top: 16px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: 999999;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-island-pill {
|
||||||
|
pointer-events: auto;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 9px;
|
||||||
|
padding: 7px 18px 7px 10px;
|
||||||
|
background: #000000;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 9999px;
|
||||||
|
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.15);
|
||||||
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
|
||||||
|
animation: dynamicIslandExpand 0.45s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.dynamic-island-badge {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
background-color: #22c55e;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
background-color: #f59e0b;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
background-color: #ef4444;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-island-text {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #ffffff;
|
||||||
|
letter-spacing: -0.1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dynamicIslandExpand {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scaleX(0.4) scaleY(0.6);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scaleX(1) scaleY(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.dynamic-island-wrapper {
|
||||||
|
top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-island-pill {
|
||||||
|
padding: 8px 16px 8px 10px;
|
||||||
|
|
||||||
|
.dynamic-island-text {
|
||||||
|
font-size: 12.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
// import React, { useState } from 'react';
|
||||||
|
// import { IoMdThumbsUp } from 'react-icons/io';
|
||||||
|
// import "../ToastMessage/ToastMessage.scss";
|
||||||
|
|
||||||
|
// const ToastMessage = () => {
|
||||||
|
// const [isToastMessageOpen, setIsToastMessageOpen] = useState(false);
|
||||||
|
// const [currentToast, setCurrentToast] = useState({ type: '', content: '' });
|
||||||
|
|
||||||
|
// const showToastMessage = (type, content) => {
|
||||||
|
// setCurrentToast({ type, content });
|
||||||
|
// setIsToastMessageOpen(true);
|
||||||
|
|
||||||
|
// setTimeout(() => {
|
||||||
|
// setIsToastMessageOpen(false);
|
||||||
|
// }, 3000);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const Toasttext = [
|
||||||
|
// { type: "success", content: "Operation successful" },
|
||||||
|
// { type: "error", content: "Operation failed" },
|
||||||
|
// { type: "warning", content: "Check the operation" },
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div className='ToastMessage-Master'>
|
||||||
|
// <div
|
||||||
|
// className={`messagemain ${isToastMessageOpen ? 'show' : 'hide'} ${currentToast.type}`}>
|
||||||
|
// <IoMdThumbsUp
|
||||||
|
// size={20}
|
||||||
|
// color={currentToast.type === "success" ? '#52C41A' : currentToast.type === "error" ? '#FF4D4F' : '#FAAD14'} />
|
||||||
|
// {currentToast.content}
|
||||||
|
// </div>
|
||||||
|
// <div style={{ display: 'flex', gap: '10px', width: "100%", justifyContent: "center" }}>
|
||||||
|
// {Toasttext.map((item, index) => (
|
||||||
|
// <button
|
||||||
|
// key={index}
|
||||||
|
// onClick={() => showToastMessage(item.type, item.content)}>
|
||||||
|
// Show {item.type} Message
|
||||||
|
// </button>
|
||||||
|
// ))}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default ToastMessage;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import './ToggleSwitch.scss'; // Ensure you have this SCSS file for styling
|
||||||
|
|
||||||
|
const ToggleSwitch = () => {
|
||||||
|
// Initialize state to true for an active toggle switch
|
||||||
|
const [isActive, setIsActive] = useState(true);
|
||||||
|
|
||||||
|
// Function to handle toggle switch change
|
||||||
|
const handleToggle = () => {
|
||||||
|
setIsActive((prev) => {
|
||||||
|
const newState = !prev;
|
||||||
|
// alert(newState ? 'The toggle is ON!' : 'The toggle is OFF!'); // Alert based on new state
|
||||||
|
return newState;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`toggle-switch ${isActive ? 'on' : 'off'}`} onClick={handleToggle}>
|
||||||
|
<div className={`toggle-indicator ${isActive ? 'active' : ''}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ToggleSwitch;
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
.toggle-switch {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
width: 30px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 12px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
|
// Off state background color (red)
|
||||||
|
&.off {
|
||||||
|
background-color: red; // Change to red when off
|
||||||
|
|
||||||
|
.toggle-indicator {
|
||||||
|
background-color: white;
|
||||||
|
transform: translateX(2px); // Indicator position for OFF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On state background color (green)
|
||||||
|
&.on {
|
||||||
|
background-color: #4caf50; // On color (green)
|
||||||
|
|
||||||
|
.toggle-indicator {
|
||||||
|
background-color: white;
|
||||||
|
transform: translateX(16px); // Indicator position for ON
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-indicator {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import "../../Components/Tooltip/PozoPublicTooltip.scss";
|
||||||
|
|
||||||
|
const PozoPublicTooltip = ({ infoText, children }) => {
|
||||||
|
const [showTooltip, setShowTooltip] = useState(false);
|
||||||
|
const [hovered, setHovered] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let showTimeout;
|
||||||
|
let hideTimeout;
|
||||||
|
|
||||||
|
if (hovered) {
|
||||||
|
showTimeout = setTimeout(() => {
|
||||||
|
setShowTooltip(true);
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
hideTimeout = setTimeout(() => {
|
||||||
|
setShowTooltip(false);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(showTimeout);
|
||||||
|
clearTimeout(hideTimeout);
|
||||||
|
};
|
||||||
|
}, [hovered]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="tooltip-container"
|
||||||
|
onMouseEnter={() => setHovered(true)}
|
||||||
|
onMouseLeave={() => setHovered(false)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
|
||||||
|
{/* Tooltip content */}
|
||||||
|
<div className={`tooltip ${showTooltip ? "open" : ""}`}>
|
||||||
|
{infoText}
|
||||||
|
{/* Arrow indicator */}
|
||||||
|
<div className="arrow" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PozoPublicTooltip;
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
.tooltip-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
max-width: 80vw;
|
||||||
|
font-size: 15px !important;
|
||||||
|
font-weight: 400;
|
||||||
|
background-color: rgba(0, 0, 0, 0.925);
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #d8e2e2;
|
||||||
|
position: absolute;
|
||||||
|
top: -51px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
opacity: 0;
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 100;
|
||||||
|
left: -40px;
|
||||||
|
transform: scale(0.5);
|
||||||
|
will-change: transform, opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip.open {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 8px solid transparent;
|
||||||
|
border-right: 8px solid transparent;
|
||||||
|
border-top: 10px solid rgba(0, 0, 0, 0.925);
|
||||||
|
position: absolute;
|
||||||
|
bottom: -5px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.tooltip {
|
||||||
|
font-size: 10px;
|
||||||
|
padding: 4px 14px;
|
||||||
|
top: -50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.tooltip {
|
||||||
|
font-size: 9px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
top: -55px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -8px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
const AdminPanel = createSlice({
|
||||||
|
name: "adminpanel",
|
||||||
|
initialState: {
|
||||||
|
ModuleTabColor: {
|
||||||
|
"categorry": "All Categories",
|
||||||
|
"color": "#60B0E9",
|
||||||
|
"background": "#EFF7FD",
|
||||||
|
"activeBackground": "#C2D9EA",
|
||||||
|
"tabBgColor":"#C2D9EA"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
changeglobalModuleTabColor: (state, action) => {
|
||||||
|
state.ModuleTabColor=action.payload
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {changeglobalModuleTabColor} = AdminPanel.actions
|
||||||
|
export const GlobalModuleTabColor = (state)=>state?.AdminPanel?.ModuleTabColor
|
||||||
|
export default AdminPanel.reducer;
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const initialState = { cartShow: false, CartitemsCount: 1 };
|
||||||
|
|
||||||
|
const PublicBooking = createSlice({
|
||||||
|
name: "PublicBooking",
|
||||||
|
initialState: initialState,
|
||||||
|
reducers: {
|
||||||
|
changeCartShow: (state, action) => {
|
||||||
|
state.cartShow = action.payload
|
||||||
|
},
|
||||||
|
changecartCount: (state, action) => {
|
||||||
|
state.CartitemsCount = action.payload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const { changeCartShow, changecartCount } = PublicBooking.actions;
|
||||||
|
export const globalchangeCartShow = (state) => state?.PublicBooking?.cartShow;
|
||||||
|
export const globalcartCount = (state) => state?.PublicBooking?.CartitemsCount;
|
||||||
|
|
||||||
|
export default PublicBooking.reducer;
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
breadCrumb: [],
|
||||||
|
RedirectStatus: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const landingPage = createSlice({
|
||||||
|
name: "centerPage",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
changeBreadCrumb: (state, action) => {
|
||||||
|
const { items } = action.payload;
|
||||||
|
state.breadCrumb = items;
|
||||||
|
},
|
||||||
|
emptyBreadCrumb: (state, action) => {
|
||||||
|
state.breadCrumb = [];
|
||||||
|
},
|
||||||
|
changeRedirectStatus: (state, action) => {
|
||||||
|
state.RedirectStatus = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { changeBreadCrumb, changeRedirectStatus, emptyBreadCrumb } =
|
||||||
|
landingPage.actions;
|
||||||
|
|
||||||
|
export const breadCrumbSelector = (state) => state?.landingPage?.breadCrumb;
|
||||||
|
export const GlobalRedirectStatus = (state) =>
|
||||||
|
state?.landingPage?.RedirectStatus;
|
||||||
|
export default landingPage.reducer;
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
let initialState = { SearchedText: null };
|
||||||
|
|
||||||
|
const Search = createSlice({
|
||||||
|
name: "Search",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
changeSearchText: (state, action) => {
|
||||||
|
console.log("Global",action.payload)
|
||||||
|
state.SearchedText = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { changeSearchText } = Search.actions;
|
||||||
|
|
||||||
|
export const GlobalSearchText = (state) => state?.Search?.SearchedText;
|
||||||
|
|
||||||
|
export default Search.reducer;
|
||||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue