first commit

This commit is contained in:
Sridhar R 2026-08-12 14:24:25 +05:30
commit 2f0cd84c4a
288 changed files with 63828 additions and 0 deletions

20
.eslintrc.cjs Normal file
View File

@ -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 },
],
},
}

24
.gitignore vendored Normal file
View File

@ -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?

BIN
Public Updated 12Aug.zip Normal file

Binary file not shown.

BIN
Public Updated.zip Normal file

Binary file not shown.

8
README.md Normal file
View File

@ -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

44
codeStructure.txt Normal file
View File

@ -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

38
index.html Normal file
View File

@ -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: &quot;Poppins&quot;, sans-serif;
"
></iframe>
</html>

9619
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

63
package.json Normal file
View File

@ -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"
}
}

1
public/vite.svg Normal file
View File

@ -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

9
src/.env.development Normal file
View File

@ -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/'

8
src/.env.production Normal file
View File

@ -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/'

98
src/App.jsx Normal file
View File

@ -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;

706
src/Check.jsx Normal file
View File

@ -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;

View File

@ -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;

View File

@ -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;
// }
// }

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,8 @@
@keyframes sliceIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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%;
}
}
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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 */
}

View File

@ -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;

View File

@ -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;
// }

View File

@ -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;

View File

@ -0,0 +1,3 @@
.piechartsize {
width: 100px;
}

View File

@ -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;

View File

@ -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} &nbsp;
<span className="title2Collapse">{title2}
&nbsp; {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;

View File

@ -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;
}
}
}

View File

@ -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} &nbsp; <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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}
} */

View File

@ -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)}>&lt;&lt;</button>
<button onClick={() => handleMonthChange(-1)}>&lt;</button>
<span>{currentDate.toLocaleString('default', { month: 'long' })} {currentDate.getFullYear()}</span>
<button onClick={() => handleMonthChange(1)}>&gt;</button>
<button onClick={() => handleYearChange(1)}>&gt;&gt;</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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -0,0 +1,9 @@
import React from 'react'
const PozoPublicDropdownAdd = () => {
return (
<div>PozoPublicDropdownAdd</div>
)
}
export default PozoPublicDropdownAdd

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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%);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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> &nbsp;{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>&nbsp; {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 &nbsp; </span>Free •{" "}
<span>6 | Jul | Saturday </span>
&nbsp;{" "}
<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;

View File

@ -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> &nbsp;{Size}</div>
</div>
)}
{showColor == "Y" && (
<div className="color">
Color : <div>&nbsp; {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 &nbsp; </span>Free •{" "}
<span>6 | Jul | Saturday </span>
&nbsp;{" "}
<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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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%);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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