handle subscription tab according to tenant existent

This commit is contained in:
pramod mahajan 2025-08-16 12:23:10 +05:30
parent 30e9f49eb1
commit 9366a131e6
4 changed files with 157 additions and 110 deletions

View File

@ -25,7 +25,10 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
isError: tenantError, isError: tenantError,
error, error,
isPending, isPending,
} = useCreateTenant(() => onNext()); } = useCreateTenant(() => {
debugger
onNext()
});
const handleNext = async () => { const handleNext = async () => {
const valid = await trigger([ const valid = await trigger([

View File

@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
import ContactInfro from "./ContactInfro"; import ContactInfro from "./ContactInfro";
import SubScription from "./SubScription"; import SubScription from "./SubScription";
import OrganizationInfo from "./OrganizationInfo"; import OrganizationInfo from "./OrganizationInfo";
import Congratulation from "./Congratulation";
import { useForm, FormProvider } from "react-hook-form"; import { useForm, FormProvider } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { import {
@ -11,7 +12,6 @@ import {
subscriptionSchema, subscriptionSchema,
tenantDefaultValues, tenantDefaultValues,
} from "./TenantSchema"; } from "./TenantSchema";
import Congratulation from "./Congratulation";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
const TenantForm = () => { const TenantForm = () => {
@ -21,7 +21,10 @@ const TenantForm = () => {
const [activeTab, setActiveTab] = useState(0); const [activeTab, setActiveTab] = useState(0);
const [completedTabs, setCompletedTabs] = useState([]); const [completedTabs, setCompletedTabs] = useState([]);
const PlanTextLabel = HasSelectedCurrentTenant?.operationMode === 1 ? "Upgrade Plan":"Select Plan" const PlanTextLabel =
HasSelectedCurrentTenant?.operationMode === 1
? "Upgrade Plan"
: "Select Plan";
// Jump to subscription if tenant already exists // Jump to subscription if tenant already exists
useEffect(() => { useEffect(() => {
@ -31,14 +34,10 @@ useEffect(() => {
setActiveTab(2); // index for "SubScription" setActiveTab(2); // index for "SubScription"
setCompletedTabs([0, 1]); // mark previous steps as completed setCompletedTabs([0, 1]); // mark previous steps as completed
} else if (HasSelectedCurrentTenant.operationMode === 0) { } else if (HasSelectedCurrentTenant.operationMode === 0) {
// Start from the beginning (new tenant creation) setActiveTab(0); // start from beginning
setActiveTab(0);
} }
} else {
// Default: no tenant selected
return ;
} }
}, [HasSelectedCurrentTenant,activeTab]); }, [HasSelectedCurrentTenant]);
const tenantForm = useForm({ const tenantForm = useForm({
resolver: zodResolver(newTenantSchema), resolver: zodResolver(newTenantSchema),
@ -63,23 +62,41 @@ useEffect(() => {
setActiveTab((prev) => { setActiveTab((prev) => {
let nextStep = Math.min(prev + 1, newTenantConfig.length - 1); let nextStep = Math.min(prev + 1, newTenantConfig.length - 1);
if (HasSelectedCurrentTenant && nextStep === 2) {
nextStep = 3; // skip subscription if already upgraded // Check tenant operationMode to decide navigation
if (
HasSelectedCurrentTenant &&
HasSelectedCurrentTenant.operationMode === 1 &&
nextStep === 2
) {
// If tenant already has subscription, show upgrade
nextStep = 2;
} else if (
HasSelectedCurrentTenant &&
[0, 2].includes(HasSelectedCurrentTenant.operationMode) &&
nextStep === 2
) {
// If tenant just created (0) OR exists without subscription (2)
// stay on subscription tab
nextStep = 2;
} }
return nextStep; return nextStep;
}); });
} }
}; };
const handlePrev = () => { const handlePrev = () => {
setActiveTab((prev) => Math.max(prev - 1, 0)); setActiveTab((prev) => Math.max(prev - 1, 0));
}; };
const onSubmitTenant = (data) => { const onSubmitTenant = (data) => {
// console.log("Tenant Data:", data); console.log("Tenant Data:", data);
}; };
const onSubmitSubScription = (data) => { const onSubmitSubScription = (data) => {
// console.log("Subscription Data:", data); console.log("Subscription Data:", data);
}; };
const newTenantConfig = [ const newTenantConfig = [
@ -113,9 +130,9 @@ useEffect(() => {
), ),
}, },
{ {
name: "congratulation", name: "Congratulation",
icon: "bx bx-star bx-md", icon: "bx bx-check-circle bx-md",
subtitle: "Select a plan", subtitle: "Completed",
component: <Congratulation />, component: <Congratulation />,
}, },
]; ];
@ -123,7 +140,10 @@ useEffect(() => {
const isSubscriptionTab = activeTab === 2; const isSubscriptionTab = activeTab === 2;
return ( return (
<div id="wizard-property-listing" className="bs-stepper horizontically mt-2"> <div
id="wizard-property-listing"
className="bs-stepper horizontically mt-2"
>
<div className="bs-stepper-header border-end text-start "> <div className="bs-stepper-header border-end text-start ">
{newTenantConfig {newTenantConfig
.filter((step) => step.name.toLowerCase() !== "congratulation") .filter((step) => step.name.toLowerCase() !== "congratulation")
@ -142,7 +162,7 @@ useEffect(() => {
<button <button
type="button" type="button"
className={`step-trigger ${isActive ? "active" : ""}`} className={`step-trigger ${isActive ? "active" : ""}`}
// onClick={() => setActiveTab(index)} // onClick={() => setActiveTab(index)} // optional
> >
<span className="bs-stepper-circle"> <span className="bs-stepper-circle">
{isCompleted ? ( {isCompleted ? (
@ -170,13 +190,15 @@ useEffect(() => {
<div className="bs-stepper-content py-2"> <div className="bs-stepper-content py-2">
{isSubscriptionTab ? ( {isSubscriptionTab ? (
<FormProvider {...subscriptionForm}> <FormProvider {...subscriptionForm}>
<form onSubmit={subscriptionForm.handleSubmit(onSubmitTenant)}> <form
onSubmit={subscriptionForm.handleSubmit(onSubmitSubScription)}
>
{newTenantConfig[activeTab].component} {newTenantConfig[activeTab].component}
</form> </form>
</FormProvider> </FormProvider>
) : ( ) : (
<FormProvider {...tenantForm}> <FormProvider {...tenantForm}>
<form onSubmit={tenantForm.handleSubmit(onSubmitSubScription)}> <form onSubmit={tenantForm.handleSubmit(onSubmitTenant)}>
{newTenantConfig[activeTab].component} {newTenantConfig[activeTab].component}
</form> </form>
</FormProvider> </FormProvider>

View File

@ -7,8 +7,6 @@ import { setCurrentTenant } from "../slices/globalVariablesSlice";
import { ITEMS_PER_PAGE } from "../utils/constants"; import { ITEMS_PER_PAGE } from "../utils/constants";
import moment from "moment"; import moment from "moment";
const cleanFilter = (filter) => { const cleanFilter = (filter) => {
const cleaned = { ...filter }; const cleaned = { ...filter };
@ -20,7 +18,11 @@ const cleanFilter = (filter) => {
// moment.utc() to get consistent UTC ISO strings // moment.utc() to get consistent UTC ISO strings
if (!cleaned.startDate) { if (!cleaned.startDate) {
cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString(); cleaned.startDate = moment
.utc()
.subtract(7, "days")
.startOf("day")
.toISOString();
} }
if (!cleaned.endDate) { if (!cleaned.endDate) {
@ -29,7 +31,6 @@ const cleanFilter = (filter) => {
return cleaned; return cleaned;
}; };
export const useTenants = (pageNumber, filter, searchString = "") => { export const useTenants = (pageNumber, filter, searchString = "") => {
return useQuery({ return useQuery({
queryKey: ["Tenants", pageNumber, filter, searchString], queryKey: ["Tenants", pageNumber, filter, searchString],
@ -54,69 +55,85 @@ export const useTenantDetails =(id)=>{
const response = await TenantRepository.getTenantDetails(id); const response = await TenantRepository.getTenantDetails(id);
return response.data; return response.data;
}, },
}) });
} };
export const useIndustries = () => { export const useIndustries = () => {
return useQuery({ return useQuery({
queryKey:['Industries'], queryKey: ["Industries"],
queryFn: async () => { queryFn: async () => {
const res = await MarketRepository.getIndustries(); const res = await MarketRepository.getIndustries();
return res.data; return res.data;
} },
}) });
} };
export const useSubscriptionPlan = (freq) => { export const useSubscriptionPlan = (freq) => {
return useQuery({ return useQuery({
queryKey:['SubscriptionPlan',freq], queryKey: ["SubscriptionPlan", freq],
queryFn: async () => { queryFn: async () => {
const res = await TenantRepository.getSubscriptionPlan(freq); const res = await TenantRepository.getSubscriptionPlan(freq);
return res.data; return res.data;
} },
}) });
} };
// ------------Mutation--------------------- // ------------Mutation---------------------
export const useCreateTenant = (onSuccessCallback) => { export const useCreateTenant = (onSuccessCallback) => {
const dispatch = useDispatch() const dispatch = useDispatch();
return useMutation({ return useMutation({
mutationFn: async (tenantPayload) => { mutationFn: async (tenantPayload) => {
const res = await TenantRepository.createTenant(tenantPayload); const res = await TenantRepository.createTenant(tenantPayload);
return res.data; return res.data;
}, },
onSuccess: (data, variables) => { onSuccess: (data, variables) => {
showToast("Tenant Created SuccessFully","success") showToast("Tenant Created SuccessFully", "success");
dispatch(setCurrentTenant({operationMode:0,data:data})) // dispatch(setCurrentTenant({operationMode:0,data:data}))
if(onSuccessCallback) onSuccessCallback() let operationMode = 0; // default = new tenant, needs subscription
}, if (data?.subscriptionHistery?.length > 0) {
onError:(error)=>{ operationMode = 1; // tenant already has a subscription
showToast(error.response.message || error?.response?.data?.errors || `Something went wrong`,"error") } else if (data && !data.subscriptionHistery) {
operationMode = 2; // tenant exists but subscription not added yet
} }
}) dispatch(setCurrentTenant({ operationMode, data }));
}
if (onSuccessCallback) onSuccessCallback();
},
onError: (error) => {
showToast(
error.response.message ||
error?.response?.data?.errors ||
`Something went wrong`,
"error"
);
},
});
};
export const useUpdateTenantDetails = (onSuccessCallback) => { export const useUpdateTenantDetails = (onSuccessCallback) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn:async({id,tenantPayload})=> TenantRepository.updateTenantDetails(id,tenantPayload), mutationFn: async ({ id, tenantPayload }) =>
TenantRepository.updateTenantDetails(id, tenantPayload),
onSuccess: (_, variables) => { onSuccess: (_, variables) => {
const { id } = variables.tenantPayload; const { id } = variables.tenantPayload;
queryClient.invalidateQueries({queryKey:["Tenant",id]}) queryClient.invalidateQueries({ queryKey: ["Tenant", id] });
queryClient.invalidateQueries({queryKey:["Tenants"]}) queryClient.invalidateQueries({ queryKey: ["Tenants"] });
if(onSuccessCallback) onSuccessCallback() if (onSuccessCallback) onSuccessCallback();
}, },
onError: (error) => { onError: (error) => {
showToast(error.response.message || error.message || `Something went wrong`,"error") showToast(
} error.response.message || error.message || `Something went wrong`,
}) "error"
} );
},
});
};
export const useAddSubscription = (onSuccessCallback) => { export const useAddSubscription = (onSuccessCallback) => {
const queryClient = useQueryClient() const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async (subscriptionPayload) => { mutationFn: async (subscriptionPayload) => {
const res = await TenantRepository.addSubscription(subscriptionPayload); const res = await TenantRepository.addSubscription(subscriptionPayload);
@ -124,22 +141,27 @@ export const useAddSubscription =(onSuccessCallback)=>{
}, },
onSuccess: (data, variables) => { onSuccess: (data, variables) => {
const { tenantId } = variables; const { tenantId } = variables;
showToast("Tenant Plan Added SuccessFully","success") showToast("Tenant Plan Added SuccessFully", "success");
queryClient.invalidateQueries({queryKey:["Tenant",tenantId]}) queryClient.invalidateQueries({ queryKey: ["Tenant", tenantId] });
if(onSuccessCallback) onSuccessCallback() if (onSuccessCallback) onSuccessCallback();
}, },
onError: (error) => { onError: (error) => {
showToast(error.response.message || error.message || `Something went wrong`,"error") showToast(
} error.response.message || error.message || `Something went wrong`,
}) "error"
} );
},
});
};
export const useUpgradeSubscription = (onSuccessCallback) => { export const useUpgradeSubscription = (onSuccessCallback) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async (subscriptionPayload) => { mutationFn: async (subscriptionPayload) => {
const res = await TenantRepository.upgradeSubscription(subscriptionPayload); const res = await TenantRepository.upgradeSubscription(
subscriptionPayload
);
return res.data; return res.data;
}, },
onSuccess: (data, variables) => { onSuccess: (data, variables) => {
@ -160,6 +182,6 @@ export const useUpgradeSubscription = (onSuccessCallback) => {
"Something went wrong", "Something went wrong",
"error" "error"
); );
} },
}); });
}; };

View File

@ -58,7 +58,7 @@ const TenantDetails = () => {
]; ];
if (isLoading) return <div className="my-4">Loading...</div>; if (isLoading) return <div className="my-4">Loading...</div>;
if (isError) return <div>{error.message}</div>; if (isError) return <div className="my-3">{error.message}</div>;
return ( return (
<> <>
<TenantDetailsContext.Provider value={contextValues}> <TenantDetailsContext.Provider value={contextValues}>