360 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useParams } from "react-router-dom";
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();
const [selectedFrequency, setSelectedFrequency] = useState(
parseInt(frequency)
);
const dispatch = useDispatch();
const client = useSelector(
(store) => store.localVariables.selfTenant.details
);
const [selectedPlan, setSelectedPlan] = useState(planName);
const [currentPlan, setCurrentPlan] = useState(null);
const [failPayment, setFailPayment] = useState(null);
const {
data: plans,
isError,
isLoading,
error,
refetch,
isRefetching,
} = useSubscription(selectedFrequency);
const handleChange = (e) => setSelectedPlan(e.target.value);
useEffect(() => {
if (!plans || !selectedPlan) return;
const selected = plans.find((p) => p.planName === selectedPlan);
if (selected) {
setCurrentPlan(selected);
dispatch(
setSelfTenant({ planId: selected.id, frequency: selectedFrequency })
);
}
}, [plans, selectedPlan, dispatch, selectedFrequency]);
const handleNextStep = () => {
dispatch(setSelfTenant({ frequency: selectedFrequency }));
setStepStatus((prev) => ({ ...prev, 2: "success" }));
onNext();
};
return (
<div className="container text-start ">
<div className="row gx-4 gy-5 align-items-center justify-content-around">
<div className="col-sm-12 col-md-6">
<div className="row">
<div className="col-12 mb-3 text-start">
<h4>Choose the Perfect Plan for Your Organization</h4>
<p className="text-muted small mb-3">
Select a plan that fits your teams needs and unlock the
features that drive productivity.
</p>
<div>
<div className="form-check form-check-inline mt-4">
<input
className="form-check-input"
type="radio"
name="frequencyOptions"
id="frequencyMonthly"
value={0}
checked={selectedFrequency === 0}
onChange={(e) =>
setSelectedFrequency(Number(e.target.value))
}
/>
<label
className="form-check-label"
htmlFor="frequencyMonthly"
>
Monthly
</label>
</div>
<div className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
name="frequencyOptions"
id="frequencyQuarterly"
value={1}
checked={selectedFrequency === 1}
onChange={(e) =>
setSelectedFrequency(Number(e.target.value))
}
/>
<label
className="form-check-label"
htmlFor="frequencyQuarterly"
>
Quarterly
</label>
</div>
<div className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
name="frequencyOptions"
id="frequencyHalfYear"
value={2}
checked={selectedFrequency === 2}
onChange={(e) =>
setSelectedFrequency(Number(e.target.value))
}
/>
<label
className="form-check-label"
htmlFor="frequencyHalfYear"
>
Half-Yearly
</label>
</div>
<div className="form-check form-check-inline">
<input
className="form-check-input"
type="radio"
name="frequencyOptions"
id="frequencyYearly"
value={3}
checked={selectedFrequency === 3}
onChange={(e) =>
setSelectedFrequency(Number(e.target.value))
}
/>
<label className="form-check-label" htmlFor="frequencyYearly">
Yearly
</label>
</div>
</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 />
) : (
<>
{plans?.map((plan) => (
<div key={plan?.id} className="col-12 col-md-4 mb-md-3 mb-2">
<div
className={`form-check custom-option custom-option-basic text-start w-100 bg-light-primary ${
selectedPlan === plan?.planName
? "border border-primary shadow-md"
: ""
}`}
>
<label
className="form-check-label custom-option-content w-100"
htmlFor={`customRadioTemp${plan?.id}`}
>
<input
name="customRadioTemp"
className="form-check-input"
type="radio"
value={plan?.planName}
id={`customRadioTemp${plan?.id}`}
checked={selectedPlan === plan?.planName}
onChange={handleChange}
/>
<span className="custom-option-header d-flex justify-content-between align-items-center">
<span className="h6 mb-0">{plan?.planName}</span>
<span>
{plan.currency?.symbol} {plan.price} /{" "}
{frequencyLabel(selectedFrequency)}
</span>
</span>
<span className="custom-option-body d-block mt-1">
<small>{plan?.description}</small>
</span>
</label>
</div>
</div>
))}
{selectedPlan && (
<div className="col-12 text-start">
<div className="border-warning mt-3">
{(() => {
const selected = plans?.find(
(p) => p.planName === selectedPlan
);
if (!selected) return null;
const {
price,
frequency,
trialDays,
maxUser,
maxStorage,
currency,
features,
} = selected;
return (
<>
<div className="row g-2 mb-3">
<div className="col-sm-6 col-md-4">
<div className="border rounded-3 p-2 bg-light">
<i className="bx bx-user me-1 text-primary"></i>
<strong>Max Users:</strong> {maxUser}
</div>
</div>
<div className="col-sm-6 col-md-4">
<div className="border rounded-3 p-2 bg-light">
<i className="bx bx-hdd me-1 text-primary"></i>
<strong>Max Storage:</strong> {maxStorage} MB
</div>
</div>
<div className="col-sm-6 col-md-4">
<div className="border rounded-3 p-2 bg-light">
<i className="bx bx-time-five me-1 text-primary"></i>
<strong>Trial Days:</strong> {trialDays}
</div>
</div>
</div>
<h6 className="fw-bold text-secondary mb-2">
Included Features
</h6>
<div className="row">
{features &&
Object.entries(features?.modules || {})
.filter(([key]) => key !== "id")
.map(([key, mod]) => (
<div
key={key}
className="col-4 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>
<h6 className="fw-bold text-secondary mt-3 mb-2">
Support
</h6>
<ul className="list-unstyled d-flex flex-wrap gap-3 align-items-center mb-0 small">
{features?.supports?.emailSupport && (
<li className="d-flex align-items-center">
<i className="bx bx-envelope text-primary me-1 fs-5"></i>
Email Support
</li>
)}
{features?.supports?.phoneSupport && (
<li className="d-flex align-items-center">
<i className="bx bx-phone text-primary me-1 fs-5"></i>
Phone Support
</li>
)}
{features?.supports?.prioritySupport && (
<li className="d-flex align-items-center">
<i className="bx bx-star text-warning me-1 fs-5"></i>
Priority Support
</li>
)}
</ul>
<hr className="divider border-2" />
<div className="d-flex flex-column co-12">
<div className="d-flex justify-content-between">
<h6 className="fs-6 m-0">Duration</h6>
<h5 className="fs-6 m-0">
{frequencyLabel(frequency, true)}
</h5>
</div>
<div className="d-flex justify-content-between">
<h6 className="fs-4">Total Price</h6>
<h5 className="fs-3">
{formatFigure(price, {
type: "currency",
currency: currency.currencyCode,
})}
</h5>
</div>
</div>
</>
);
})()}
</div>
</div>
)}
</>
)}
</div>
</div>
{/* Image Section */}
<div className="d-none d-md-flex col-md-6 justify-content-center align-items-center">
<img
src="/public/img/illustrations/undraw_pricing.png"
alt="image"
className="img-fluid"
style={{
maxWidth: "70%",
height: "auto",
objectFit: "contain",
}}
/>
</div>
</div>
<div className="col-12 d-flex justify-content-end mt-3">
<button
type="submit"
className="btn btn-label-primary d-flex align-items-center me-2"
onClick={handleNextStep}
>
Next <i className="bx bx-chevron-right"></i>
</button>
</div>
</div>
);
};
export default SelectPlan;