Compare commits
7 Commits
09bb58e50e
...
9ba2ecfb1f
Author | SHA1 | Date | |
---|---|---|---|
9ba2ecfb1f | |||
a27b8571b5 | |||
fd36298543 | |||
1c0e8655c4 | |||
6211f52e3a | |||
df9107f0d8 | |||
eea7252b96 |
@ -299,7 +299,7 @@ nav.layout-navbar.navbar-active::after {
|
|||||||
color: #d3d4dc;
|
color: #d3d4dc;
|
||||||
}
|
}
|
||||||
.landing-footer .footer-bottom {
|
.landing-footer .footer-bottom {
|
||||||
background-color: #282c3e;
|
background-color: #f44336;
|
||||||
}
|
}
|
||||||
.landing-footer .footer-link {
|
.landing-footer .footer-link {
|
||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
@ -312,6 +312,7 @@ nav.layout-navbar.navbar-active::after {
|
|||||||
padding-bottom: 1.3rem;
|
padding-bottom: 1.3rem;
|
||||||
border-top-left-radius: 1.75rem;
|
border-top-left-radius: 1.75rem;
|
||||||
border-top-right-radius: 1.75rem;
|
border-top-right-radius: 1.75rem;
|
||||||
|
background-color: #f44336;
|
||||||
}
|
}
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
.landing-footer .footer-top {
|
.landing-footer .footer-top {
|
||||||
|
@ -591,14 +591,14 @@ const LandingPage = () => {
|
|||||||
<span className="badge bg-label-primary heading">FAQ</span>
|
<span className="badge bg-label-primary heading">FAQ</span>
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-center mb-1">
|
<h4 className="text-center mb-1">
|
||||||
Frequently asked
|
Frequently Asked
|
||||||
<span className="position-relative fw-extrabold z-1">
|
<span className="position-relative fw-extrabold z-1 ms-2">
|
||||||
questions
|
Questions
|
||||||
<img
|
{/* <img
|
||||||
src="/img/icons/section-title-icon.png"
|
src="/img/icons/section-title-icon.png"
|
||||||
alt="laptop charging"
|
alt="laptop charging"
|
||||||
className="section-title-img position-absolute object-fit-contain bottom-0 z-n1"
|
className="section-title-img position-absolute object-fit-contain bottom-0 z-n1"
|
||||||
/>
|
/> */}
|
||||||
</span>
|
</span>
|
||||||
</h4>
|
</h4>
|
||||||
<p className="text-center mb-12 pb-md-4">
|
<p className="text-center mb-12 pb-md-4">
|
||||||
@ -816,19 +816,26 @@ const LandingPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="row align-items-center gy-12 mb-12">
|
<div className="row align-items-center gy-12 mb-12">
|
||||||
|
<div className="col-lg-6 pt-lg-12 text-center text-lg-start">
|
||||||
|
<img
|
||||||
|
style={{ width: "80%" }}
|
||||||
|
src="/img/images/contact-customer-service.png"
|
||||||
|
alt="hero elements"
|
||||||
|
></img>
|
||||||
|
</div>
|
||||||
<div className="col-lg-6 text-start text-sm-center text-lg-start">
|
<div className="col-lg-6 text-start text-sm-center text-lg-start">
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
{" "}
|
{" "}
|
||||||
<h4 className="text-start mb-1">
|
<h4 className="text-start mb-1">
|
||||||
<span className="position-relative fw-extrabold z-1">
|
<span className="position-relative fw-extrabold z-1">
|
||||||
Let's work
|
Let's Work
|
||||||
<img
|
{/* <img
|
||||||
src="/img/icons/section-title-icon.png"
|
src="/img/icons/section-title-icon.png"
|
||||||
alt="laptop charging"
|
alt="laptop charging"
|
||||||
className="section-title-img position-absolute object-fit-contain bottom-0 z-n1"
|
className="section-title-img position-absolute object-fit-contain bottom-0 z-n1"
|
||||||
/>
|
/> */}
|
||||||
</span>
|
</span>
|
||||||
together
|
Together
|
||||||
</h4>
|
</h4>
|
||||||
<p className="text-start pb-md-4">
|
<p className="text-start pb-md-4">
|
||||||
Any question or remark? just write us a message
|
Any question or remark? just write us a message
|
||||||
@ -873,15 +880,15 @@ const LandingPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-10">
|
<div className="mt-10">
|
||||||
<h4 className="cta-title text-primary mb-1">
|
<h5 className="cta-title text-primary mb-1">
|
||||||
Ready to Get Started?
|
Ready to Get Started?
|
||||||
</h4>
|
|
||||||
<h5 className="text-body mb-8">
|
|
||||||
Start your project with a 14-day free trial
|
|
||||||
</h5>
|
</h5>
|
||||||
<a href="#landingPricing" className="btn btn-lg btn-primary">
|
<h5 className="text-body mb-8">
|
||||||
|
Start your project with a free trial
|
||||||
|
</h5>
|
||||||
|
{/* <a href="#landingPricing" className="btn btn-lg btn-primary">
|
||||||
Get Started
|
Get Started
|
||||||
</a>{" "}
|
</a>{" "} */}
|
||||||
<a
|
<a
|
||||||
href="/auth/reqest/demo"
|
href="/auth/reqest/demo"
|
||||||
className="btn btn-lg btn-primary"
|
className="btn btn-lg btn-primary"
|
||||||
@ -890,13 +897,6 @@ const LandingPage = () => {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6 pt-lg-12 text-center text-lg-end">
|
|
||||||
<img
|
|
||||||
style={{ width: "80%" }}
|
|
||||||
src="/img/images/contact-customer-service.png"
|
|
||||||
alt="hero elements"
|
|
||||||
></img>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -1056,7 +1056,10 @@ const LandingPage = () => {
|
|||||||
|
|
||||||
{/* Footer: Start */}
|
{/* Footer: Start */}
|
||||||
<footer className="landing-footer bg-body footer-text">
|
<footer className="landing-footer bg-body footer-text">
|
||||||
<div className="footer-top position-relative overflow-hidden z-1">
|
<div
|
||||||
|
className="footer-top position-relative overflow-hidden z-1"
|
||||||
|
hidden
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src="/img/backgrounds/footer-bg.png"
|
src="/img/backgrounds/footer-bg.png"
|
||||||
alt="footer bg"
|
alt="footer bg"
|
||||||
@ -1193,7 +1196,7 @@ const LandingPage = () => {
|
|||||||
|
|
||||||
<div className="col-lg-6 col-md-6 d-flex gap-3 align-items-center justify-content-end">
|
<div className="col-lg-6 col-md-6 d-flex gap-3 align-items-center justify-content-end">
|
||||||
<h6 className="footer-title mt-3">Download our app</h6>
|
<h6 className="footer-title mt-3">Download our app</h6>
|
||||||
<a href="javascript:void(0);">
|
<a href="javascript:void(0);" hidden>
|
||||||
<img src="/img/icons/apple-icon.png" alt="apple icon" />
|
<img src="/img/icons/apple-icon.png" alt="apple icon" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
@ -1209,21 +1212,9 @@ const LandingPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="footer-bottom py-3 py-md-5">
|
<div className="footer-bottom py-md-4">
|
||||||
<div className="container d-flex flex-wrap justify-content-between flex-md-row flex-column text-center text-md-start">
|
<div className="container d-flex flex-wrap justify-content-between flex-md-row flex-column text-center text-md-start">
|
||||||
<div className="mb-2 mb-md-0">
|
<div className="col-lg-4 col-md-4 d-flex align-items-center justify-content-start">
|
||||||
<span className="footer-bottom-text me-1">
|
|
||||||
©{new Date().getFullYear()}
|
|
||||||
</span>
|
|
||||||
<a
|
|
||||||
href="https://marcoaiot.com"
|
|
||||||
target="_blank"
|
|
||||||
className="text-white"
|
|
||||||
>
|
|
||||||
Marco AIoT Technologies Pvt. Ltd.,
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a
|
<a
|
||||||
href="https://www.facebook.com/marcoaiot/"
|
href="https://www.facebook.com/marcoaiot/"
|
||||||
className="me-4"
|
className="me-4"
|
||||||
@ -1242,6 +1233,34 @@ const LandingPage = () => {
|
|||||||
<img src="/img/icons/instagram.svg" alt="google icon" />
|
<img src="/img/icons/instagram.svg" alt="google icon" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-lg-4 col-md-4 mb-2 mb-md-0 d-flex gap-3 align-items-center justify-content-center">
|
||||||
|
<span className="footer-bottom-text me-1">
|
||||||
|
©{new Date().getFullYear()}
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
href="https://marcoaiot.com"
|
||||||
|
target="_blank"
|
||||||
|
className="text-white"
|
||||||
|
>
|
||||||
|
Marco AIoT Technologies Pvt. Ltd.,
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-lg-4 col-md-4 d-flex gap-3 align-items-center justify-content-end">
|
||||||
|
<h6 className="footer-title mt-3">Download our app</h6>
|
||||||
|
<a href="javascript:void(0);" hidden>
|
||||||
|
<img src="/img/icons/apple-icon.png" alt="apple icon" />
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://play.google.com/store/apps/details?id=com.marco.aiotstage&pcampaignid=web_share"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/img/icons/google-play-icon.png"
|
||||||
|
alt="google play icon"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
44
src/pages/Home/PlanCardSkeleton.jsx
Normal file
44
src/pages/Home/PlanCardSkeleton.jsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const SubscriptionPlanSkeleton = () => {
|
||||||
|
return (
|
||||||
|
<div className="col-xl-4 col-lg-6 col-md-6">
|
||||||
|
<div className="card h-100 shadow-sm border-0 p-3 text-center">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<div className="bg-light rounded-circle mx-auto mb-3" style={{ width: "50px", height: "50px" }}></div>
|
||||||
|
<div className="bg-light rounded w-75 mx-auto mb-2" style={{ height: "20px" }}></div>
|
||||||
|
<div className="bg-light rounded w-50 mx-auto" style={{ height: "16px" }}></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Price */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<div className="bg-light rounded w-50 mx-auto" style={{ height: "24px" }}></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Storage & Trial */}
|
||||||
|
<div className="d-flex justify-content-center gap-4 mb-5">
|
||||||
|
<div className="bg-light rounded" style={{ width: "100px", height: "16px" }}></div>
|
||||||
|
<div className="bg-light rounded" style={{ width: "100px", height: "16px" }}></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Features */}
|
||||||
|
<h6 className="fw-bold text-uppercase border-top pt-3 mb-3 text-center">
|
||||||
|
Features
|
||||||
|
</h6>
|
||||||
|
<ul className="list-unstyled text-start mb-4 ms-7">
|
||||||
|
{[1, 2, 3].map((i) => (
|
||||||
|
<li key={i} className="mb-3">
|
||||||
|
<div className="bg-light rounded" style={{ width: "70%", height: "16px" }}></div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{/* Button */}
|
||||||
|
<div className="bg-light rounded w-100" style={{ height: "40px" }}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SubscriptionPlanSkeleton;
|
@ -1,115 +1,7 @@
|
|||||||
// // src/components/SubscriptionPlans.jsx
|
|
||||||
// import React, { useState, useEffect } from "react";
|
|
||||||
// import axios from "axios";
|
|
||||||
|
|
||||||
// const SubscriptionPlans = () => {
|
|
||||||
// const [plans, setPlans] = useState([]);
|
|
||||||
// const [frequency, setFrequency] = useState(1); // 1=Monthly, 2=Quarterly, 3=Half-Yearly, 4=Yearly
|
|
||||||
// const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// const fetchPlans = async () => {
|
|
||||||
// try {
|
|
||||||
// setLoading(true);
|
|
||||||
// const res = await axios.get(
|
|
||||||
// `/api/market/list/subscription-plan?frequency=${frequency}`
|
|
||||||
// );
|
|
||||||
// setPlans(res.data?.data || []);
|
|
||||||
// } catch (err) {
|
|
||||||
// console.error("Error fetching plans:", err);
|
|
||||||
// } finally {
|
|
||||||
// setLoading(false);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// fetchPlans();
|
|
||||||
// }, [frequency]);
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <div className="container py-5">
|
|
||||||
// {/* Frequency Switcher */}
|
|
||||||
// <div className="text-center mb-4">
|
|
||||||
// <div className="btn-group" role="group" aria-label="Plan frequency">
|
|
||||||
// {["Monthly", "Quarterly", "Half-Yearly", "Yearly"].map((label, idx) => (
|
|
||||||
// <button
|
|
||||||
// key={idx}
|
|
||||||
// type="button"
|
|
||||||
// className={`btn btn-${frequency === idx + 1 ? "primary" : "outline-secondary"}`}
|
|
||||||
// onClick={() => setFrequency(idx + 1)}
|
|
||||||
// >
|
|
||||||
// {label}
|
|
||||||
// </button>
|
|
||||||
// ))}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Cards */}
|
|
||||||
// <div className="row g-4">
|
|
||||||
// {loading ? (
|
|
||||||
// <div className="text-center">Loading...</div>
|
|
||||||
// ) : plans.length === 0 ? (
|
|
||||||
// <div className="text-center">No plans found</div>
|
|
||||||
// ) : (
|
|
||||||
// plans.map((plan) => (
|
|
||||||
// <div key={plan.id} className="col-xl-4 col-lg-6 col-md-6">
|
|
||||||
// <div className="card h-100 shadow-sm">
|
|
||||||
// <div className="card-header text-center">
|
|
||||||
// <h4 className="mb-1">{plan.planName}</h4>
|
|
||||||
// <p className="text-muted small">{plan.description}</p>
|
|
||||||
// <div className="d-flex align-items-center justify-content-center">
|
|
||||||
// <span className="h2 text-primary fw-bold mb-0">
|
|
||||||
// {plan.currency?.symbol}
|
|
||||||
// {plan.price}
|
|
||||||
// </span>
|
|
||||||
// <sub className="h6 text-muted mb-n1 ms-1">/mo</sub>
|
|
||||||
// </div>
|
|
||||||
// <div className="text-muted">
|
|
||||||
// Max Users: {plan.maxUser} | Storage: {plan.maxStorage} MB
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// <div className="card-body">
|
|
||||||
// <ul className="list-unstyled">
|
|
||||||
// {plan.features?.modules &&
|
|
||||||
// Object.values(plan.features.modules).map((mod) => (
|
|
||||||
// <li key={mod.id} className="mb-2">
|
|
||||||
// <i className="bx bx-check text-success me-2"></i>
|
|
||||||
// {mod.name}{" "}
|
|
||||||
// {mod.enabled ? (
|
|
||||||
// <span className="badge bg-success ms-2">Enabled</span>
|
|
||||||
// ) : (
|
|
||||||
// <span className="badge bg-secondary ms-2">Disabled</span>
|
|
||||||
// )}
|
|
||||||
// </li>
|
|
||||||
// ))}
|
|
||||||
// <li className="mb-2">
|
|
||||||
// <i className="bx bx-support text-primary me-2"></i>
|
|
||||||
// Support:{" "}
|
|
||||||
// {plan.features?.supports?.prioritySupport
|
|
||||||
// ? "Priority"
|
|
||||||
// : plan.features?.supports?.phoneSupport
|
|
||||||
// ? "Phone & Email"
|
|
||||||
// : "Email Only"}
|
|
||||||
// </li>
|
|
||||||
// </ul>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// <div className="card-footer text-center">
|
|
||||||
// <button className="btn btn-primary w-100">Get Started</button>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// ))
|
|
||||||
// )}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export default SubscriptionPlans;
|
|
||||||
|
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import PlanCardSkeleton from "./PlanCardSkeleton";
|
||||||
|
|
||||||
const SubscriptionPlans = () => {
|
const SubscriptionPlans = () => {
|
||||||
const [plans, setPlans] = useState([]);
|
const [plans, setPlans] = useState([]);
|
||||||
@ -120,11 +12,10 @@ const SubscriptionPlans = () => {
|
|||||||
const fetchPlans = async () => {
|
const fetchPlans = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await axios.get(`http://localhost:5032/api/market/list/subscription-plan?frequency=${frequency}`, {
|
const res = await axios.get(
|
||||||
headers: {
|
`http://localhost:5032/api/market/list/subscription-plan?frequency=${frequency}`,
|
||||||
"Content-Type": "application/json"
|
{ headers: { "Content-Type": "application/json" } }
|
||||||
}
|
);
|
||||||
});
|
|
||||||
setPlans(res.data?.data || []);
|
setPlans(res.data?.data || []);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error fetching plans:", err);
|
console.error("Error fetching plans:", err);
|
||||||
@ -137,10 +28,10 @@ const SubscriptionPlans = () => {
|
|||||||
|
|
||||||
const frequencyLabel = (freq) => {
|
const frequencyLabel = (freq) => {
|
||||||
switch (freq) {
|
switch (freq) {
|
||||||
case 0: return "mo";
|
case 0: return "1 mo";
|
||||||
case 1: return "3 mo";
|
case 1: return "3 mo";
|
||||||
case 2: return "6 mo";
|
case 2: return "6 mo";
|
||||||
case 3: return "yr";
|
case 3: return "1 yr";
|
||||||
default: return "mo";
|
default: return "mo";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -155,7 +46,7 @@ const SubscriptionPlans = () => {
|
|||||||
key={idx}
|
key={idx}
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn btn-${frequency === idx ? "primary" : "outline-secondary"}`}
|
className={`btn btn-${frequency === idx ? "primary" : "outline-secondary"}`}
|
||||||
onClick={() => setFrequency(idx)} // use idx directly (0,1,2,3)
|
onClick={() => setFrequency(idx)}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</button>
|
</button>
|
||||||
@ -163,73 +54,88 @@ const SubscriptionPlans = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* Cards */}
|
{/* Cards */}
|
||||||
<div className="row g-4">
|
<div className="row g-4 mt-10">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="text-center">Loading...</div>
|
// Show 3 skeletons
|
||||||
|
<>
|
||||||
|
<PlanCardSkeleton />
|
||||||
|
<PlanCardSkeleton />
|
||||||
|
<PlanCardSkeleton />
|
||||||
|
</>
|
||||||
) : plans.length === 0 ? (
|
) : plans.length === 0 ? (
|
||||||
<div className="text-center">No plans found</div>
|
<div className="text-center">No plans found</div>
|
||||||
) : (
|
) : (
|
||||||
plans.map((plan) => (
|
plans.map((plan) => (
|
||||||
<div key={plan.id} className="col-xl-4 col-lg-6 col-md-6">
|
<div key={plan.id} className="col-xl-4 col-lg-6 col-md-6">
|
||||||
<div className="card h-100 shadow-sm">
|
<div className="card h-100 shadow-lg border-0 p-3 text-center p-10">
|
||||||
<div className="card-header text-center">
|
{/* Header */}
|
||||||
<h4 className="mb-1">{plan.planName}</h4>
|
<div className="mb-3">
|
||||||
<p className="text-muted small">{plan.description}</p>
|
<i className="bx bxs-package text-primary fs-1 mb-2"></i>
|
||||||
<div className="d-flex align-items-center justify-content-center">
|
<p className="card-title fs-3 fw-bold mb-1">{plan.planName}</p>
|
||||||
<span className="h2 text-primary fw-bold mb-0">
|
<p className="text-muted mb-0 fs-5">{plan.description}</p>
|
||||||
{plan.currency?.symbol}{plan.price}
|
|
||||||
</span>
|
|
||||||
<sub className="h6 text-muted mb-n1 ms-1">/{frequencyLabel(frequency)}</sub>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted">
|
|
||||||
Max Users: {plan.maxUser} | Storage: {plan.maxStorage} MB
|
{/* Price */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<h4 className="fw-semibold mt-auto mb-0 fs-3">
|
||||||
|
{plan.currency?.symbol} {plan.price}
|
||||||
|
<small className="text-muted ms-1">/ {frequencyLabel(frequency)}</small>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Storage & Trial */}
|
||||||
|
<div className="text-muted mb-5 d-flex justify-content-center gap-4">
|
||||||
|
<div>
|
||||||
|
<i className="fa-solid fa-hdd me-2"></i>
|
||||||
|
Storage {plan.maxStorage} MB
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i className="fa-regular fa-calendar-check text-success me-2"></i>
|
||||||
|
Trial Days {plan.trialDays}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="card-body">
|
{/* Features */}
|
||||||
<ul className="list-unstyled">
|
<h6 className="fw-bold text-uppercase border-top pt-3 mb-3 text-center">
|
||||||
|
Features
|
||||||
|
</h6>
|
||||||
|
<ul className="list-unstyled text-start mb-4 ms-7 fs-5">
|
||||||
{plan.features?.modules &&
|
{plan.features?.modules &&
|
||||||
Object.values(plan.features.modules).map((modGroup) =>
|
Object.values(plan.features.modules).map((mod) =>
|
||||||
Object.values(modGroup).map((mod) =>
|
|
||||||
mod && mod.name ? (
|
mod && mod.name ? (
|
||||||
<li key={mod.id} className="mb-2">
|
<li
|
||||||
<i className="bx bx-check text-success me-2"></i>
|
key={mod.id}
|
||||||
{mod.name}{" "}
|
className="d-flex align-items-center mb-4"
|
||||||
|
>
|
||||||
{mod.enabled ? (
|
{mod.enabled ? (
|
||||||
<span className="badge bg-success ms-2">Enabled</span>
|
<i className="fa-regular fa-circle-check text-success me-2"></i>
|
||||||
) : (
|
) : (
|
||||||
<span className="badge bg-secondary ms-2">Disabled</span>
|
<i className="fa-regular fa-circle-xmark text-danger me-2"></i>
|
||||||
)}
|
)}
|
||||||
|
{mod.name}
|
||||||
</li>
|
</li>
|
||||||
) : null
|
) : null
|
||||||
)
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<li className="mb-2">
|
|
||||||
<i className="bx bx-support text-primary me-2"></i>
|
|
||||||
Support:{" "}
|
|
||||||
{plan.features?.supports?.prioritySupport
|
|
||||||
? "Priority"
|
|
||||||
: plan.features?.supports?.phoneSupport
|
|
||||||
? "Phone & Email"
|
|
||||||
: "Email Only"}
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="card-footer text-center">
|
{/* Button */}
|
||||||
<button className="btn btn-primary w-100">Get Started</button>
|
<div className="mt-auto">
|
||||||
|
<Link
|
||||||
|
to="/auth/reqest/demo"
|
||||||
|
className="btn btn-outline-primary w-100 fw-bold"
|
||||||
|
>
|
||||||
|
Request a Demo
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SubscriptionPlans;
|
export default SubscriptionPlans;
|
||||||
|
|
||||||
|
@ -146,7 +146,8 @@ const LoginPage = () => {
|
|||||||
type={hidepass ? "password" : "text"}
|
type={hidepass ? "password" : "text"}
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
id="password"
|
id="password"
|
||||||
className="form-control form-control-xl shadow-none"
|
className={`form-control form-control-xl shadow-none ${errors.password ? "is-invalid" : ""
|
||||||
|
}`}
|
||||||
name="password"
|
name="password"
|
||||||
{...register("password")}
|
{...register("password")}
|
||||||
placeholder="••••••••••••"
|
placeholder="••••••••••••"
|
||||||
@ -155,7 +156,7 @@ const LoginPage = () => {
|
|||||||
<span className="input-group-text cursor-pointer border-start-0">
|
<span className="input-group-text cursor-pointer border-start-0">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-link p-0"
|
className="btn btn-link-secondary p-0"
|
||||||
onClick={() => setHidepass(!hidepass)}
|
onClick={() => setHidepass(!hidepass)}
|
||||||
>
|
>
|
||||||
{hidepass ? (
|
{hidepass ? (
|
||||||
@ -166,7 +167,15 @@ const LoginPage = () => {
|
|||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* ✅ Error message */}
|
||||||
|
{errors.password && (
|
||||||
|
<div className="invalid-feedback text-start" style={{ fontSize: "12px" }}>
|
||||||
|
{errors.password.message}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* Remember Me + Forgot Password */}
|
{/* Remember Me + Forgot Password */}
|
||||||
<div className="mb-3 d-flex justify-content-between align-items-center">
|
<div className="mb-3 d-flex justify-content-between align-items-center">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user