From 960673210b0b14c0ee7f03d0bc76042ba04af0a5 Mon Sep 17 00:00:00 2001 From: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:43:59 +0530 Subject: [PATCH 1/4] [UI] PRicing Form added Signed-off-by: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> --- src/components/PricingForm/index.js | 71 +++++++++++++++++++ .../PricingForm/pricingForm.style.js | 68 ++++++++++++++++++ src/sections/Pricing/index.js | 2 + 3 files changed, 141 insertions(+) create mode 100644 src/components/PricingForm/index.js create mode 100644 src/components/PricingForm/pricingForm.style.js diff --git a/src/components/PricingForm/index.js b/src/components/PricingForm/index.js new file mode 100644 index 000000000000..ff5d78e8d6dc --- /dev/null +++ b/src/components/PricingForm/index.js @@ -0,0 +1,71 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import { Formik, Form, Field } from "formik"; +import PricingFormWrapper from "./pricingForm.style"; + +const PricingForm = () => { + // Use the same naming convention as your other forms + const [memberFormOne, setMemberFormOne] = useState({}); + const [submit, setSubmit] = useState(false); + + useEffect(() => { + if (submit) { + axios + .post("https://hook.us1.make.com/7c1op88rysnmeitovt35fxzcv2spspp0", { + memberFormOne, + }) + .catch((err) => { + console.error("Error submitting the form:", err); + }); + } + }, [submit, memberFormOne]); + + return ( + +

Sign Up for More Pricing Info

+ { + // Store the form values in the memberFormOne state + setMemberFormOne(values); + // Trigger the effect to POST the data + setSubmit(true); + }} + > + {() => ( +
+
+ + +
+ +
+ + +
+ + +
+ )} +
+
+ ); +}; + +export default PricingForm; diff --git a/src/components/PricingForm/pricingForm.style.js b/src/components/PricingForm/pricingForm.style.js new file mode 100644 index 000000000000..5ad8d9fe1345 --- /dev/null +++ b/src/components/PricingForm/pricingForm.style.js @@ -0,0 +1,68 @@ +import styled from "styled-components"; + +const PricingFormWrapper = styled.div` + /* Center the form and give some breathing space */ + max-width: 500px; + margin: 3rem auto; + padding: 2rem; + border: 1px solid #e2e2e2; + border-radius: 8px; + background-color: #fff; + + h2 { + text-align: center; + margin-bottom: 1.5rem; + color: #333; + } + + form.pricing-form { + display: flex; + flex-direction: column; + gap: 1.5rem; + } + + .form-field { + display: flex; + flex-direction: column; + } + + label { + font-weight: 600; + margin-bottom: 0.5rem; + color: #555; + } + + input[type="text"], + input[type="email"] { + padding: 0.75rem; + font-size: 1rem; + border: 1px solid #ccc; + border-radius: 4px; + outline: none; + } + + input[type="text"]:focus, + input[type="email"]:focus { + border-color: #00b39f; + } + + button[type="submit"] { + width: fit-content; + align-self: center; + background-color: #00b39f; + color: #fff; + padding: 0.75rem 2rem; + font-size: 1rem; + font-weight: 600; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.25s ease-in-out; + } + + button[type="submit"]:hover { + background-color: #008577; + } +`; + +export default PricingFormWrapper; diff --git a/src/sections/Pricing/index.js b/src/sections/Pricing/index.js index d7e6f852ef80..761defe58ee0 100644 --- a/src/sections/Pricing/index.js +++ b/src/sections/Pricing/index.js @@ -5,6 +5,7 @@ import FAQ from "../General/Faq"; import Reviews from "./review-slider"; import options from "./generatePlans"; import PlanCard from "../../components/PlanCard"; +import PricingForm from "../../components/PricingForm"; const Pricing = () => { // const [monthly, setMonthly] = useState(false); @@ -46,6 +47,7 @@ const Pricing = () => { + From 504bd08249770d8bc8b35f344e8387dd27779cf5 Mon Sep 17 00:00:00 2001 From: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:44:30 +0530 Subject: [PATCH 2/4] [UI] Pricing Form added Signed-off-by: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> --- src/components/PricingForm/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/PricingForm/index.js b/src/components/PricingForm/index.js index ff5d78e8d6dc..a474223d624d 100644 --- a/src/components/PricingForm/index.js +++ b/src/components/PricingForm/index.js @@ -4,7 +4,6 @@ import { Formik, Form, Field } from "formik"; import PricingFormWrapper from "./pricingForm.style"; const PricingForm = () => { - // Use the same naming convention as your other forms const [memberFormOne, setMemberFormOne] = useState({}); const [submit, setSubmit] = useState(false); @@ -29,9 +28,7 @@ const PricingForm = () => { email: "", }} onSubmit={(values) => { - // Store the form values in the memberFormOne state setMemberFormOne(values); - // Trigger the effect to POST the data setSubmit(true); }} > From bc19fc078a9fbdbf11f6986149fbb473171a0ecc Mon Sep 17 00:00:00 2001 From: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> Date: Fri, 27 Dec 2024 19:03:06 +0530 Subject: [PATCH 3/4] styling updated modal added Signed-off-by: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> --- src/components/PlanCard/index.js | 96 +++++++++++----- src/components/PricingForm/index.js | 102 +++++++++++++---- .../PricingForm/pricingForm.style.js | 108 +++++++++++++----- src/sections/Pricing/index.js | 2 - 4 files changed, 226 insertions(+), 82 deletions(-) diff --git a/src/components/PlanCard/index.js b/src/components/PlanCard/index.js index b3b8cca35533..887bf82c84d5 100644 --- a/src/components/PlanCard/index.js +++ b/src/components/PlanCard/index.js @@ -1,10 +1,17 @@ -import React from "react"; +import React, { useState } from "react"; import Button from "../../reusecore/Button"; import { Col, Row, Container } from "../../reusecore/Layout"; import PlanCardWrapper from "./planCard.style"; import FeatureDetails from "./collapsible-details"; +import Modal from "react-modal"; +import PricingForm from "../PricingForm"; + +const PlanCard = ({ planData, isYearly }) => { + const [modalIsOpen, setModalIsOpen] = useState(false); + + const openModal = () => setModalIsOpen(true); + const closeModal = () => setModalIsOpen(false); -const PlanCard = ({ planData , isYearly }) => { if (!planData || !Array.isArray(planData) || planData.length === 0) { return
No plan data available
; } @@ -14,18 +21,13 @@ const PlanCard = ({ planData , isYearly }) => { {planData.map((x) => ( - //
- - {x.tier === "Personal" ?
Free Forever
: null} - - {x.tier === "Team Designer" ?
Most Popular
: null} + {x.tier === "Personal" &&
Free Forever
} + {x.tier === "Team Designer" &&
Most Popular
} {x.pricing_coming_soon && ( -
- {x.pricing_coming_soon} -
+
{x.pricing_coming_soon}
)}

{x.tier}

@@ -35,50 +37,42 @@ const PlanCard = ({ planData , isYearly }) => { {isYearly ? ( x.yearlyprice !== undefined ? (
- $ - {x.yearlyprice === 0 - ? "0" - : x.yearlyprice.toFixed(0)} + + $ + {x.yearlyprice === 0 ? "0" : x.yearlyprice.toFixed(0)} USD per user/year
) : ( -
- {x.pricing_coming_soon} -
+
{x.pricing_coming_soon}
) ) : ( x.monthlyprice !== undefined ? (
- $ - {x.monthlyprice === 0 - ? "0" - : x.monthlyprice.toFixed(0)} + + $ + {x.monthlyprice === 0 ? "0" : x.monthlyprice.toFixed(0)} USD per user/month
) : ( -
- {x.pricing_coming_soon} -
+
{x.pricing_coming_soon}
) )}
-
{x.byline2}
@@ -95,12 +89,56 @@ const PlanCard = ({ planData , isYearly }) => { ))} - ))}
+ + +

