253 lines
8.4 KiB
JavaScript
253 lines
8.4 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import {
|
|
useAddSubscription,
|
|
useSubscriptionPlan,
|
|
useUpgradeSubscription,
|
|
} from "../../hooks/useTenant";
|
|
import SegmentedControl from "./SegmentedControl";
|
|
import { useFormContext } from "react-hook-form";
|
|
import { CONSTANT_TEXT } from "../../utils/constants";
|
|
import Label from "../common/Label";
|
|
import { useSelector } from "react-redux";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
const SubScription = ({ onSubmitSubScription, onNext }) => {
|
|
const [frequency, setFrequency] = useState(3);
|
|
const [selectedPlanId, setSelectedPlanId] = useState(null);
|
|
const selectedTenant = useSelector(
|
|
(store) => store.globalVariables.currentTenant
|
|
);
|
|
const naviget = useNavigate();
|
|
const {
|
|
data: plans = [],
|
|
isError,
|
|
isLoading,
|
|
error: subscriptionGettingError,
|
|
} = useSubscriptionPlan(frequency);
|
|
|
|
const {
|
|
register,
|
|
setValue,
|
|
getValues,
|
|
trigger,
|
|
formState: { errors },
|
|
} = useFormContext();
|
|
|
|
const {
|
|
mutate: AddSubScription,
|
|
isPending,
|
|
error,
|
|
} = useAddSubscription(() => {
|
|
naviget("/tenants");
|
|
});
|
|
const { mutate: updgradeSubscription, isPending: upgrading } =
|
|
useUpgradeSubscription(() => {
|
|
naviget("/tenants");
|
|
});
|
|
const handleSubscriptionSubmit = async () => {
|
|
const isValid = await trigger([
|
|
"planId",
|
|
"currencyId",
|
|
"maxUsers",
|
|
"frequency",
|
|
"isTrial",
|
|
"autoRenew",
|
|
]);
|
|
|
|
if (isValid) {
|
|
const payload = getValues();
|
|
// onSubmitSubScription(payload);
|
|
let subscriptionPayload = null;
|
|
|
|
if (selectedTenant?.operationMode === 1) {
|
|
subscriptionPayload = {
|
|
planId: payload.planId,
|
|
currencyId: payload.currencyId,
|
|
maxUsers: payload.maxUsers,
|
|
tenantId: selectedTenant?.data?.id,
|
|
};
|
|
updgradeSubscription(subscriptionPayload);
|
|
} else {
|
|
subscriptionPayload = {
|
|
...payload,
|
|
tenantId: selectedTenant?.data?.id,
|
|
};
|
|
AddSubScription(subscriptionPayload);
|
|
}
|
|
}
|
|
};
|
|
|
|
const handlePlanSelection = (plan) => {
|
|
setSelectedPlanId(plan.id);
|
|
setValue("planId", plan.id);
|
|
setValue("currencyId", plan.currency?.id);
|
|
setValue("frequency", frequency);
|
|
};
|
|
|
|
const selectedPlan = plans.find((p) => p.id === selectedPlanId);
|
|
if (isLoading) return <div className="text-center">Loading....</div>;
|
|
if (isError)
|
|
return (
|
|
<div className="text-center">{subscriptionGettingError?.message}</div>
|
|
);
|
|
return (
|
|
<div className="text-start">
|
|
<SegmentedControl
|
|
setFrequency={setFrequency}
|
|
defultFequency={frequency}
|
|
/>
|
|
|
|
{!isLoading && !isError && plans.length > 0 && (
|
|
<div className="row g-4 my-6">
|
|
{plans.map((plan) => {
|
|
const isSelected = plan.id === selectedPlanId;
|
|
|
|
return (
|
|
<div key={plan.id} className="col-md-4">
|
|
<div
|
|
className={`card h-100 shadow-none border-1 cursor-pointer ${
|
|
isSelected ? "border-primary border-1 shadow-md" : ""
|
|
}`}
|
|
onClick={() => handlePlanSelection(plan)}
|
|
>
|
|
<div className="card-body d-flex flex-column p-3">
|
|
<div className="d-flex align-items-center gap-3 mb-3">
|
|
<i className="bx bxs-package text-primary fs-1"></i>
|
|
<div>
|
|
<p className="card-title fs-4 fw-bold mb-1">
|
|
{plan.planName}
|
|
</p>
|
|
<p className="text-muted mb-0">{plan.description}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<h4 className="fw-semibold mt-auto mb-3">
|
|
{plan.currency?.symbol} {plan.price}
|
|
</h4>
|
|
|
|
<ul className="list-unstyled d-flex gap-4 flex-wrap mb-2">
|
|
<li className="d-flex align-items-center">
|
|
<i className="bx bx-server me-1"></i>
|
|
Storage {plan.maxStorage} MB
|
|
</li>
|
|
<li className="d-flex align-items-center">
|
|
<i className="bx bx-check-double text-success me-2"></i>
|
|
Trial Days {plan.trialDays}
|
|
</li>
|
|
</ul>
|
|
|
|
<div>
|
|
<div className="divider my-3">
|
|
<div className="divider-text card-text text-uppercase text-muted small">
|
|
Features
|
|
</div>
|
|
</div>
|
|
{plan?.features &&
|
|
Object.entries(plan?.features?.modules || {})
|
|
.filter(([key]) => key !== "id")
|
|
.map(([key, mod]) => (
|
|
<div
|
|
key={key}
|
|
className="mb-2 d-flex align-items-center"
|
|
>
|
|
<i
|
|
className={`fa-regular ${
|
|
mod.enabled
|
|
? "fa-circle-check text-success"
|
|
: "fa-circle-xmark text-danger"
|
|
}`}
|
|
></i>
|
|
<small className="ms-1">{mod.name}</small>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<button
|
|
className={`btn mt-3 ${
|
|
isSelected ? "btn-primary" : "btn-outline-primary"
|
|
}`}
|
|
onClick={() => handlePlanSelection(plan)}
|
|
>
|
|
{isSelected ? "Selected" : "Select Plan"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
|
|
{/* Form Inputs */}
|
|
<div className="row g-2 mt-3">
|
|
<div className="col-sm-4">
|
|
<Label htmlFor="maxUsers" required>
|
|
{" "}
|
|
Team Size
|
|
</Label>
|
|
<input
|
|
type="number"
|
|
step={1}
|
|
className="form-control form-control-sm"
|
|
{...register("maxUsers", {
|
|
valueAsNumber: true,
|
|
})}
|
|
onKeyDown={(e) => {
|
|
if (["e", "E", "+", "-", "."].includes(e.key)) {
|
|
e.preventDefault();
|
|
}
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12">
|
|
<div className="d-flex justify-content-start align-items-center gap-2">
|
|
<label className="form-label d-block">Enable auto renew</label>
|
|
<label className="switch switch-square switch-sm">
|
|
<input
|
|
type="checkbox"
|
|
className="switch-input"
|
|
{...register("autoRenew")}
|
|
/>
|
|
<span className="switch-toggle-slider">
|
|
<span className="switch-on">
|
|
<i className="icon-base bx bx-check"></i>
|
|
</span>
|
|
<span className="switch-off">
|
|
<i className="icon-base bx bx-x"></i>
|
|
</span>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
<small className="text-secondary text-tiny">
|
|
{CONSTANT_TEXT.RenewsubscriptionLabel}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
{Object.keys(errors).length > 0 && (
|
|
<div class="alert alert-danger" role="alert">
|
|
{Object.entries(errors).map(([key, error]) => (
|
|
<div key={key} className="danger-text">
|
|
{error?.message}
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
<div className="d-flex text-center mt-4">
|
|
<button
|
|
onClick={handleSubscriptionSubmit}
|
|
className="btn btn-sm btn-primary"
|
|
type="button"
|
|
disabled={isPending || upgrading}
|
|
>
|
|
{isPending || upgrading ? "Please Wait..." : "Submit"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SubScription;
|