+
+
{
>
<>{row?.original.name}>
-
-
- {row.original.website}
-
>
@@ -118,7 +109,7 @@ const ClinicsList = () => {
{
enableColumnFilter: false,
enableSorting: true,
- size: 100,
+ size: 150,
accessorKey: "update_time",
header: "Req.Raised On",
Cell: ({ row }) => (
@@ -132,43 +123,43 @@ const ClinicsList = () => {
),
},
// .................send email column..................
- {
- enableColumnFilter: false,
- enableSorting: true,
- accessorKey: "lastEmailSent",
- size: 190,
- header: "Send Mail",
- Cell: ({ row }) => (
- <>
- {(row.original.status === CLINIC_STATUS.REJECTED ||
- row.original.status === CLINIC_STATUS.ON_HOLD) && (
-
-
handleEmailSent(row)}
- className={classes.sendEmailStatus}
- >
-
- {row.original.status === CLINIC_STATUS.ON_HOLD &&
- "Resend On Hold Mail"}
- {row.original.status === CLINIC_STATUS.REJECTED &&
- "Resend Rejection Mail"}
-
-
-
- Last Sent On:
- {format(
- new Date(row?.original?.lastEmailSent),
- "dd MMM yyyy"
- )}
-
-
- )}
- >
- ),
- },
+ // {
+ // enableColumnFilter: false,
+ // enableSorting: true,
+ // accessorKey: "lastEmailSent",
+ // size: 190,
+ // header: "Send Mail",
+ // Cell: ({ row }) => (
+ // <>
+ // {(row.original.status === CLINIC_STATUS.REJECTED ||
+ // row.original.status === CLINIC_STATUS.ON_HOLD) && (
+ //
+ //
handleEmailSent(row)}
+ // className={classes.sendEmailStatus}
+ // >
+ //
+ // {row.original.status === CLINIC_STATUS.ON_HOLD &&
+ // "Resend On Hold Mail"}
+ // {row.original.status === CLINIC_STATUS.REJECTED &&
+ // "Resend Rejection Mail"}
+ //
+ //
+ //
+ // Last Sent On:
+ // {format(
+ // new Date(row?.original?.lastEmailSent),
+ // "dd MMM yyyy"
+ // )}
+ //
+ //
+ // )}
+ // >
+ // ),
+ // },
// .................location column..................
{
- size: 100,
+ size: 150,
enableColumnFilter: false,
enableSorting: true,
accessorKey: "city",
@@ -196,7 +187,7 @@ const ClinicsList = () => {
accessorFn: ({ status }) => (
<>
{
header: "Clinic Name",
Cell: ({ row }) => (
<>
-
- {/*

*/}
-
-
+
+
{
>
<>{row?.original.name}>
-
- {row.original.website}
-
>
diff --git a/src/views/Dashboard/components/PaymentConfig.jsx b/src/views/Dashboard/components/PaymentConfig.jsx
index 6f73484..359f0d3 100644
--- a/src/views/Dashboard/components/PaymentConfig.jsx
+++ b/src/views/Dashboard/components/PaymentConfig.jsx
@@ -146,13 +146,13 @@ const PaymentConfig = () => {
$,
- endAdornment: /min,
+ endAdornment: /calls,
}}
variant="outlined"
/>
diff --git a/src/views/MasterData/index.jsx b/src/views/MasterData/index.jsx
index bf3e629..8d1b3d8 100644
--- a/src/views/MasterData/index.jsx
+++ b/src/views/MasterData/index.jsx
@@ -143,7 +143,7 @@ const MasterDataManagement = () => {
const handleEdit = async (row) => {
setEditId(row.original.id); // Store the ID for update operation
- setType(row.original.type);
+ setType(row.original.type.charAt(0).toUpperCase() + row.original.type.slice(1));
setOpenDialog(true);
};
diff --git a/src/views/Signup/YourDetailsForm.jsx b/src/views/Signup/YourDetailsForm.jsx
index 5cc1599..ee2f34b 100644
--- a/src/views/Signup/YourDetailsForm.jsx
+++ b/src/views/Signup/YourDetailsForm.jsx
@@ -346,7 +346,10 @@ function YourDetailsForm() {
pushNotification(response?.data?.message, NOTIFICATION.ERROR);
return;
}
- pushNotification("OTP sent successfully to your email", NOTIFICATION.SUCCESS);
+ pushNotification(
+ "OTP sent successfully to your email",
+ NOTIFICATION.SUCCESS
+ );
};
const verifyOTP = async (e) => {
@@ -393,8 +396,9 @@ function YourDetailsForm() {
return;
}
pushNotification(response?.data?.message, NOTIFICATION.SUCCESS);
+ localStorage.setItem("temp_signup_token", response?.data?.data?.token);
// open new page for stripe payment from url
- const newWindow = window.open(response?.data?.data, "_blank", "noopener,noreferrer");
+ window.open(response?.data?.data?.url, "_blank", "noopener,noreferrer");
// if (!newWindow || newWindow.closed || typeof newWindow.closed === 'undefined') {
// // Fallback in case popup is blocked
// window.location.href = response?.data?.data;
diff --git a/src/views/WaitingPage/index.jsx b/src/views/WaitingPage/index.jsx
new file mode 100644
index 0000000..7e85f66
--- /dev/null
+++ b/src/views/WaitingPage/index.jsx
@@ -0,0 +1,436 @@
+import React, { useState, useEffect, useRef } from "react";
+import {
+ Box,
+ Card,
+ CardContent,
+ Typography,
+ Button,
+ CircularProgress,
+ Avatar,
+ LinearProgress,
+ Chip,
+ Stack,
+ Paper,
+ Divider,
+ Alert,
+} from "@mui/material";
+import {
+ CheckCircle,
+ Schedule,
+ ArrowBack,
+ OpenInNew,
+ Error,
+ Refresh,
+} from "@mui/icons-material";
+import { green, blue, red, grey } from "@mui/material/colors";
+import { API_BASE_URL } from "../../common/envVariables";
+import { useNavigate } from "react-router-dom";
+
+const PaymentSuccessPage = () => {
+ const [status, setStatus] = useState("processing"); // 'processing', 'success', 'error'
+ const [invoiceUrl, setInvoiceUrl] = useState("");
+ const [timeElapsed, setTimeElapsed] = useState(0);
+ const [token, setToken] = useState("");
+ const navigate = useNavigate();
+
+ // Use refs to track active polling and timer
+ const pollingRef = useRef(null);
+ const timerRef = useRef(null);
+ const isPollingActiveRef = useRef(false);
+
+ const checkPaymentStatus = async () => {
+ try {
+ if (!token || !isPollingActiveRef.current) {
+ return;
+ }
+
+ const response = await fetch(`${API_BASE_URL}/stripe/get-invoice`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${token}`,
+ },
+ });
+
+ const data = await response.json();
+
+ if (data.data && isPollingActiveRef.current) {
+ // Success - stop polling and timer
+ isPollingActiveRef.current = false;
+ if (pollingRef.current) {
+ clearTimeout(pollingRef.current);
+ pollingRef.current = null;
+ }
+ if (timerRef.current) {
+ clearInterval(timerRef.current);
+ timerRef.current = null;
+ }
+
+ setStatus("success");
+ setInvoiceUrl(data.data);
+ } else if (isPollingActiveRef.current) {
+ // Still processing, check again in 10 seconds
+ pollingRef.current = setTimeout(() => checkPaymentStatus(), 10000);
+ }
+ } catch (error) {
+ console.error("Error checking payment status:", error);
+ if (isPollingActiveRef.current) {
+ // Retry after 10 seconds on error
+ pollingRef.current = setTimeout(() => checkPaymentStatus(), 10000);
+ }
+ }
+ };
+
+ const startTimer = () => {
+ timerRef.current = setInterval(() => {
+ setTimeElapsed(prev => prev + 1);
+ }, 1000);
+ };
+
+ const stopPollingAndTimer = () => {
+ isPollingActiveRef.current = false;
+
+ if (pollingRef.current) {
+ clearTimeout(pollingRef.current);
+ pollingRef.current = null;
+ }
+
+ if (timerRef.current) {
+ clearInterval(timerRef.current);
+ timerRef.current = null;
+ }
+ };
+
+ const openInvoice = () => {
+ // Stop all polling and timer before navigation
+ stopPollingAndTimer();
+
+ if (invoiceUrl) {
+ window.open(invoiceUrl, "_blank");
+ }
+
+ // Clean up and navigate
+ localStorage.removeItem("temp_signup_token");
+ setToken("");
+ navigate("/auth/login");
+ };
+
+ const goToLogin = () => {
+ stopPollingAndTimer();
+ localStorage.removeItem("temp_signup_token");
+ navigate("/auth/login");
+ };
+
+ const goToDashboard = () => {
+ stopPollingAndTimer();
+ navigate("/dashboard");
+ };
+
+ const handleRetry = () => {
+ stopPollingAndTimer();
+ setStatus("processing");
+ setTimeElapsed(0);
+ isPollingActiveRef.current = true;
+ startTimer();
+ checkPaymentStatus();
+ };
+
+ const formatTime = (seconds) => {
+ const mins = Math.floor(seconds / 60);
+ const secs = seconds % 60;
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
+ };
+
+ useEffect(() => {
+ const storedToken = localStorage.getItem("temp_signup_token");
+ if (!storedToken) {
+ navigate("/auth/login");
+ return;
+ }
+
+ setToken(storedToken);
+ isPollingActiveRef.current = true;
+ startTimer();
+
+ // Start checking payment status once token is set
+ const initializeChecking = async () => {
+ if (storedToken) {
+ checkPaymentStatus();
+ }
+ };
+
+ initializeChecking();
+
+ // Cleanup function
+ return () => {
+ stopPollingAndTimer();
+ };
+ }, []); // Remove token from dependency array to avoid infinite loop
+
+ // Separate useEffect for when token changes
+ useEffect(() => {
+ if (token && status === "processing" && !isPollingActiveRef.current) {
+ isPollingActiveRef.current = true;
+ checkPaymentStatus();
+ }
+ }, [token]);
+
+ if (status === "processing") {
+ return (
+
+
+
+ {/* Header */}
+
+
+
+
+
+ Processing Your Payment
+
+
+
+ Please wait while we confirm your subscription and prepare your
+ invoice...
+
+
+ {/* Loading Animation */}
+
+
+
+ Time elapsed: {formatTime(timeElapsed)}
+
+
+
+ {/* Progress Steps */}
+
+
+
+
+
+ Payment Submitted
+
+
+
+
+
+
+ Confirming Payment
+
+
+
+
+
+
+ Generating Invoice
+
+
+
+
+
+ {/* Back Button */}
+ }
+ onClick={goToLogin}
+ sx={{ mt: 2 }}
+ >
+ Back to Login
+
+
+
+
+ );
+ }
+
+ if (status === "success") {
+ return (
+
+
+
+ {/* Success Header */}
+
+
+
+
+
+ Payment Successful!
+
+
+
+ Your subscription has been activated and your invoice is ready.
+
+
+ {/* Processing Time */}
+
+
+ {/* Action Buttons */}
+
+ }
+ onClick={openInvoice}
+ sx={{ py: 1.5 }}
+ >
+ View Invoice
+
+
+
+
+
+
+ }
+ onClick={goToLogin}
+ >
+ Back to Login
+
+
+
+
+
+ );
+ }
+
+ if (status === "error") {
+ return (
+
+
+
+ {/* Error Header */}
+
+
+
+
+
+ Payment Processing Error
+
+
+
+ We encountered an issue while processing your payment. Please try
+ again or contact support.
+
+
+ {/* Action Buttons */}
+
+ }
+ onClick={handleRetry}
+ sx={{ py: 1.5 }}
+ >
+ Try Again
+
+
+ }
+ onClick={goToLogin}
+ sx={{ py: 1.5 }}
+ >
+ Back to Login
+
+
+
+
+
+ );
+ }
+};
+
+export default PaymentSuccessPage;
\ No newline at end of file