Contact Sales

+
+ +
+
); }; diff --git a/src/components/PricingForm/index.js b/src/components/PricingForm/index.js index a474223d624d..e8c2a3060c3d 100644 --- a/src/components/PricingForm/index.js +++ b/src/components/PricingForm/index.js @@ -21,11 +21,14 @@ const PricingForm = () => { return ( -

Sign Up for More Pricing Info

{ setMemberFormOne(values); @@ -34,30 +37,80 @@ const PricingForm = () => { > {() => (
-
- - -
+ {/* Scrollable Form Fields */} +
+ {/* All form fields here */} +
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
-
- - +
+ + +
+
+ + +
- + {/* Submit Button */} +
+ +
)} @@ -66,3 +119,4 @@ const PricingForm = () => { }; export default PricingForm; + diff --git a/src/components/PricingForm/pricingForm.style.js b/src/components/PricingForm/pricingForm.style.js index 5ad8d9fe1345..95a59c503fb9 100644 --- a/src/components/PricingForm/pricingForm.style.js +++ b/src/components/PricingForm/pricingForm.style.js @@ -1,59 +1,86 @@ import styled from "styled-components"; const PricingFormWrapper = styled.div` - /* Center the form and give some breathing space */ - max-width: 500px; - margin: 3rem auto; + max-width: 800px; + margin: 1rem auto; padding: 2rem; - border: 1px solid #e2e2e2; border-radius: 8px; - background-color: #fff; + background-color: var(--background); + color: var(--text-color); + display: flex; + flex-direction: column; + max-height: 90vh; + overflow: hidden; + + .form-content { + flex: 1; + overflow-y: auto; /* Enable scrolling */ + margin-bottom: 1rem; + scrollbar-width: none; /* Hide scrollbar for Firefox */ + -ms-overflow-style: none; /* Hide scrollbar for IE and Edge */ + + /* Hide scrollbar for Webkit browsers (Chrome, Safari, Edge) */ + &::-webkit-scrollbar { + display: none; + } + } h2 { text-align: center; margin-bottom: 1.5rem; - color: #333; - } - - form.pricing-form { - display: flex; - flex-direction: column; - gap: 1.5rem; + color: var(--text-color); + font-size: 20px; + font-weight: bold; } .form-field { - display: flex; - flex-direction: column; + margin-bottom: 1.5rem; } label { - font-weight: 600; + font-weight: bold; margin-bottom: 0.5rem; - color: #555; + font-size: 14px; + color: var(--label-color); } input[type="text"], - input[type="email"] { + input[type="email"], + textarea, + input[type="number"] { + width: 100%; padding: 0.75rem; font-size: 1rem; - border: 1px solid #ccc; + border: 1px solid ${props => props["data-theme"] === "dark" ? "#000000" : "#ffffff"}; border-radius: 4px; + background-color: var(--input-bg); + color: var(--input-text); outline: none; } - input[type="text"]:focus, - input[type="email"]:focus { - border-color: #00b39f; + textarea { + resize: none; + min-height: 100px; + } + + input:focus, + textarea:focus { + border-color: var(--primary-color); + box-shadow: 0 0 5px var(--primary-color); + } + + .form-footer { + display: flex; + justify-content: center; + margin-top: 1rem; } button[type="submit"] { - width: fit-content; - align-self: center; - background-color: #00b39f; - color: #fff; + background-color: #03d3a9; + color: #ffffff; padding: 0.75rem 2rem; font-size: 1rem; - font-weight: 600; + font-weight: bold; border: none; border-radius: 4px; cursor: pointer; @@ -61,7 +88,34 @@ const PricingFormWrapper = styled.div` } button[type="submit"]:hover { - background-color: #008577; + background-color: var(--button-hover-bg); + } + + /* Light and Dark Mode Variables */ + :root { + --background: #ffffff; + --text-color: #333333; + --label-color: #555555; + --input-bg: #f9f9f9; + --input-border: #ffffff; + --input-text: #333333; + --button-bg: #03D3A9; + --button-text: #ffffff; + --button-hover-bg: #03d3a9; + --primary-color: #007bff; + } + + [data-theme="dark"] { + --background: #1a1a1a; + --text-color: #f0f0f0; + --label-color: #aaaaaa; + --input-bg: #333333; + --input-border: #000000; + --input-text: #ffffff; + --button-bg: #0d6efd; + --button-text: #ffffff; + --button-hover-bg: #0a58ca; + --primary-color: #0d6efd; } `; diff --git a/src/sections/Pricing/index.js b/src/sections/Pricing/index.js index 761defe58ee0..d7e6f852ef80 100644 --- a/src/sections/Pricing/index.js +++ b/src/sections/Pricing/index.js @@ -5,7 +5,6 @@ import FAQ from "../General/Faq"; import Reviews from "./review-slider"; import options from "./generatePlans"; import PlanCard from "../../components/PlanCard"; -import PricingForm from "../../components/PricingForm"; const Pricing = () => { // const [monthly, setMonthly] = useState(false); @@ -47,7 +46,6 @@ const Pricing = () => {
- From 0bf65b9ac3e76288f191f816fe144bb34da3e868 Mon Sep 17 00:00:00 2001 From: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> Date: Fri, 27 Dec 2024 19:20:03 +0530 Subject: [PATCH 4/4] Products Page plan card data fixed Signed-off-by: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> --- src/sections/Products/index.js | 142 +-------------------------------- 1 file changed, 1 insertion(+), 141 deletions(-) diff --git a/src/sections/Products/index.js b/src/sections/Products/index.js index 40caa00cad8a..7369c6479a02 100644 --- a/src/sections/Products/index.js +++ b/src/sections/Products/index.js @@ -11,152 +11,12 @@ import mesheryLogo from "../../assets/images/meshery/icon-only/meshery-logo-ligh import cloudicon from "./images/cloud.svg"; import layer5 from "../../assets/images/layer5/5 icon/svg/light/5-light-no-trim.svg"; import kanvas from "../../assets/images/kanvas/icon-only/kanvas-icon-color.svg"; -import comingSoon from "./icons/coming-soon.webp"; import { useStyledDarkMode } from "../../theme/app/useStyledDarkMode"; import PlanCard from "../../components/PlanCard"; import { Row } from "../../reusecore/Layout"; import Reviews from "../Pricing/review-slider"; +import options from "../../sections/Pricing/generatePlans"; -const options = [ - { - tier: "Personal", - featured: true, - monthlyprice: 0, - yearlyprice: 0, - byline: "Open Source features, plus:", - button: ["Join for Free", "https://cloud.layer5.io"], - summary: [ - { - id: 0, - category: "Cloud Native Design Patterns", - description: - "Import and export your designs using your local filesystem or remote URL.", - }, - { - id: 1, - category: "Multiple Kubernetes Clusters", - description: - "Ongoing synchronization of Kubernetes configuration, workloads and cloud native infrastructure changes across any number of Kubernetes clusters.", - }, - { - id: 2, - category: "Cluster Discovery", - description: - "Day 2 support for ongoing synchronization of Kubernetes configuration, workloads and cloud native infrastructure changes.", - }, - { - id: 3, - category: "Microservices Performance", - description: - "Continuous visibility across all of your clusters and workloads.", - }, - { - id: 4, - category: "Load Generation", - description: - "Single Load Generator: Support testing multiple endpoints simultaneously.", - }, - { - id: 5, - category: "MeshMark", - description: "Identify the cost of a specific network function.", - }, - ], - }, - { - tier: "Team", - featured: false, - monthlyprice: 9.99, - yearlyprice: 100, - byline: "Everything in Free, plus:", - button: [ - "Contact Sales", - "https://us15.list-manage.com/contact-form?u=6b50be5aea3dfe1fd4c041d80&form_id=d0ffe17c92d8014ede6b721aa16096e8", - ], - summary: [ - { - id: 0, - category: "Dry-run", - description: - "Test and verify configuration changes in a separate environment.", - }, - { - id: 1, - category: "Design Reviews", - description: - "Discuss any design by leaving review comments or notes on a specific design. Control who has access, notify discussion participants with updates, and link from anywhere.", - }, - { - id: 2, - category: "Visual Design", - description: - "Drag-n-drop cloud native infrastructure designer to configure, model, and deploy your workloads", - }, - { - id: 3, - category: "Performance Profiles", - description: - "Share performance profiles and test results with individual users or teams.", - }, - { - id: 4, - category: "Built-in Roles", - description: "Static - out of the box", - }, - { - id: 5, - category: "Standard Support", - description: - "Layer5 Support can help you troubleshoot issues you run into while using Meshery. Get support via the web.", - }, - ], - }, - { - tier: "Enterprise", - featured: false, - monthlyprice: 15.99, - yearlyprice: 180, - pricing_coming_soon: , - byline: "Everything in Team, plus:", - button: ["Coming Soon", ""], - summary: [ - { - id: 0, - category: "User-defined Roles", - description: "Customizable roles for specific permission assignments", - }, - { - id: 1, - category: "Authentication: LDAP", - description: - "Access Meshery using your existing accounts and centrally manage repository access.", - }, - { - id: 2, - category: "Authentication: SAML", - description: - "Use an identity provider to manage the identities of Meshery users and applications.", - }, - { - id: 3, - category: "Self-hosted Deployment", - description: - "Self-hosted Meshery Cloud for on-prem appliances or self-managed cloud tenants.", - }, - { - id: 4, - category: "Traffic Replay", - description: "Visual event replay in Kanvas", - }, - { - id: 5, - category: "Phone Support", - description: - "Layer5 Support can help you troubleshoot issues you run into while using Meshery. Get support via phone.", - }, - ], - }, -]; const CardsData = [ { id: 1,