extendedPlan

This commit is contained in:
Tamilselvan 2026-02-11 12:09:36 +05:30
parent 3d4cb2f9af
commit 2333bb74bd
3 changed files with 406 additions and 93 deletions

View File

@ -1,12 +1,13 @@
// AppRoutes.jsx
import React, { useEffect, useState, useRef, } from 'react';
import React, { useEffect, useState, useRef, lazy, } from 'react';
import { Routes, Route } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import ProtectedRoutes from './ProtectedRoutes';
import SelfBooking from './Pages/SelfBooking/SelfBooking.jsx'
import SelfBooking from './Pages/SelfBooking/SelfBooking.jsx'
import { isMobile, isIOS } from "react-device-detect";
// const { routesConfig }=lazy(()=>import('./routesConfig'));
// const { routesConfig } = lazy(() => import('./routesConfig'));
import { routesConfig } from './routesConfig';
import {
ChangeAppExpDateData,
@ -31,6 +32,10 @@ const subDirectory = import.meta.env.ENV_BASE_URL;
import "../ownLib/my-ui-lib.css"
import CustomerMenuPage from './Pages/Reports/MenuQRCode/CustomerMenuPage.jsx';
import WeightScaleApp from './Pages/BookingScreen/WeightscaleApp.jsx';
import { getPurchasedAppDetails, postInvoice } from './Features/BookingScreen/Pricing/Pricing.js';
import { sendSms } from './Features/Payment/PaymentDetails/PaymentDetails.js';
import ExtendSubscriptionModal from './Pages/ExtentedModal/ExtendSubscriptionModal.jsx';
const AppRoutes = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
@ -39,6 +44,7 @@ const AppRoutes = () => {
const prevRemainingDays = useRef(null);
const [sessionData, setSessionData] = useState(null);
const [devToolsOpen, setDevToolsOpen] = useState(false);
const [extendModel, setExtendModel] = useState(false);
useEffect(() => {
const handlePopState = (e) => {
const SessionId = getSession('SessionId');
@ -62,12 +68,12 @@ const AppRoutes = () => {
};
}, []);
//cmd it start
// useEffect(() => {
// sessionCheckFun()
// }, [navigate, ItemCard]);
//cmd it start
// useEffect(() => {
// sessionCheckFun()
// }, [navigate, ItemCard]);
//cmd it End
//cmd it End
useEffect(() => {
@ -118,15 +124,22 @@ const AppRoutes = () => {
dispatch(ChangeAppExpDateData(expData));
dispatch(changeHeightforExpDate(expData.RemainingDays));
if (
expData.RemainingDays < 1 &&
expData.RemainingHours < 1 &&
expData.RemainingMinutes < 1 &&
expData.RemainingSeconds < 1
) {
if (
UserType !== 'Super Admin' ||
UserType !== 'Super Admin User'
(UserType !== 'Super Admin' ||
UserType !== 'Super Admin User') && (expData?.PlanType?.toLowerCase() == "extend expired")
) {
console.log('Subscription expired, logging out...');
alert(
@ -134,8 +147,24 @@ const AppRoutes = () => {
);
Logout();
}
else if (
(UserType !== 'Super Admin' ||
UserType !== 'Super Admin User') && (expData?.PlanType?.toLowerCase() == "plan expired")
) {
setExtendModel(true)
// "Extend Expired"
// alert(
// 'Subscription expired, logging out. Redirecting to login...'
// );
// Logout();
}
}
}
} else {
console.log('No subscription data found, logging out...');
alert(
@ -170,95 +199,203 @@ const AppRoutes = () => {
console.error('Logout failed:', error);
}
};
// mohan
// useEffect(() => {
// if (isMobile || isIOS) {
// console.log("📱 Mobile/iOS device skipping DevTools detection");
// return;
// }
// const checkDevTools = setInterval(() => {
// if (devtools.isOpen && !devToolsOpen) {
// setDevToolsOpen(true);
// document.body.innerHTML =
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
// }
// else if (!devtools.isOpen && devToolsOpen) {
// setDevToolsOpen(false);
// setTimeout(() => {
// window.location.reload();
// }, 100);
// clearInterval(checkDevTools);
// }
// if (!devtools.isOpen) {
// let before = performance.now();
// let after = performance.now();
// let executionDelay = after - before;
// if (executionDelay > 100) {
// setDevToolsOpen(true);
// document.body.innerHTML =
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
// } else {
// setDevToolsOpen(false);
// }
// }
// }, 1000);
// return () => clearInterval(checkDevTools);
// }, [devToolsOpen]);
const sessionCheckFun = async () => {
const UserId = getSession('UserId');
const sessionId = getSession('SessionId');
const IsLogout = getSession('Mode');
let encryptedLoginType = TokendecryptedValuesFun(
sessionStorage.getItem('LoginType')
);
if (encryptedLoginType != 'Kiosk') {
const res = await dispatch(checkSession({ UserId, sessionId })).unwrap();
if (res?.data?.statusCode === 1) {
if (res?.data?.response === 'False') {
if (IsLogout !== 'Logout') {
alert('Session invalid. Redirecting to login...');
}
clearSession();
window.location.replace(commonSubDir);
// mohan
// useEffect(() => {
// if (isMobile || isIOS) {
// console.log("📱 Mobile/iOS device skipping DevTools detection");
// return;
// }
// const checkDevTools = setInterval(() => {
// if (devtools.isOpen && !devToolsOpen) {
// setDevToolsOpen(true);
// document.body.innerHTML =
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
// }
// else if (!devtools.isOpen && devToolsOpen) {
// setDevToolsOpen(false);
// setTimeout(() => {
// window.location.reload();
// }, 100);
// clearInterval(checkDevTools);
// }
// if (!devtools.isOpen) {
// let before = performance.now();
// let after = performance.now();
// let executionDelay = after - before;
// if (executionDelay > 100) {
// setDevToolsOpen(true);
// document.body.innerHTML =
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
// } else {
// setDevToolsOpen(false);
// }
// }
// }, 1000);
// return () => clearInterval(checkDevTools);
// }, [devToolsOpen]);
const sessionCheckFun = async () => {
const UserId = getSession('UserId');
const sessionId = getSession('SessionId');
const IsLogout = getSession('Mode');
let encryptedLoginType = TokendecryptedValuesFun(
sessionStorage.getItem('LoginType')
);
if (encryptedLoginType != 'Kiosk') {
const res = await dispatch(checkSession({ UserId, sessionId })).unwrap();
if (res?.data?.statusCode === 1) {
if (res?.data?.response === 'False') {
if (IsLogout !== 'Logout') {
alert('Session invalid. Redirecting to login...');
}
clearSession();
window.location.replace(commonSubDir);
}
}
};
}
};
// ---------------- DATE UTILS ----------------
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
}
function addDays(dateString, days) {
// Make it ISO-safe for iOS / WebView
const isoDate = dateString.replace(' ', 'T');
const currentDate = new Date(isoDate);
currentDate.setDate(currentDate.getDate() + Number(days));
return formatDate(currentDate);
}
// ---------------- MAIN FUNCTION ----------------
const freeExtend = async () => {
try {
const { CompId, AppId, BranchId, UserType } = sessionData;
const UserId = getSession('UserId');
// Current date
const now = new Date();
const currentDate = formatDate(now);
// 1 Get purchased app details
const response1 = await dispatch(
getPurchasedAppDetails({ AppId, UserId })
).unwrap();
const PurchasedDetails = response1?.data?.data;
if (!PurchasedDetails || !PurchasedDetails.length) {
console.error('No purchased details found');
return;
}
// 2 Prepare post data
const postData = {
UserId: UserId,
AppId: AppId,
PricingId: PurchasedDetails[0]?.PricingId,
PurDate: currentDate,
NoofDays: 30,
PaymentMode: 27,
PaymentStatus: 'S',
LicenseStatus: PurchasedDetails[0]?.LicenseStatus,
Price: PurchasedDetails[0]?.Price ?? 0,
TaxId: PurchasedDetails[0]?.TaxId ?? 0,
NetPrice: PurchasedDetails[0]?.ExistingPlanNetPrice ?? 0,
ValidityStart: currentDate,
ValidityEnd: addDays(
currentDate,
PurchasedDetails[0]?.NoOfDays
),
CreatedBy: UserId,
TaxAmount: PurchasedDetails[0]?.TaxAmount ?? 0,
MobileNo: getSession('MobileNo'),
MailId: 'ts@gmmail.com',
Type: "FreeExtend"
};
// 3 Post invoice
const response = await dispatch(postInvoice(postData)).unwrap();
// 4 Send SMS if required
if (response?.data?.statusCode === 1 && response?.data?.SMSbody) {
await dispatch(
sendSms({ body: response.data.SMSbody })
);
setExtendModel(false)
}
} catch (error) {
console.error('freeExtend error:', error);
}
};
const handleCancel = () => {
Logout();
setExtendModel(false)
}
const handlePay = () => {
setExtendModel(false)
let AppName = getSession("AppName")
navigate(`${subDirectory}PricingPage`, { state: { AppName: AppName } });
}
if (extendModel) {
return (
<ExtendSubscriptionModal
onClose={handleCancel}
onPayNow={handlePay}
onContinueWithCredits={freeExtend}
/>
);
}
return (
<Routes>
<Route
path={`${subDirectory}selfBooking/:SelfBookingId`}
element={<SelfBooking />}
/>
<Route
path={`${subDirectory}MenuQRCode`}
element={<CustomerMenuPage />}
/>
<>
<Routes>
<Route
path={`${subDirectory}weightscaleapp`}
element={<WeightScaleApp />}
/>
<Route path={`${subDirectory}kioskSelfBooking`} element={<KisokSelBooking />} />
<Route
path= {`${subDirectory}kiosk-individual-self-booking`}
element={<IndividualBooking />}
/>
<Route
path="/*"
element={<ProtectedRoutes routesConfig={routesConfig} />}
/>
</Routes>
path={`${subDirectory}selfBooking/:SelfBookingId`}
element={<SelfBooking />}
/>
<Route
path={`${subDirectory}MenuQRCode`}
element={<CustomerMenuPage />}
/>
<Route
path={`${subDirectory}weightscaleapp`}
element={<WeightScaleApp />}
/>
<Route path={`${subDirectory}kioskSelfBooking`} element={<KisokSelBooking />} />
<Route
path={`${subDirectory}kiosk-individual-self-booking`}
element={<IndividualBooking />}
/>
<Route
path="/*"
element={<ProtectedRoutes routesConfig={routesConfig} />}
/>
</Routes>
</>
);
};

View File

@ -0,0 +1,48 @@
import { Tooltip } from "antd";
import "./extendSubscribtionModel.scss";
import { IoClose } from "react-icons/io5";
const ExtendSubscriptionModal = ({
onClose,
onPayNow,
onContinueWithCredits
}) => {
return (
<div className="extendmodal-backdrop">
<div className="extendmodal">
<div className="extendModalheader">
<h2>Subscription Expired</h2>
<Tooltip placement="left" title="Close">
<IoClose
onClick={onClose}
className="extendModalClose"
size={20}
/>
</Tooltip>
</div>
<p>
Your plan has expired. Please extend to continue using the app.
</p>
<div className="extendmodal-actions">
<button
className="CreditsBTN"
onClick={onContinueWithCredits}
>
Continue with Credits
</button>
<button
className="PayNowBTN"
onClick={onPayNow}
>
Pay Now
</button>
</div>
</div>
</div>
);
};
export default ExtendSubscriptionModal;

View File

@ -0,0 +1,128 @@
.extendmodal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}
.extendmodal {
background: #fff;
padding: 20px;
border-radius: 12px;
width: 450px;
font-family: "Poppins", sans-serif;
h2 {
font-size: 22px;
font-weight: 600;
}
p {
font-size: 14px;
margin-top: 8px;
color: #555;
width: 90%;
}
@media (max-width: 600px) {
width: 90% !important;
}
}
.extendModalheader {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
margin-bottom: 12px;
gap: 1rem;
}
.extendModalClose {
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
padding: 3px;
background-color: #ffecec;
color: #ef4444;
transition: all 0.2s;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #ffd5d5;
}
}
.extendmodal-actions {
margin: 2rem 0 1rem 0;
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
}
/* Common button style */
.PayNowBTN,
.CreditsBTN {
padding: 8px 14px;
font-family: "Poppins", sans-serif;
border: none;
outline: none;
font-weight: 500;
font-size: 14px;
cursor: pointer;
border-radius: 4px;
transition: all 0.2s;
}
/* Pay Now */
.PayNowBTN {
background-color: #10b981;
color: #fff;
padding: 8px 22px;
animation: payNowPulse 1.8s ease-in-out infinite;
transition: transform 0.25s ease, box-shadow 0.25s ease;
&:hover {
background-color: #10b981;
animation-play-state: paused;
transform: scale(1.08);
}
}
/* Continue with Credits */
.CreditsBTN {
background-color: #f3f4f6;
color: #111;
border: 1px solid #d1d5db;
&:hover {
background-color: #e5e7eb;
}
}
/* Attention animation */
@keyframes payNowPulse {
0% {
transform: scale(1);
box-shadow: 0 0 0 0 #05c283;
}
50% {
transform: scale(1.07);
box-shadow: 0 0 0 8px #1292ee00;
}
100% {
transform: scale(1);
box-shadow: 0 0 0 0 #1292ee00;
}
}