486 lines
17 KiB
JavaScript
Executable File
486 lines
17 KiB
JavaScript
Executable File
import React, { useEffect, useState, useContext } from "react";
|
|
import { Link, useNavigate, useLocation } from "react-router-dom";
|
|
import { Container, Row, Col, Card, Button } from "react-bootstrap";
|
|
import Swiper from "react-id-swiper";
|
|
import "swiper/css/bundle";
|
|
import "swiper/bundle";
|
|
|
|
//Services
|
|
import dashboardService from "../services/Dashboard";
|
|
import contestServices from "../services/ContestServices";
|
|
import authService from "../services/Auth";
|
|
|
|
//Components
|
|
import PageComponent from "../components/PageComponent/PageComponent";
|
|
import PerformanceStatsContainer from "../components/DashboardPerformanceStats/PerformanceStatsContainer";
|
|
import PlaceholderCard from "../components/PlaceholderCard/PlaceholderCard";
|
|
import IconWrapper from "../components/IconWrapper/IconWrapper";
|
|
import UploadFile from "../components/UploadFile/UploadFile2";
|
|
import DashboardMagazinesContainer from "../components/DashboardMagazines/DashboardMagazinesContainer";
|
|
import DashboardContestsContainer from "../components/Contests/DashboardContestsContainer";
|
|
import CustomIcon from "../components/CustomIcon/CustomIcon";
|
|
import AppVersionUpdateModal from "../components/UI/AppVersionCheckAndUpdate/AppVersionUpdateModal";
|
|
import CustomImage from "../components/UI/CustomImage/CustomImage";
|
|
import MyCustomImage from "../components/UI/CustomImage/MyCustomImage";
|
|
import DashboardCompetitionContestsContainer from "../components/CompetitionContests/DashboardCompetitionContestsContainer";
|
|
import DashboardBanner from "../components/DashboardBanner/DashboardBanner";
|
|
import DashboardAdvertiseModal from "../components/DashboardAdvertiseModal/DashboardAdvertiseModal";
|
|
import OverlayNotificationModal from "../components/Notifications/OverlayNotificationModal";
|
|
import DashboardCampaignsContainer from "../components/DashboardCampaigns/DashboardCampaignsContainer";
|
|
|
|
//API
|
|
import notificationServices from "../services/NotificationServices";
|
|
|
|
//COntext
|
|
import AppContext from "../AppContext";
|
|
|
|
import { App as CapacitorApp } from "@capacitor/app";
|
|
|
|
function Dashboard() {
|
|
// console.log("Dashboard executed...");
|
|
const navigate = useNavigate();
|
|
const {getNotificationStats} = useContext(AppContext)
|
|
|
|
const location = useLocation();
|
|
|
|
const [wallBanners, setWallBanners] = useState([]);
|
|
const [otherBanners, setOtherBanners] = useState([]);
|
|
const [popupBanners, setPopupBanners] = useState([]);
|
|
const [appUpdatedInfo, setAppUpdatedInfo] = useState(null);
|
|
const [loadingBanner, setLoadingBanner] = useState(true);
|
|
const [loadingAppInfo, setLoadingAppInfo] = useState(true);
|
|
const [showAppVersionUpdateModal, setShowAppVersionUpdateModal] =
|
|
useState(false);
|
|
const [showDashboardAdvertisementModal, setShowDashboardAdvertisementModal] =
|
|
useState(false);
|
|
/** Unread overlay notifications; first item is shown in OverlayNotificationModal */
|
|
const [overlayNotificationQueue, setOverlayNotificationQueue] = useState([]);
|
|
|
|
function handleLogout() {
|
|
localStorage.clear();
|
|
navigate("/");
|
|
}
|
|
|
|
// App Version Update Confirmation Modal close
|
|
const handleCloseAppVersionUpdateModal = () => {
|
|
// console.log("Closing the modal");
|
|
setShowAppVersionUpdateModal(false);
|
|
};
|
|
//App Version Update Confirmation Modal Open
|
|
const handleShowAppVersionUpdateModal = () => {
|
|
setShowAppVersionUpdateModal(true);
|
|
// console.log("Opening the modal");
|
|
};
|
|
|
|
// Dashboard Advertisement Modal close
|
|
const handleCloseDashboardAdvertisementModal = () => {
|
|
// console.log("Closing the modal");
|
|
setShowDashboardAdvertisementModal(false);
|
|
};
|
|
//Dashboard Advertisement Modal Open
|
|
const handleShowDashboardAdvertisementModal = () => {
|
|
setShowDashboardAdvertisementModal(true);
|
|
// console.log("Opening the modal");
|
|
};
|
|
|
|
async function appInfoFromServer(data) {
|
|
// console.log(
|
|
// "async function appInfoFromServer called in Dashboard.jsx = ",
|
|
// JSON.stringify(data)
|
|
// );
|
|
// console.log("I am executed before CapacitorApp.getInfo()...");
|
|
const currentAppInfo = await CapacitorApp.getInfo();
|
|
// console.log("-- Outer currentAppInfo = ", JSON.stringify(currentAppInfo));
|
|
// console.log("I am executed after CapacitorApp.getInfo()...");
|
|
setLoadingAppInfo(true);
|
|
authService
|
|
.appInfoFromServer(data)
|
|
.then((res) => {
|
|
console.log("appInfoFromServer called == ", JSON.stringify(res.data));
|
|
if (res.data.status === "success") {
|
|
// console.log(
|
|
// "res from appInfoFromServer on SUCCESS =",
|
|
// JSON.stringify(res)
|
|
// );
|
|
const app_info = res.data?.data?.app_info;
|
|
|
|
// console.log(
|
|
// "-- currentAppInfo inside appInfoFromServer success = ",
|
|
// JSON.stringify(currentAppInfo)
|
|
// );
|
|
|
|
setAppUpdatedInfo(app_info);
|
|
const appCurrentVersion = parseFloat(
|
|
currentAppInfo?.version
|
|
// authService.getAppCurrentVersion()
|
|
).toFixed(2);
|
|
const appUpdatedVersion = parseFloat(app_info.min_version).toFixed(2);
|
|
setLoadingAppInfo(false);
|
|
// console.log("appCurrentVersion =", parseFloat(appCurrentVersion));
|
|
// console.log("appUpdatedVersion =", parseFloat(appUpdatedVersion));
|
|
if (parseFloat(appCurrentVersion) < parseFloat(appUpdatedVersion)) {
|
|
// console.log("Inside if");
|
|
handleShowAppVersionUpdateModal();
|
|
}
|
|
}
|
|
})
|
|
.catch((e) => {
|
|
console.log("ERROR in appInfoFromServer ", JSON.stringify(e));
|
|
setLoadingAppInfo(false);
|
|
setAppUpdatedInfo(null);
|
|
});
|
|
}
|
|
|
|
async function fetchAllNotificationsPages() {
|
|
const all = [];
|
|
let lastKeyParam = null;
|
|
for (;;) {
|
|
const res = await notificationServices.getAllNotifications(lastKeyParam);
|
|
if (res.data?.status !== "success") break;
|
|
const list = res.data?.data?.notifications ?? [];
|
|
all.push(...list);
|
|
const lastKeyVal = res.data?.data?.lastkey;
|
|
if (!lastKeyVal) break;
|
|
lastKeyParam = lastKeyVal;
|
|
}
|
|
return all;
|
|
}
|
|
|
|
async function loadUnreadOverlayNotifications() {
|
|
try {
|
|
const list = await fetchAllNotificationsPages();
|
|
const overlays = list.filter(
|
|
(n) => n?.notification_type === "overlay" && !n?.is_read
|
|
// (n) => n?.notification_type === "overlay"
|
|
);
|
|
console.log('overlays - ',overlays)
|
|
setOverlayNotificationQueue(overlays);
|
|
} catch (e) {
|
|
console.log("Error in loadUnreadOverlayNotifications = ", e);
|
|
setOverlayNotificationQueue([]);
|
|
}
|
|
}
|
|
|
|
const handleCloseOverlayNotificationModal = () => {
|
|
setOverlayNotificationQueue((prev) => prev.slice(1));
|
|
};
|
|
|
|
async function getDashboardWallBanners() {
|
|
// console.log("Inside Dashboard: getDashboardWallBanners()...");
|
|
dashboardService
|
|
.getDashboardWallBanners()
|
|
.then((res) => {
|
|
console.log("getDashboardWallBanners RES = ", res.data);
|
|
if (res.data.status === "success") {
|
|
// console.log(
|
|
// "Success in getDashboardWallBanners =",
|
|
// res.data.data.items
|
|
// );
|
|
let allBannerItems = res.data?.data?.items;
|
|
let mainBanners =
|
|
allBannerItems.length > 0
|
|
? allBannerItems.filter((item) => item.position === "default")
|
|
: [];
|
|
|
|
let otherBanners =
|
|
allBannerItems.length > 0
|
|
? allBannerItems.filter(
|
|
(item) =>
|
|
item.position !== "default" && item.position !== "popup"
|
|
)
|
|
: [];
|
|
let popupBanners =
|
|
allBannerItems.length > 0
|
|
? allBannerItems.filter((item) => item.position === "popup")
|
|
: [];
|
|
// console.log("mainBanners = ", mainBanners);
|
|
// console.log("otherBanners = ", otherBanners);
|
|
// console.log("popupBanners = ", popupBanners);
|
|
setWallBanners(mainBanners);
|
|
setOtherBanners(otherBanners);
|
|
setPopupBanners(popupBanners);
|
|
setLoadingBanner(false);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
setLoadingBanner(false);
|
|
setWallBanners([]);
|
|
setOtherBanners([]);
|
|
setPopupBanners([]);
|
|
console.log("Error in getDashboardWallBanners = ", error);
|
|
});
|
|
}
|
|
|
|
useEffect(() => {
|
|
// console.log("DASHBOARD useeffect");
|
|
getDashboardWallBanners();
|
|
|
|
//Calling getNotificationStats for latest status..
|
|
getNotificationStats();
|
|
loadUnreadOverlayNotifications();
|
|
// const showPopup = sessionStorage.getItem("showPopup");
|
|
// console.log("showPopup --- ", showPopup);
|
|
// if (!showPopup) {
|
|
// console.log("inside if (!showPopup)");
|
|
// if (popupBanners.length > 0) {
|
|
// console.log("inside if (popupBanners.length > 0)");
|
|
// setTimeout(() => {
|
|
// handleShowDashboardAdvertisementModal();
|
|
// sessionStorage.setItem("showPopup", true);
|
|
// }, 500);
|
|
// }
|
|
// }
|
|
|
|
appInfoFromServer({
|
|
platform: authService.getDevicePlatform(),
|
|
package_name: authService.getAppID(),
|
|
});
|
|
}, []);
|
|
|
|
const currentOverlayNotification = overlayNotificationQueue[0] ?? null;
|
|
|
|
useEffect(() => {
|
|
if (!currentOverlayNotification?.id) return;
|
|
notificationServices
|
|
.markReadNotification({ id: currentOverlayNotification.id })
|
|
.then((res) => {
|
|
if (res.data?.status === "success") {
|
|
getNotificationStats();
|
|
}
|
|
})
|
|
.catch((err) =>
|
|
console.log("Error marking overlay notification read = ", err)
|
|
);
|
|
}, [currentOverlayNotification?.id]);
|
|
|
|
useEffect(() => {
|
|
const showPopup = sessionStorage.getItem("showPopup");
|
|
// console.log("showPopup = ", showPopup);
|
|
if (!showPopup) {
|
|
if (popupBanners.length > 0) {
|
|
// console.log("popupBanners.length = ", popupBanners.length);
|
|
setTimeout(() => {
|
|
handleShowDashboardAdvertisementModal();
|
|
sessionStorage.setItem("showPopup", true);
|
|
}, 500);
|
|
}
|
|
}
|
|
}, [popupBanners]);
|
|
|
|
// useEffect(() => {
|
|
// console.log("### appStateChange listener useEffect");
|
|
// console.log("## location.pathname = ", location.pathname);
|
|
// // Listen for app resume
|
|
// const listener = CapacitorApp.addListener(
|
|
// "appStateChange",
|
|
// ({ isActive }) => {
|
|
// console.log("App state -- isActive -- ", isActive);
|
|
|
|
// const isOnDashboard = location.pathname === "/dashboard";
|
|
// console.log("location.pathname = ", location.pathname);
|
|
// if (isActive && isOnDashboard) {
|
|
// console.log("Inside if (isActive && isOnDashboard)");
|
|
// console.log("App resumed and on Dashboard. Refetching...");
|
|
// /** Note:
|
|
// * Don't use window.location.reload() on every app state change or page navigation — it's heavy and bypasses SPA benefits.
|
|
// * When Should You Use window.location.reload()?
|
|
// - After logout, to clear all component state and start fresh.
|
|
// - After major app updates (e.g., language change, user role change).
|
|
// - After token refresh fails, and you want to force re-init.
|
|
// */
|
|
// // window.location.reload();
|
|
// getDashboardWallBanners();
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// // Clean up listener on unmount
|
|
// return () => {
|
|
// listener.remove();
|
|
// };
|
|
// }, [location.pathname]);
|
|
|
|
const swiperParams = {
|
|
shouldSwiperUpdate: true,
|
|
rebuildOnUpdate: true,
|
|
// autoHeight: true,
|
|
effect: "slide",
|
|
// autoplay: {
|
|
// delay: 4000,
|
|
// disableOnInteraction: false,
|
|
// },
|
|
pagination: {
|
|
el: ".swiper-pagination",
|
|
clickable: true,
|
|
},
|
|
spaceBetween: 15,
|
|
grabCursor: true,
|
|
};
|
|
|
|
return (
|
|
<PageComponent className="dashboard-content-wrapper">
|
|
<Container className="mb-2 banner-container bg-primary-lighter">
|
|
<Row className="row-cols-2 gx-2 mb-1 justify-content-center px-4">
|
|
<Col>
|
|
<Card
|
|
className="card-theme border-0 shadow-sm h-100"
|
|
style={{ background: `var(--color-kudos-light)` }}
|
|
>
|
|
<Link to="/appreciations">
|
|
<Card.Body className="p-2 text-center d-flex align-items-center">
|
|
<div
|
|
className="pe-none icon-wrap wrap-sm"
|
|
style={{ background: `var(--color-kudos)` }}
|
|
>
|
|
<img
|
|
src={`/img/appreciations-icon.png`}
|
|
alt="Appreciations Icon"
|
|
/>
|
|
</div>
|
|
|
|
<span className="d-block font-12 ms-2 text-truncate">
|
|
Appreciations
|
|
</span>
|
|
</Card.Body>
|
|
</Link>
|
|
</Card>
|
|
</Col>
|
|
<Col>
|
|
<Card
|
|
className="card-theme border-0 shadow-sm h-100"
|
|
style={{ background: `var(--color-badges-light)` }}
|
|
>
|
|
<Link to="/badges">
|
|
<Card.Body className="p-2 text-center d-flex align-items-center">
|
|
<div
|
|
className="pe-none icon-wrap wrap-sm"
|
|
style={{ background: `var(--color-badges)` }}
|
|
>
|
|
<img src={`/img/badges-icon.png`} alt="Badges Icon" />
|
|
</div>
|
|
|
|
<span className="d-block font-12 ms-2">Badges</span>
|
|
</Card.Body>
|
|
</Link>
|
|
</Card>
|
|
</Col>
|
|
{/* <Col>
|
|
<Card
|
|
className="card-theme border-0 shadow-sm h-100"
|
|
style={{ background: `var(--color-rewards-light)` }}
|
|
>
|
|
<Link to="/rewards">
|
|
<Card.Body className="p-2 text-center d-flex align-items-center">
|
|
<div
|
|
className="pe-none icon-wrap wrap-sm"
|
|
style={{ background: `var(--color-rewards)` }}
|
|
>
|
|
<img src={`/img/rewards-icon.png`} alt="Rewards Icon" />
|
|
</div>
|
|
|
|
<span className="d-block font-12 ms-2">Rewards</span>
|
|
</Card.Body>
|
|
</Link>
|
|
</Card>
|
|
</Col> */}
|
|
</Row>
|
|
|
|
<section
|
|
className={`${wallBanners.length > 0 ? "py-1 pb-3 py-sm-3" : ""}`}
|
|
>
|
|
{loadingBanner && <PlaceholderCard type="banners" />}
|
|
{!loadingBanner && wallBanners.length > 0 && (
|
|
<DashboardBanner
|
|
loading={loadingBanner}
|
|
banners={wallBanners}
|
|
itemClassName="rounded-1 shadow-none"
|
|
className=""
|
|
/>
|
|
)}
|
|
</section>
|
|
</Container>
|
|
|
|
<PerformanceStatsContainer />
|
|
|
|
{otherBanners?.length > 0 && (
|
|
<section
|
|
className={`overflow-hidden ${
|
|
otherBanners.length > 0
|
|
? "py-3 px-4 py-sm-3 my-2 bg-red-lighter1"
|
|
: "d-none"
|
|
}`}
|
|
>
|
|
{loadingBanner && <PlaceholderCard type="banners" />}
|
|
{!loadingBanner && otherBanners.length > 0 && (
|
|
<DashboardBanner
|
|
loading={loadingBanner}
|
|
banners={otherBanners}
|
|
itemClassName="rounded-4 shadow-sm cta-slide"
|
|
/>
|
|
)}
|
|
</section>
|
|
)}
|
|
|
|
<DashboardCampaignsContainer />
|
|
|
|
<DashboardCompetitionContestsContainer />
|
|
|
|
<DashboardMagazinesContainer />
|
|
|
|
{/* <section
|
|
className={`overflow-hidden ${
|
|
wallBanners.length > 0 ? "py-4 px-4 py-sm-3 bg-gray-lighter2" : ""
|
|
}`}
|
|
>
|
|
{loadingBanner && <PlaceholderCard type="banners" />}
|
|
{!loadingBanner && wallBanners.length > 0 && (
|
|
<DashboardBanner
|
|
loading={loadingBanner}
|
|
banners={wallBanners}
|
|
itemClassName="rounded-4 shadow-sm cta-slide"
|
|
className=""
|
|
/>
|
|
)}
|
|
</section> */}
|
|
|
|
<DashboardContestsContainer />
|
|
|
|
{/* <Button
|
|
type="button"
|
|
className="btn-theme btn-icon btn-lg btn-secondary btn-quick-action position-fixed border-0 rounded-circle shadow"
|
|
style={{ bottom: 120, right: 10 }}
|
|
onClick={() => {
|
|
navigate("/quick-actions");
|
|
}}
|
|
>
|
|
<CustomIcon tag="add3" className="font-32" />
|
|
</Button> */}
|
|
|
|
<DashboardAdvertiseModal
|
|
show={showDashboardAdvertisementModal}
|
|
loading={loadingBanner}
|
|
banners={popupBanners}
|
|
handleClose={handleCloseDashboardAdvertisementModal}
|
|
/>
|
|
|
|
<AppVersionUpdateModal
|
|
show={showAppVersionUpdateModal}
|
|
loading={loadingAppInfo}
|
|
handleClose={handleCloseAppVersionUpdateModal}
|
|
platform={authService.getDevicePlatform()}
|
|
appUpdatedInfo={appUpdatedInfo}
|
|
/>
|
|
|
|
<OverlayNotificationModal
|
|
show={Boolean(currentOverlayNotification)}
|
|
handleClose={handleCloseOverlayNotificationModal}
|
|
data={currentOverlayNotification}
|
|
/>
|
|
|
|
<div className="d-block" style={{ height: 150 }}></div>
|
|
</PageComponent>
|
|
);
|
|
}
|
|
|
|
export default Dashboard;
|