diff --git a/public/assets/css/core-extend.css b/public/assets/css/core-extend.css index d6967023..788d2d08 100644 --- a/public/assets/css/core-extend.css +++ b/public/assets/css/core-extend.css @@ -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 */ diff --git a/src/components/Employee/EmployeeNav.jsx b/src/components/Employee/EmployeeNav.jsx index 824949b7..dc01efab 100644 --- a/src/components/Employee/EmployeeNav.jsx +++ b/src/components/Employee/EmployeeNav.jsx @@ -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 ( diff --git a/src/components/UserSubscription/ManageSubscription/ManageSubscription.jsx b/src/components/UserSubscription/ManageSubscription/ManageSubscription.jsx new file mode 100644 index 00000000..a4068f28 --- /dev/null +++ b/src/components/UserSubscription/ManageSubscription/ManageSubscription.jsx @@ -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 + case "billing": + return
💳 Billing Info section content goes here.
; + + default: + return null; + } + }; + + return ( +
+
+
    +
  • + setActiveTab("plan")} + > + Subscription OverView + +
  • +
  • + setActiveTab("billing")} + > + Manage Subscription + +
  • + +
+
+ +
+ {renderContent()} +
+
+ ); +}; + +export default ManageSubscription; + diff --git a/src/components/UserSubscription/ManageSubscription/SubscriptionOverview.jsx b/src/components/UserSubscription/ManageSubscription/SubscriptionOverview.jsx new file mode 100644 index 00000000..7d91af1b --- /dev/null +++ b/src/components/UserSubscription/ManageSubscription/SubscriptionOverview.jsx @@ -0,0 +1,87 @@ +import React from 'react' +import Avatar from '../../common/Avatar' + +const SubscriptionOverview = () => { + return ( +
+
+ Overview +

Summerizees all your payments and subscription for the purchsed Application

+
+
+
+

Contact Details

+ Who should we contact if neccessary ? +
+

Manage Contact Details

+
+
+
+
+
+ +
+ Pramod Mahajan + pramod.mahajan@marcoaiot.com +

Marco Aiot Pvt Limited

+
+
+
+
+ +
+
+
+
+ + +
+ +
+
+

Current Plan

+ You can update your plan anytime for best benifit from the product and track your projct +
+

Switch Plan

+
+
+
+
+
+ + Super Package + ₹ 5999 +
+ +
+
+

Includes up to 100 userss, 10GB individual cloud storage and access maximum features

+
+
+
+
+ + +
+ +
+ +
+
+

Billing History

+ Sumary on the payment history for the subscription plan of the application +
+

Billing History

+
+
+ +
+
+ +
+ ) +} + +export default SubscriptionOverview diff --git a/src/components/UserSubscription/ProcessedPayment.jsx b/src/components/UserSubscription/ProcessedPayment.jsx index b389f840..9f7ed25b 100644 --- a/src/components/UserSubscription/ProcessedPayment.jsx +++ b/src/components/UserSubscription/ProcessedPayment.jsx @@ -23,11 +23,13 @@ const ProcessedPayment = ({ setStepStatus, resetFormStep, }) => { - const { planName } = useParams(); + 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); @@ -77,18 +77,18 @@ const ProcessedPayment = ({ alert("Failed to load Razorpay SDK"); return; } - MakePayment({ amount:selectedPlan?.price }); + MakePayment({ amount: selectedPlan?.price }); }; const handleRetry = () => { setFailPayment(null); if (typeof resetPaymentStep === "function") resetPaymentStep(); }; - const handlPrevious=()=>{ + const handlPrevious = () => { setCurrentStep, - setStepStatus((prev) => ({ ...prev, 2: "pending",3:"pending" })); - setCurrentStep(2); - } + setStepStatus((prev) => ({ ...prev, 2: "pending", 3: "pending" })); + setCurrentStep(2); + }; // useEffect(() => { // if (!client || Object.keys(client).length === 0) { @@ -154,156 +154,190 @@ const ProcessedPayment = ({ and help you maximize productivity.

