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,
error,
isPending,
} = useCreateTenant(() => onNext());
} = useCreateTenant(() => {
debugger
onNext()
});
const handleNext = async () => {
const valid = await trigger([

View File

@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
import ContactInfro from "./ContactInfro";
import SubScription from "./SubScription";
import OrganizationInfo from "./OrganizationInfo";
import Congratulation from "./Congratulation";
import { useForm, FormProvider } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
@ -11,7 +12,6 @@ import {
subscriptionSchema,
tenantDefaultValues,
} from "./TenantSchema";
import Congratulation from "./Congratulation";
import { useSelector } from "react-redux";
const TenantForm = () => {
@ -21,24 +21,23 @@ const TenantForm = () => {
const [activeTab, setActiveTab] = useState(0);
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
useEffect(() => {
if (HasSelectedCurrentTenant) {
if (HasSelectedCurrentTenant.operationMode === 1) {
// Skip to subscription step
setActiveTab(2); // index for "SubScription"
setCompletedTabs([0, 1]); // mark previous steps as completed
} else if (HasSelectedCurrentTenant.operationMode === 0) {
// Start from the beginning (new tenant creation)
setActiveTab(0);
useEffect(() => {
if (HasSelectedCurrentTenant) {
if (HasSelectedCurrentTenant.operationMode === 1) {
// Skip to subscription step
setActiveTab(2); // index for "SubScription"
setCompletedTabs([0, 1]); // mark previous steps as completed
} else if (HasSelectedCurrentTenant.operationMode === 0) {
setActiveTab(0); // start from beginning
}
}
} else {
// Default: no tenant selected
return ;
}
}, [HasSelectedCurrentTenant,activeTab]);
}, [HasSelectedCurrentTenant]);
const tenantForm = useForm({
resolver: zodResolver(newTenantSchema),
@ -54,32 +53,50 @@ useEffect(() => {
activeTab === 2 ? subscriptionForm.trigger : tenantForm.trigger;
const handleNext = async () => {
const currentStepFields = getStepFields(activeTab);
const trigger = getCurrentTrigger();
const valid = await trigger(currentStepFields);
const currentStepFields = getStepFields(activeTab);
const trigger = getCurrentTrigger();
const valid = await trigger(currentStepFields);
if (valid) {
setCompletedTabs((prev) => [...new Set([...prev, activeTab])]);
if (valid) {
setCompletedTabs((prev) => [...new Set([...prev, activeTab])]);
setActiveTab((prev) => {
let nextStep = Math.min(prev + 1, newTenantConfig.length - 1);
// 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;
});
}
};
setActiveTab((prev) => {
let nextStep = Math.min(prev + 1, newTenantConfig.length - 1);
if (HasSelectedCurrentTenant && nextStep === 2) {
nextStep = 3; // skip subscription if already upgraded
}
return nextStep;
});
}
};
const handlePrev = () => {
setActiveTab((prev) => Math.max(prev - 1, 0));
};
const onSubmitTenant = (data) => {
// console.log("Tenant Data:", data);
console.log("Tenant Data:", data);
};
const onSubmitSubScription = (data) => {
// console.log("Subscription Data:", data);
console.log("Subscription Data:", data);
};
const newTenantConfig = [
@ -113,9 +130,9 @@ useEffect(() => {
),
},
{
name: "congratulation",
icon: "bx bx-star bx-md",
subtitle: "Select a plan",
name: "Congratulation",
icon: "bx bx-check-circle bx-md",
subtitle: "Completed",
component: <Congratulation />,
},
];
@ -123,7 +140,10 @@ useEffect(() => {
const isSubscriptionTab = activeTab === 2;
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 ">
{newTenantConfig
.filter((step) => step.name.toLowerCase() !== "congratulation")
@ -142,7 +162,7 @@ useEffect(() => {
<button
type="button"
className={`step-trigger ${isActive ? "active" : ""}`}
// onClick={() => setActiveTab(index)}
// onClick={() => setActiveTab(index)} // optional
>
<span className="bs-stepper-circle">
{isCompleted ? (
@ -170,13 +190,15 @@ useEffect(() => {
<div className="bs-stepper-content py-2">
{isSubscriptionTab ? (
<FormProvider {...subscriptionForm}>
<form onSubmit={subscriptionForm.handleSubmit(onSubmitTenant)}>
<form
onSubmit={subscriptionForm.handleSubmit(onSubmitSubScription)}
>
{newTenantConfig[activeTab].component}
</form>
</FormProvider>
) : (
<FormProvider {...tenantForm}>
<form onSubmit={tenantForm.handleSubmit(onSubmitSubScription)}>
<form onSubmit={tenantForm.handleSubmit(onSubmitTenant)}>
{newTenantConfig[activeTab].component}
</form>
</FormProvider>

View File

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

View File

@ -58,7 +58,7 @@ const TenantDetails = () => {
];
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 (
<>
<TenantDetailsContext.Provider value={contextValues}>