initially setupuser can update or revnew plan

This commit is contained in:
pramod.mahajan 2025-10-30 00:18:37 +05:30
parent d81ffe86b7
commit 7b4d19a932
7 changed files with 376 additions and 159 deletions

View File

@ -145,7 +145,7 @@
}
.text-xxs { font-size: 0.55rem; } /* 8px */
.text-xs { font-size: 0.75rem; } /* 12px */
.text-sm { font-size: 0.875rem; } /* 14px */
.text-sm { font-size: 0.675rem; } /* 14px */
.text-base { font-size: 1rem; } /* 16px */
.text-lg { font-size: 1.125rem; } /* 18px */
.text-xl { font-size: 1.25rem; } /* 20px */

View File

@ -1,12 +1,12 @@
import React, { useEffect, useState } from "react";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { VIEW_DOCUMENT } from "../../utils/constants";
import { SUPPER_TENANT, VIEW_DOCUMENT } from "../../utils/constants";
import { useProfile } from "../../hooks/useProfile";
import { useParams } from "react-router-dom";
const EmployeeNav = ({ onPillClick, activePill }) => {
const { employeeId } = useParams();
const [isAbleToViewDocuments, setIsAbleToViewDocuments] = useState(false);
const isSuperUser = useHasUserPermission(SUPPER_TENANT)
const canViewDocuments = useHasUserPermission(VIEW_DOCUMENT);
const { profile } = useProfile();
@ -24,6 +24,7 @@ const EmployeeNav = ({ onPillClick, activePill }) => {
icon: "bx bx-file",
label: "Documents",
},
(isSuperUser && { key: "setting", icon: "bx bx-cog", label: "Setting" }),
// { key: "activities", icon: "bx bx-grid-alt", label: "Activities" },
].filter(Boolean);
return (

View File

@ -0,0 +1,51 @@
import React, { useState } from "react";
import SubscriptionOverview from "./SubscriptionOverview";
const ManageSubscription = () => {
const [activeTab, setActiveTab] = useState("plan");
const renderContent = () => {
switch (activeTab) {
case "plan":
return <SubscriptionOverview/>
case "billing":
return <div className="p-3">💳 <strong>Billing Info</strong> section content goes here.</div>;
default:
return null;
}
};
return (
<div className="card page-min-h">
<div className=" border-bottom-0 pb-0 overflow-auto p-2">
<ul className="nav nav-tabs">
<li className="nav-item text-sm">
<small
className={` nav-link ${activeTab === "plan" ? "active" : ""}`}
onClick={() => setActiveTab("plan")}
>
Subscription OverView
</small>
</li>
<li className="nav-item">
<small
className={`nav-link ${activeTab === "billing" ? "active" : ""}`}
onClick={() => setActiveTab("billing")}
>
Manage Subscription
</small>
</li>
</ul>
</div>
<div className="px-2 py-1">
{renderContent()}
</div>
</div>
);
};
export default ManageSubscription;

View File

@ -0,0 +1,87 @@
import React from 'react'
import Avatar from '../../common/Avatar'
const SubscriptionOverview = () => {
return (
<div className='container-md text-start'>
<div className='row d-flex justify-content-between py-1'>
<small className='fw-semibold fs-sm-6 fs-md-5'>Overview</small>
<p className='text-muted m-0'>Summerizees all your payments and subscription for the purchsed Application</p>
<hr className="divider border-2 my-2" />
<div className='col-md-4 d-flex flex-column gap-6'>
<div className=''>
<p className=' d-bolck fw-semibold fs-6'>Contact Details</p>
<small className='d-bolck'>Who should we contact if neccessary ?</small>
</div>
<p className='fw-semibold text-primary'>Manage Contact Details</p>
</div>
<div className='col-md-6 '>
<div className='row border'>
<div className='col-6'>
<div className='d-flex flex-row gap-2 align-items-center p-2'>
<Avatar size='md' firstName={"pramod"} lastName={"Mahajan"}/>
<div >
<small className='d-block fw-semibold fs-6'>Pramod Mahajan</small>
<small className='text-muted text-tiny'>pramod.mahajan@marcoaiot.com</small>
<p className='my-3'>Marco Aiot Pvt Limited</p>
</div>
<div className="vr border-2"></div>
</div>
</div>
<div className='col-6 text-center align-items-center my-auto'>
<a className='text-primary'>Update Details</a>
</div>
</div>
</div>
</div>
<hr className="divider border-2 my-2" />
<div className='row d-flex justify-content-between py-1'>
<div className='col-md-4 d-flex flex-column gap-6'>
<div className=''>
<p className=' d-bolck fw-semibold fs-6'>Current Plan</p>
<small className='d-bolck'>You can update your plan anytime for best benifit from the product and track your projct</small>
</div>
<p className='fw-semibold text-primary'>Switch Plan</p>
</div>
<div className='col-md-6 '>
<div className='row border bg-light-primary p-2'>
<div className='d-flex justify-content-between align-items-center'>
<div className='d-flex flex-row gap-4'>
<small><i className='bx bxs-package'></i></small>
<small className='fw-bold'>Super Package</small>
<small className='fw-bold text-primary'> 5999</small>
</div>
<span className=' bg-primary rounded-circle'><i className='bx bx-md bx-check text-white'></i></span>
</div>
<div className='mt-3'>
<p className='m-0 ms-6 text-muted text-tiny'>Includes up to 100 userss, 10GB individual cloud storage and access maximum features</p>
</div>
</div>
</div>
</div>
<hr className="divider border-2 my-2" />
<div className='row d-flex justify-content-between py-1'>
<div className='col-md-4 d-flex flex-column gap-6'>
<div className=''>
<p className=' d-bolck fw-semibold fs-6'>Billing History</p>
<small className='d-bolck'>Sumary on the payment history for the subscription plan of the application</small>
</div>
<p className='fw-semibold text-primary'>Billing History</p>
</div>
<div className='col-md-6 '>
</div>
</div>
</div>
)
}
export default SubscriptionOverview

View File

@ -25,9 +25,11 @@ const ProcessedPayment = ({
}) => {
const { planName } = useParams();
const { details: client, planId: selectedPlanId,frequency } = useSelector(
(store) => store.localVariables.selfTenant
);
const {
details: client,
planId: selectedPlanId,
frequency,
} = useSelector((store) => store.localVariables.selfTenant);
const [selectedPlan, setSelectedPlan] = useState(null);
const [currentPlan, setCurrentPlan] = useState(null);
const [failPayment, setFailPayment] = useState(null);
@ -35,7 +37,7 @@ const ProcessedPayment = ({
const {
data: plans,
isError: isPlanError,
isLoading,
isLoading,isError,isRefetching,refetch
} = useSubscription(frequency);
useEffect(() => {
if (!plans || !selectedPlanId) return;
@ -54,12 +56,10 @@ const ProcessedPayment = ({
const { mutate: MakePayment, isPending } = useMakePayment(
(response) => {
unblockUI();
onNext(response);
},
(fail) => {
unblockUI();
setFailPayment(fail);
onNext(fail);
@ -88,7 +88,7 @@ const ProcessedPayment = ({
setCurrentStep,
setStepStatus((prev) => ({ ...prev, 2: "pending", 3: "pending" }));
setCurrentStep(2);
}
};
// useEffect(() => {
// if (!client || Object.keys(client).length === 0) {
@ -154,21 +154,49 @@ const ProcessedPayment = ({
and help you maximize productivity.
</p>
</div>
{isLoading ? <SelectedPlanSkeleton/> : (<>
{isError && (
<div className="col-12 col-md text-center">
<p className="text-muted">{error?.message}</p>
<small>{error?.name}</small>
<small
className={`text-muted ${
isRefetching ? "cursor-notallowed" : "cursor-pointer"
}`}
onClick={refetch}
>
{isRefetching ? (
<>
<i
className={`bx bx-loader-alt ${
isRefetching ? "bx-spin" : ""
}`}
></i>{" "}
Retrying...
</>
) : (
"Try to refetch"
)}
</small>
</div>
)}
{isLoading ? (
<SelectedPlanSkeleton />
) : (
<>
{selectedPlan && (
<div className="col-12 col-md-8 mb-md-3 mb-2">
<div className="custom-option custom-option-basic text-start w-100 bg-light-primary border border-primary shadow-md p-3 rounded-3">
<div className="custom-option-header d-flex justify-content-between align-items-center">
<span className="h6 mb-0">{selectedPlan?.planName}</span>
<span className="h6 mb-0">
{selectedPlan?.planName}
</span>
<i className="bx bx-check-circle text-primary fs-4"></i>
</div>
<div className="d-flex justify-content-between mt-1">
<small className="text-muted">
{selectedPlan?.currency?.symbol} {selectedPlan?.price} /
{frequencyLabel(frequency,false)}
{selectedPlan?.currency?.symbol} {selectedPlan?.price}{" "}
/{frequencyLabel(frequency, false)}
</small>
</div>
@ -269,7 +297,10 @@ const ProcessedPayment = ({
<div className="d-flex justify-content-between">
<h6 className="fs-6 m-0">Duration</h6>
<h5 className="fs-6 m-0">
{frequencyLabel(selectedPlan?.frequency, true)}
{frequencyLabel(
selectedPlan?.frequency,
true
)}
</h5>
</div>
@ -278,7 +309,8 @@ const ProcessedPayment = ({
<h5 className="fs-3">
{formatFigure(selectedPlan?.price, {
type: "currency",
currency: selectedPlan?.currency.currencyCode,
currency:
selectedPlan?.currency.currencyCode,
})}
</h5>
</div>
@ -289,21 +321,23 @@ const ProcessedPayment = ({
</div>
</div>
)}
</>)}
</>
)}
</div>
</div>
<div className="col-12 col-md-4 ">
{client && (
<div className="text-start">
<h6 className="fs-md-4 my-4">Confirm your organization details.</h6>
<h6 className="fs-md-4 my-4">
Confirm your organization details.
</h6>
<div className="row g-2">
<div className="col-sm-6 mb-2">
<strong>Name:</strong>
</div>
<div className="col-sm-6 mb-2">{client.firstName} {client.lastName}</div>
<div className="col-sm-6 mb-2">
{client.firstName} {client.lastName}
</div>
<div className="col-sm-6">
<strong>Email:</strong>
@ -320,8 +354,6 @@ const ProcessedPayment = ({
</div>
<div className="col-sm-6 mb-2">{client.organizationName}</div>
<div className="col-sm-6 mb-2">
<strong>Onboarding Date:</strong>
</div>
@ -356,7 +388,14 @@ const ProcessedPayment = ({
className="btn btn-label-primary d-flex align-items-center me-2"
onClick={() => ProcessToPayment(currentPlan?.price)}
>
{isPending ? <span><i className='bx bx-loader-alt bx-md bx-spin me-2'></i>Please Wait...</span> : "Processed To Payment"}
{isPending ? (
<span>
<i className="bx bx-loader-alt bx-md bx-spin me-2"></i>Please
Wait...
</span>
) : (
"Processed To Payment"
)}
</button>
</div>
</div>

View File

@ -5,6 +5,7 @@ import { useSubscription } from "../../hooks/useAuth";
import { formatFigure, frequencyLabel } from "../../utils/appUtils";
import { setSelfTenant } from "../../slices/localVariablesSlice";
import SelectedPlanSkeleton from "./SelectedPlanSkeleton";
import { error } from "pdf-lib";
const SelectPlan = ({ currentStep, setStepStatus, onNext }) => {
const { frequency, planName } = useParams();
@ -22,8 +23,11 @@ const SelectPlan = ({ currentStep, setStepStatus, onNext }) => {
const {
data: plans,
isError: isPlanError,
isError,
isLoading,
error,
refetch,
isRefetching,
} = useSubscription(selectedFrequency);
const handleChange = (e) => setSelectedPlan(e.target.value);
@ -137,6 +141,32 @@ const SelectPlan = ({ currentStep, setStepStatus, onNext }) => {
</div>
</div>
{isError && (
<div className="col-12 col-md text-center">
<p className="text-muted">{error?.message}</p>
<small>{error?.name}</small>
<small
className={`text-muted ${
isRefetching ? "cursor-notallowed" : "cursor-pointer"
}`}
onClick={refetch}
>
{isRefetching ? (
<>
<i
className={`bx bx-loader-alt ${
isRefetching ? "bx-spin" : ""
}`}
></i>{" "}
Retrying...
</>
) : (
"Try to refetch"
)}
</small>
</div>
)}
{isLoading ? (
<SelectedPlanSkeleton />
) : (

View File

@ -24,6 +24,7 @@ import EmpDashboard from "../../components/Employee/EmpDashboard";
import EmpDocuments from "../../components/Employee/EmpDocuments";
import EmpActivities from "../../components/Employee/EmpActivities";
import { setProjectId } from "../../slices/localVariablesSlice";
import ManageSubscription from "../../components/UserSubscription/ManageSubscription/ManageSubscription";
const EmployeeProfile = () => {
const { profile } = useProfile();
@ -77,6 +78,14 @@ const EmployeeProfile = () => {
);
break;
}
case "setting": {
return (
<>
<ManageSubscription />
</>
);
break;
}
case "activities": {
return (
<>