- - {isLoading ? : (<> - - {selectedPlan && ( -
-
-
- {selectedPlan?.planName} - -
- -
- - {selectedPlan?.currency?.symbol} {selectedPlan?.price} / - {frequencyLabel(frequency,false)} - -
- - - {selectedPlan?.description} - -
+ {isError && ( +
+

{error?.message}

+ {error?.name} + + {isRefetching ? ( + <> + {" "} + Retrying... + + ) : ( + "Try to refetch" + )} +
)} + {isLoading ? ( + + ) : ( + <> + {selectedPlan && ( +
+
+
+ + {selectedPlan?.planName} + + +
- {selectedPlan && ( -
-
- {(() => { - const { - planName, - description, - price, - frequency, - trialDays, - maxUser, - maxStorage, - currency, - features, - } = selectedPlan; - return ( - <> -
-
-
- - Max Users: {maxUser} -
-
-
-
- - Max Storage: {maxStorage} MB -
-
-
-
- - Trial Days: {trialDays} -
-
-
+
+ + {selectedPlan?.currency?.symbol} {selectedPlan?.price}{" "} + /{frequencyLabel(frequency, false)} + +
-
- Included Features -
-
- {features && - Object.entries(features?.modules || {}) - .filter(([key]) => key !== "id") - .map(([key, mod]) => ( -
- - {mod.name} + + {selectedPlan?.description} + +
+
+ )} + + {selectedPlan && ( +
+
+ {(() => { + const { + planName, + description, + price, + frequency, + trialDays, + maxUser, + maxStorage, + currency, + features, + } = selectedPlan; + return ( + <> +
+
+
+ + Max Users: {maxUser}
- ))} -
+
+
+
+ + Max Storage: {maxStorage} MB +
+
+
+
+ + Trial Days: {trialDays} +
+
+
-
- Support -
-
    - {features?.supports?.emailSupport && ( -
  • - - Email Support -
  • - )} - {features?.supports?.phoneSupport && ( -
  • - - Phone Support -
  • - )} - {features?.supports?.prioritySupport && ( -
  • - - Priority Support -
  • - )} -
-
-
-
-
Duration
-
- {frequencyLabel(selectedPlan?.frequency, true)} -
-
+
+ Included Features +
+
+ {features && + Object.entries(features?.modules || {}) + .filter(([key]) => key !== "id") + .map(([key, mod]) => ( +
+ + {mod.name} +
+ ))} +
-
-
Total Price
-
- {formatFigure(selectedPlan?.price, { - type: "currency", - currency: selectedPlan?.currency.currencyCode, - })} -
-
-
- - ); - })()} -
-
+
+ Support +
+
    + {features?.supports?.emailSupport && ( +
  • + + Email Support +
  • + )} + {features?.supports?.phoneSupport && ( +
  • + + Phone Support +
  • + )} + {features?.supports?.prioritySupport && ( +
  • + + Priority Support +
  • + )} +
+
+
+
+
Duration
+
+ {frequencyLabel( + selectedPlan?.frequency, + true + )} +
+
+ +
+
Total Price
+
+ {formatFigure(selectedPlan?.price, { + type: "currency", + currency: + selectedPlan?.currency.currencyCode, + })} +
+
+
+ + ); + })()} +
+
+ )} + )} - )} -
- {client && (
-
Confirm your organization details.
+
+ Confirm your organization details. +
Name:
-
{client.firstName} {client.lastName}
- +
+ {client.firstName} {client.lastName} +
Email: @@ -320,8 +354,6 @@ const ProcessedPayment = ({
{client.organizationName}
- -
Onboarding Date:
@@ -344,19 +376,26 @@ const ProcessedPayment = ({
- +
diff --git a/src/components/UserSubscription/SelectPlan.jsx b/src/components/UserSubscription/SelectPlan.jsx index 68d64fd2..da320767 100644 --- a/src/components/UserSubscription/SelectPlan.jsx +++ b/src/components/UserSubscription/SelectPlan.jsx @@ -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 }) => { + {isError && ( +
+

{error?.message}

+ {error?.name} + + {isRefetching ? ( + <> + {" "} + Retrying... + + ) : ( + "Try to refetch" + )} + +
+ )} + {isLoading ? ( ) : ( diff --git a/src/pages/employee/EmployeeProfile.jsx b/src/pages/employee/EmployeeProfile.jsx index 164643d1..0d3b89de 100644 --- a/src/pages/employee/EmployeeProfile.jsx +++ b/src/pages/employee/EmployeeProfile.jsx @@ -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 ( + <> + + + ); + break; + } case "activities": { return ( <>