From 6e5eba5206a8fd243dd663f57f02a8b5104456f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20David=20S=C3=A1nchez?= <49158320+Arzoid29@users.noreply.github.com> Date: Sun, 15 Oct 2023 18:41:06 -0400 Subject: [PATCH 1/4] Feat: Adding the princing page --- src/app/pricing/page.tsx | 21 ++ src/components/atoms/counter/index.tsx | 22 ++ .../icons/plans-icons/SA__Advanced_Plan.svg | 1 + .../icons/plans-icons/SA__Enterprise_Plan.svg | 1 + .../icons/plans-icons/SA__Essentials_Plan.svg | 1 + .../atoms/icons/plans-icons/index.ts | 9 + src/components/atoms/plan-buttons/index.tsx | 22 ++ src/components/atoms/plan-card/index.tsx | 99 +++++++ .../atoms/princing-mobile/index.tsx | 124 +++++++++ .../sections/princing/comparison/index.tsx | 53 ++++ .../sections/princing/princing-hero/index.tsx | 20 ++ .../sections/princing/princing-plan/index.tsx | 42 +++ .../princing/princing-questions/index.tsx | 43 +++ src/locales/lang/en.json | 257 +++++++++++++----- src/model/api/princing-data/data.ts | 148 ++++++++++ src/model/api/questions/data.ts | 30 ++ src/model/interactions/use-pricing/index.ts | 69 +++++ src/model/types/index.ts | 38 ++- 18 files changed, 926 insertions(+), 74 deletions(-) create mode 100644 src/app/pricing/page.tsx create mode 100644 src/components/atoms/counter/index.tsx create mode 100644 src/components/atoms/icons/plans-icons/SA__Advanced_Plan.svg create mode 100644 src/components/atoms/icons/plans-icons/SA__Enterprise_Plan.svg create mode 100644 src/components/atoms/icons/plans-icons/SA__Essentials_Plan.svg create mode 100644 src/components/atoms/icons/plans-icons/index.ts create mode 100644 src/components/atoms/plan-buttons/index.tsx create mode 100644 src/components/atoms/plan-card/index.tsx create mode 100644 src/components/atoms/princing-mobile/index.tsx create mode 100644 src/components/organism/sections/princing/comparison/index.tsx create mode 100644 src/components/organism/sections/princing/princing-hero/index.tsx create mode 100644 src/components/organism/sections/princing/princing-plan/index.tsx create mode 100644 src/components/organism/sections/princing/princing-questions/index.tsx create mode 100644 src/model/api/princing-data/data.ts create mode 100644 src/model/api/questions/data.ts create mode 100644 src/model/interactions/use-pricing/index.ts diff --git a/src/app/pricing/page.tsx b/src/app/pricing/page.tsx new file mode 100644 index 0000000..6f0a031 --- /dev/null +++ b/src/app/pricing/page.tsx @@ -0,0 +1,21 @@ +"use client"; +import { Footer } from "@/components/organism/sections/footer"; +import { PricingComparison } from "@/components/organism/sections/princing/comparison"; +import { PricingHero } from "@/components/organism/sections/princing/princing-hero"; +import { PricingPlans } from "@/components/organism/sections/princing/princing-plan"; +import { PricingQuestions } from "@/components/organism/sections/princing/princing-questions"; +import React, { useState } from "react"; + +export default function page() { + const [isFull, setIsFull] = useState(false); + const handleIsFull = () => setIsFull(!isFull); + return ( +
+ + + {isFull && } + +
+
+ ); +} diff --git a/src/components/atoms/counter/index.tsx b/src/components/atoms/counter/index.tsx new file mode 100644 index 0000000..aaa9b21 --- /dev/null +++ b/src/components/atoms/counter/index.tsx @@ -0,0 +1,22 @@ + +import { MdAdd, MdRemove } from "react-icons/md"; + +interface CounterProps { + enable?: { + add?: boolean, + remove?: boolean + }, + add: () => void, + remove: () => void, +} + +export function Counter ({ enable = { remove: true, add: false }, add, remove }: CounterProps) { + return ( +
+ Unlimited users + + + +
+ ) +} \ No newline at end of file diff --git a/src/components/atoms/icons/plans-icons/SA__Advanced_Plan.svg b/src/components/atoms/icons/plans-icons/SA__Advanced_Plan.svg new file mode 100644 index 0000000..f2eacf7 --- /dev/null +++ b/src/components/atoms/icons/plans-icons/SA__Advanced_Plan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/atoms/icons/plans-icons/SA__Enterprise_Plan.svg b/src/components/atoms/icons/plans-icons/SA__Enterprise_Plan.svg new file mode 100644 index 0000000..d884db0 --- /dev/null +++ b/src/components/atoms/icons/plans-icons/SA__Enterprise_Plan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/atoms/icons/plans-icons/SA__Essentials_Plan.svg b/src/components/atoms/icons/plans-icons/SA__Essentials_Plan.svg new file mode 100644 index 0000000..25b302a --- /dev/null +++ b/src/components/atoms/icons/plans-icons/SA__Essentials_Plan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/atoms/icons/plans-icons/index.ts b/src/components/atoms/icons/plans-icons/index.ts new file mode 100644 index 0000000..5e9f2e3 --- /dev/null +++ b/src/components/atoms/icons/plans-icons/index.ts @@ -0,0 +1,9 @@ +import AdvancePlan from './SA__Advanced_Plan.svg'; +import EnterPrisePlan from './SA__Enterprise_Plan.svg'; +import EssentialsPlan from './SA__Essentials_Plan.svg'; + +export const plansIcons: { code: string, path: string }[] = [ + { code: "ADVC", path: AdvancePlan }, + { code: "ENTPRS", path: EnterPrisePlan }, + { code: "ESS", path: EssentialsPlan }, +] \ No newline at end of file diff --git a/src/components/atoms/plan-buttons/index.tsx b/src/components/atoms/plan-buttons/index.tsx new file mode 100644 index 0000000..cbb4b1a --- /dev/null +++ b/src/components/atoms/plan-buttons/index.tsx @@ -0,0 +1,22 @@ +import classNames from 'classnames'; +import React from 'react' + +type Props = { + handleIsAnnually: any, + currentActive : "year" |"month" +} +function buttonClass(isActive: boolean) { + return classNames('p-4 py-2 rounded-md font-semibold duration-500 transition-all relative shadow', { 'bg-white text-orange-500': !isActive }, { 'bg-orange-500 text-white': isActive }); + } + +export default function ButtonPlans({handleIsAnnually,currentActive}: Props) { + return ( +
+ + +
+ ) +} \ No newline at end of file diff --git a/src/components/atoms/plan-card/index.tsx b/src/components/atoms/plan-card/index.tsx new file mode 100644 index 0000000..0d941f3 --- /dev/null +++ b/src/components/atoms/plan-card/index.tsx @@ -0,0 +1,99 @@ +import { MdCheck } from "react-icons/md"; +import { SiHackthebox } from "react-icons/si"; +import { plansIcons } from "../icons/plans-icons"; +import { buildIcon } from "../salesIcon"; + +import { Counter } from "../counter"; +import usePricing from "@/model/interactions/use-pricing"; +import { Plan } from "@/model/types"; + +interface PlanCardProps { + plan: Plan; + add?: () => {}; + remove?: () => {}; + annually?: boolean; + price: number; +} + +export function PlanCard({ plan, price }: PlanCardProps) { + const { users, addUsers, removeUsers } = usePricing(); + + return ( +
+
+ {buildIcon({ + data: plansIcons, + code: plan.code, + fallback: , + size: { width: 64, height: 64 }, + })} +
+
+
+

{plan.name}

+

{plan.desc}

+
+
+
+ {!plan.custom && ( +
+

{plan.starting_at?.name}

+ +

${price}

+ /mo +
+ +
+ )} + + {plan.custom && ( +
+

{plan.custom.contact_us}

+

{plan.custom.pricing}

+
+

{plan.custom.users}

+
+
+ )} +
+
+
+ {/* perks */} +
    + {plan.perks.map((perk) => ( +
  • + {perk.perk}{" "} + {perk.name} +
  • + ))} +
+ {/* features */} +
+ {plan.features.name} +
    + {plan.features.perks.map((perk, i) => { + return ( +
  • + + {perk} +
  • + ); + })} +
+
+
+ ); +} diff --git a/src/components/atoms/princing-mobile/index.tsx b/src/components/atoms/princing-mobile/index.tsx new file mode 100644 index 0000000..2c8076b --- /dev/null +++ b/src/components/atoms/princing-mobile/index.tsx @@ -0,0 +1,124 @@ +import { PricingData } from "@/model/api/princing-data/data"; +import React from "react"; +import { MdCheck } from "react-icons/md"; +import { SiHackthebox } from "react-icons/si"; +import { plansIcons } from "../icons/plans-icons"; +import { buildIcon } from "../salesIcon"; +import usePricing from "@/model/interactions/use-pricing"; + +import ButtonPlans from "../plan-buttons"; +import { Counter } from "../counter"; + +export default function PricingMobile() { + const { currentActive, current, price, handleIsActive, handleIsAnnually,addUsers,removeUsers,users } = + usePricing(); + return ( +
+
+ +
+
+
+ {PricingData.plans.map((plan, i) => { + return ( +
+ +
+ ); + })} +
+ +
+
+
+ {buildIcon({ + data: plansIcons, + code: PricingData.plans[current].code, + fallback: , + size: { width: 64, height: 64 }, + })} +
+

+ {PricingData.plans[current].name} +

+

{PricingData.plans[current].desc}

+
+
+
+ {!PricingData.plans[current].custom && ( +
+

+ {PricingData.plans[current].starting_at?.name} +

+ +

${price}

+ /mo +
+ +
+ )} + + {PricingData.plans[current].custom && ( +
+

+ {PricingData.plans[current].custom?.contact_us} +

+

+ {PricingData.plans[current].custom?.pricing} +

+

+ {PricingData.plans[current].custom?.users} +

+
+ )} +
+
+ {PricingData.plans[current].perks.map((perk) => { + return ( +
+ {perk.perk} {perk.name} +
+ ); + })} +
+ +
+

+ {PricingData.plans[current].features.name} +

+ {PricingData.plans[current].features.perks.map((perk) => { + return ( +
+ {perk} +
+ ); + })} +
+
+
+
+ ); +} diff --git a/src/components/organism/sections/princing/comparison/index.tsx b/src/components/organism/sections/princing/comparison/index.tsx new file mode 100644 index 0000000..1ce9bb4 --- /dev/null +++ b/src/components/organism/sections/princing/comparison/index.tsx @@ -0,0 +1,53 @@ +import { PlansInfo } from '@/model/api/princing-data/data'; +import { MdCheck, MdRemove } from 'react-icons/md'; +import { Section } from '@/components/atoms/section'; + +export function PricingComparison (){ + return ( +
+
+
+

{PlansInfo.title}

+
+
+
+
+
+
+ {PlansInfo.plans_names.map(plan => { + return
+

{plan.name}

+
+ })} +
+
+
+
+ {PlansInfo.features.map(feature => { + return
+
+

{feature.name}

+
+
+ {feature.perks.map(perk => { + if (perk === 'yes') { + return
+ +
+ } else if (perk === 'no') { + return
+ +
+ } else { + return

{perk}

+ } + })} +
+
+ })} +
+
+
+
+ ) +} diff --git a/src/components/organism/sections/princing/princing-hero/index.tsx b/src/components/organism/sections/princing/princing-hero/index.tsx new file mode 100644 index 0000000..2eae2b1 --- /dev/null +++ b/src/components/organism/sections/princing/princing-hero/index.tsx @@ -0,0 +1,20 @@ +import Header from '@/components/organism/header'; +import { Section } from '@/components/atoms/section'; +import { translate } from '@/locales'; + + +export function PricingHero() { + return ( +
+
+
+
+
+

{translate("pricing.pricingHero.title")}

+

{translate("pricing.pricingHero.desc")}

+
+
+
+
+ ) +} diff --git a/src/components/organism/sections/princing/princing-plan/index.tsx b/src/components/organism/sections/princing/princing-plan/index.tsx new file mode 100644 index 0000000..02c307c --- /dev/null +++ b/src/components/organism/sections/princing/princing-plan/index.tsx @@ -0,0 +1,42 @@ +import { PlanCard } from "@/components/atoms/plan-card"; +import { MdArrowDropDown } from "react-icons/md"; +import { PricingData } from "@/model/api/princing-data/data"; +import { motion } from 'framer-motion'; + + +import { Section } from "@/components/atoms/section"; +import usePricing from "@/model/interactions/use-pricing"; + +import PricingMobile from "@/components/atoms/princing-mobile"; +import ButtonPlans from "@/components/atoms/plan-buttons"; + +interface PricingHeroProps { + isClicked: boolean, + onClick: () => void +} + +export function PricingPlans({ isClicked, onClick }:PricingHeroProps) { + const {handleIsAnnually,currentActive, getDelay,price} = usePricing(); + + + return ( +
+
+
+ +
+
+ {PricingData.plans.map((plan, i) => + + )} +
+
+ + + {!isClicked && + See Full Feature Comparison + } +
+
+ ) +} diff --git a/src/components/organism/sections/princing/princing-questions/index.tsx b/src/components/organism/sections/princing/princing-questions/index.tsx new file mode 100644 index 0000000..12d8fa1 --- /dev/null +++ b/src/components/organism/sections/princing/princing-questions/index.tsx @@ -0,0 +1,43 @@ +import { Questions } from "@/model/api/questions/data"; +import { calendlyLink } from "@/model/api/routes-data/data"; +import { Section } from "@/components/atoms/section"; + +type Props = { + id: string; +}; + +export function PricingQuestions({ id }: Props) { + return ( +
+
+

{Questions.title}

+ +
+ {Questions.questions.map((question) => { + return ( +
+

+ {question.question} +

+

{question.answer}

+
+ ); + })} +
+ +
+

+ {Questions.banner.text} +

+
+ + + + +
+
+
+ ); +} diff --git a/src/locales/lang/en.json b/src/locales/lang/en.json index 31f2f20..81619bb 100644 --- a/src/locales/lang/en.json +++ b/src/locales/lang/en.json @@ -199,80 +199,79 @@ } ] }, - "benefitsData":{ + "benefitsData": { "title": "Here's How Everyone Involved Benefits", "benefits": [ - { - "title": "More sales", - "desc": "Simplify the sales process so your sales team has more time to do what matters most — sell more." - }, - { - "title": "Improve NPS", - "desc": "Provide a frictionless and convenient experience to your customers by completing the sale straight from their phones." - }, - { - "title": "Save money", - "desc": "Replace the many one-off applications and systems you currently use to complete the sale with off-the-shelf or custom Sales Actions." - }, - { - "title": "Complete sales faster", - "desc": "Make your salespeople super efficient by simplifying the collection and sharing of information. Handling customer interactions has never been easier!" - }, - { - "title": "Less mundane work", - "desc": "No more chasing customers for emails, scans, and papers, or switching between multiple systems to manually enter information to complete the sale." - }, - { - "title": "Reduce errors", - "desc": "Reduce unnecessary errors with e-Forms and e-Signatures that are smart, fully integrated with all of your existing systems." - }, - { - "title": "Reduce friction", - "desc": "Eliminate the emails, scans, multiple portals and all the back and forth by completing the sale straight from customers’ mobile device" - }, - { - "title": "Save time", - "desc": "Slash time by allowing customers to complete everything on their mobile device, from e-Signatures to uploading documents to e-Forms." - }, - { - "title": "Delight customers", - "desc": "Create happy and returning customers by providing a frictionless and personalized sales experience." - } + { + "title": "More sales", + "desc": "Simplify the sales process so your sales team has more time to do what matters most — sell more." + }, + { + "title": "Improve NPS", + "desc": "Provide a frictionless and convenient experience to your customers by completing the sale straight from their phones." + }, + { + "title": "Save money", + "desc": "Replace the many one-off applications and systems you currently use to complete the sale with off-the-shelf or custom Sales Actions." + }, + { + "title": "Complete sales faster", + "desc": "Make your salespeople super efficient by simplifying the collection and sharing of information. Handling customer interactions has never been easier!" + }, + { + "title": "Less mundane work", + "desc": "No more chasing customers for emails, scans, and papers, or switching between multiple systems to manually enter information to complete the sale." + }, + { + "title": "Reduce errors", + "desc": "Reduce unnecessary errors with e-Forms and e-Signatures that are smart, fully integrated with all of your existing systems." + }, + { + "title": "Reduce friction", + "desc": "Eliminate the emails, scans, multiple portals and all the back and forth by completing the sale straight from customers’ mobile device" + }, + { + "title": "Save time", + "desc": "Slash time by allowing customers to complete everything on their mobile device, from e-Signatures to uploading documents to e-Forms." + }, + { + "title": "Delight customers", + "desc": "Create happy and returning customers by providing a frictionless and personalized sales experience." + } ] - -}, -"howItWorks":{ - "title": "Simple To Use By Sales Team", - "desc": "3 easy steps to transform your sales completion process without changing it – no retraining necessary.", - "actions": [ - { - "code": "HIW-ASA", - "title": "Share Completion Tasks", - "desc": "Salespeople simply share the relevant Completion Tasks with their customers to review, fill out, sign, and submit, right from their mobile devices.", - "kind": "orange", - "delay": 0 - }, - { - "code": "HIW-IWC", - "title": "Monitor Completion Status", - "desc": "Salespeople have full visibility of the customers’ completion status - whether and when they have opened and completed the Tasks.", - "kind": "purple", - "delay": 0.5 }, - { - "code": "HIW-CTS", - "title": "Receive Data", - "desc": "All the data and files collected from the customers automatically import into your CRM and other SOR based on the workflows established.", - "kind": "normal", - "delay": 0.8 - } - ] + "howItWorks": { + "title": "Simple To Use By Sales Team", + "desc": "3 easy steps to transform your sales completion process without changing it – no retraining necessary.", + "actions": [ + { + "code": "HIW-ASA", + "title": "Share Completion Tasks", + "desc": "Salespeople simply share the relevant Completion Tasks with their customers to review, fill out, sign, and submit, right from their mobile devices.", + "kind": "orange", + "delay": 0 + }, + { + "code": "HIW-IWC", + "title": "Monitor Completion Status", + "desc": "Salespeople have full visibility of the customers’ completion status - whether and when they have opened and completed the Tasks.", + "kind": "purple", + "delay": 0.5 + }, + { + "code": "HIW-CTS", + "title": "Receive Data", + "desc": "All the data and files collected from the customers automatically import into your CRM and other SOR based on the workflows established.", + "kind": "normal", + "delay": 0.8 + } + ] }, - "Customers":{ - "title":" Simple to Use by Customers", + "Customers": { + "title": " Simple to Use by Customers", "desc": " Provide customers with instant, real-time, mobile-first completion experiences. Interactions with their salesperson are done in the fastest and most personalized way, Amazon style. By receiving personalized texts customers can simply click on the provided links to enter, sign, upload, verify, pay, choose, etc., whatever is needed to complete the sale." }, - "painless":{ + "painless": { "title": "Completing Sales Should Be Painless", "banner": { "cta": "Book Demo", @@ -296,7 +295,7 @@ } ] }, - "swiperData":{ + "swiperData": { "title": "Simple to Manage by Leadership", "desc": "We make it extremely easy for management to assemble the ideal Completion Panel for their sales team. On our web portal managers can easily select customizable off-the-shelf Completion Tools, integrate their existing ones, or mix and match.", "options": { @@ -310,18 +309,130 @@ "url": "/images/ActionBuilder/Step1.png", "title": "Select off-the-shelf Completion Tools", "desc": "Choose off-the-shelf Completion Tool templates from our ever-growing Template Library." - },{ + }, + { "option": "Customize your own", "url": "/images/ActionBuilder/Step2.png", "title": "Customize your own", "desc": "Modify texts, images, logos, documents, and page layout on the Completion Tools based on your needs." - },{ - "option": "Add to your Completion Panel", + }, + { + "option": "Add to your Completion Panel", "url": "/images/ActionBuilder/Step3.png", "title": "Add to your Completion Panel", - "desc": "Turn on and off Completion Tools on the Completion Panel and list them in the sequence you prefer." + "desc": "Turn on and off Completion Tools on the Completion Panel and list them in the sequence you prefer." } ] - } + } + }, + "pricing": { + "pricingHero": { + "title": "Find a Plan That Fits", + "desc": "Simple pricing structure with no upfront commitment or implementation costs. Flexibility built for organizations of any industry, use case, and size." + }, + "questions": [ + { + "question": "Who is SalesAssist for?", + "answer": "Businesses who need to optimize their sales process to reach growing revenue targets. Those who value being efficient and providing an exceptional experience to their customers." + }, + { + "question": "Does SalesAssist integrate with my systems?", + "answer": "YES. We integrate with major CRMs and DMSs." + }, + { + "question": "Can I see SalesAssist before buying? How much is it?", + "answer": "Yes! Simply click “Book Demo”. For pricing, see our Pricing Page or talk to us today." + }, + { + "question": "What’s the difference between annual and monthly billing?", + "answer": "The difference is how often you pay your subscription fee. With monthly billing, you will be charged on the same day each month. With annual billing, you are charged once for the whole year." + }, + { + "question": "Which payment methods do you accept?", + "answer": "There are different ways to pay for SalesAssist including major credit cards, debit cards and PayPal." + } + ], + "title": "Frequently Asked Questions", + "banner": { + "text": "Let’s Simplify How You Gather Info from Customers", + "button": "Book Demo" + }, + + "pricingData": { + "plans": [ + { + "name": "Essential", + "desc": "Perfect solution for small teams with simple sales process", + "code": "ESS", + "users": 0, + "limit": 0, + "perks": { "name": "Sales Widgets" }, + "features": { + "name": "Features", + "perks": [ + "Native Mobile Android and iOS apps", + "Web Portal", + "Sales Actions tracking", + "Digital Jacket", + "Template Gallery", + "Onboarding & Email Support" + ] + } + }, + { + "name": "Advanced", + "desc": "Everything you need to simplify and streamline any sales process", + "code": "ADVC", + "users": 0, + "limit": 0, + "price_per_user": { + "year": 0, + "month": 0 + }, + "starting_at": { + "name": "", + "year": 799, + "month": 899 + }, + "perks": [{ "name": "Sales Widgets", "perk": 10 }], + "features": { + "name": "All features from Essential, plus:", + "perks": [ + "CRM Embedded Extension", + "Two-way CRM Sync", + "Autofilled Forms and PDFs", + "e-Sign Sales Widget", + "OCR Machine Learning", + "1:1 Team Trainings & Customer Success Manager" + ] + } + }, + { + "name": "Enterprise", + "desc": "Fully tailored solution for your sales needs and access to unrivaled support", + "code": "ENTPRS", + "users": 0, + "limit": 0, + "price_per_user": { + "year": 0, + "month": 0 + }, + "starting_at": { + "year": 0, + "month": 0 + }, + "custom": { + "contact_us": "Contact us", + "pricing": "Custom pricing", + "users": "Unlimited users" + }, + "perks": [{ "name": "Sales Widgets", "perk": "Unlimited" }], + "features": { + "name": "All features from Advanced, plus:", + "perks": ["Dedicated Account Management", "Custom-made Widgets"] + } + } + ] + } } } diff --git a/src/model/api/princing-data/data.ts b/src/model/api/princing-data/data.ts new file mode 100644 index 0000000..7bac198 --- /dev/null +++ b/src/model/api/princing-data/data.ts @@ -0,0 +1,148 @@ +import { translate } from "@/locales"; + +export const PricingData = { + plans: [ + { + name: `${translate("pricing.pricingData.plans[0].name")}`, + desc: `${translate("pricing.pricingData.plans[0].desc")}`, + code: `${translate("pricing.pricingData.plans[0].code")}`, + users: 0, + limit: 0, + price_per_user: { + year: 0, + month: 0, + }, + starting_at: { + name: "", + year: 399, + month: 499, + }, + perks: [ + { + name: `${translate("pricing.pricingData.plans[0].perks.name")}`, + perk: 3, + }, + ], + features: { + name: `${translate("pricing.pricingData.plans[0].features.name")}`, + perks: [ + `${translate("pricing.pricingData.plans[0].features.perks[0]")}`, + `${translate("pricing.pricingData.plans[0].features.perks[1]")}`, + `${translate("pricing.pricingData.plans[0].features.perks[2]")}`, + `${translate("pricing.pricingData.plans[0].features.perks[3]")}`, + `${translate("pricing.pricingData.plans[0].features.perks[4]")}`, + `${translate("pricing.pricingData.plans[0].features.perks[5]")}`, + ], + }, + }, + { + name: `${translate("pricing.pricingData.plans[1].name")}`, + desc: `${translate("pricing.pricingData.plans[1].desc")}`, + code: `${translate("pricing.pricingData.plans[1].code")}`, + users: 0, + limit: 0, + price_per_user: { + year: 0, + month: 0, + }, + starting_at: { + name: "", + year: 799, + month: 899, + }, + perks: [ + { + name: `${translate("pricing.pricingData.plans[0].perks.name")}`, + perk: 10, + }, + ], + features: { + name: `${translate("pricing.pricingData.plans[1].features.name")}`, + perks: [ + `${translate("pricing.pricingData.plans[1].features.perks[0]")}`, + `${translate("pricing.pricingData.plans[1].features.perks[1]")}`, + `${translate("pricing.pricingData.plans[1].features.perks[2]")}`, + `${translate("pricing.pricingData.plans[1].features.perks[3]")}`, + `${translate("pricing.pricingData.plans[1].features.perks[4]")}`, + `${translate("pricing.pricingData.plans[1].features.perks[5]")}`, + ], + }, + }, + { + name: `${translate("pricing.pricingData.plans[1].name")}`, + desc: `${translate("pricing.pricingData.plans[1].desc")}`, + code: `${translate("pricing.pricingData.plans[1].code")}`, + users: 0, + limit: 0, + price_per_user: { + year: 0, + month: 0, + }, + starting_at: { + year: 0, + month: 0, + }, + custom: { + contact_us: `${translate("pricing.pricingData.plans[2].custom.contact_us")}`, + pricing: `${translate("pricing.pricingData.plans[2].custom.pricing")}`, + users: `${translate("pricing.pricingData.plans[2].custom.users")}`, + }, + perks: [ + { + name: `${translate("pricing.pricingData.plans[0].perks.name")}`, + perk: "Unlimited", + }, + ], + features: { + name: `${translate("pricing.pricingData.plans[2].features.name")}`, + perks: [ + `${translate("pricing.pricingData.plans[2].features.perks[0]")}`, + `${translate("pricing.pricingData.plans[2].features.perks[1]")}`, + ], + }, + }, + ], +}; + +export const PlansInfo = { + title: "Full Feature Comparison", + plans_names: [ + { name: "Essential", price: "$600" }, + { name: "Advanced", price: "$3600" }, + { name: "Enterprise", price: "$4800" }, + ], + features: [ + { name: "Action Dashboard", perks: ["yes", "yes", "yes"] }, + { name: "Template Gallery", perks: ["yes", "yes", "yes"] }, + { name: "Action Builder", perks: ["yes", "yes", "yes"] }, + { name: "Workflow Automation", perks: ["no", "yes", "yes"] }, + { name: "Updates & Alerts", perks: ["yes", "yes", "yes"] }, + { name: "Action Open Tracking", perks: ["yes", "yes", "yes"] }, + { name: "Action Submit Tracking", perks: ["yes", "yes", "yes"] }, + { name: "Activity Timeline", perks: ["yes", "yes", "yes"] }, + { name: "Sales Actions", perks: ["3", "10", "unlimited"] }, + { name: "eSignatures", perks: ["no", "yes", "yes"] }, + { name: "OCR Machine Learning", perks: ["no", "yes", "yes"] }, + { name: "Autofilled Forms and PDFs", perks: ["no", "yes", "yes"] }, + { name: "Custom Widgets", perks: ["no", "no", "yes"] }, + { name: "Two-way CRM Sync", perks: ["no", "yes", "yes"] }, + { name: "Multiple Branches", perks: ["no", "yes", "yes"] }, + { + name: "Native Mobile Android and iOS apps", + perks: ["yes", "yes", "yes"], + }, + { name: "CRM Chrome Extension", perks: ["yes", "yes", "yes"] }, + { name: "API Access", perks: ["yes", "yes", "yes"] }, + { name: "Webhooks", perks: ["yes", "yes", "yes"] }, + { name: "Live Chat Support", perks: ["yes", "yes", "yes"] }, + { name: "Phone Support", perks: ["no", "yes", "yes"] }, + { + name: "Onboarding Support", + perks: [ + "Onboarding & Email Support", + "1:1 Team Trainings & CSM", + "Dedicated Account Management", + ], + }, + ], +}; diff --git a/src/model/api/questions/data.ts b/src/model/api/questions/data.ts new file mode 100644 index 0000000..026bdd8 --- /dev/null +++ b/src/model/api/questions/data.ts @@ -0,0 +1,30 @@ +import { translate } from "@/locales"; + +export const Questions = { + "questions": [ + { + "question": `${translate("pricing.questions[0].question")}`, + "answer": `${translate("pricing.questions[0].answer")}` + }, + { + "question": `${translate("pricing.questions[1].question")}`, + "answer": `${translate("pricing.questions[1].answer")}` + }, + { + "question": `${translate("pricing.questions[2].question")}`, + "answer": `${translate("pricing.questions[2].answer")}` + }, + { + "question": `${translate("pricing.questions[3].question")}`, + "answer": `${translate("pricing.questions[3].answer")}`}, + { + "question": `${translate("pricing.questions[4].question")}`, + "answer": `${translate("pricing.questions[4].answer")}` + } + ], + "title": `${translate("pricing.title")}`, + "banner": { + "text": `${translate("pricing.banner.text")}`, + "button": `${translate("pricing.banner.button")}` + } +} \ No newline at end of file diff --git a/src/model/interactions/use-pricing/index.ts b/src/model/interactions/use-pricing/index.ts new file mode 100644 index 0000000..05ebc50 --- /dev/null +++ b/src/model/interactions/use-pricing/index.ts @@ -0,0 +1,69 @@ +import { PricingData } from '@/model/api/princing-data/data'; +import { useState, useEffect } from 'react'; + +function usePricing() { + const [current, setCurrent] = useState(0); + const [currentActive, setCurrentActive] = useState<'month' | 'year'>('year'); + const handleIsActive = (step: number) => () => setCurrent(step); + const [price, setPrice] = useState(PricingData.plans[current].starting_at.year); + const [pricePerUser, setPricePerUser] = useState(PricingData.plans[current].price_per_user.year); + const [users, setUsers] = useState(PricingData.plans[current].users); + + useEffect(() => { + if (currentActive === 'year') { + setUsers(PricingData.plans[current].users); + setPricePerUser(PricingData.plans[current].price_per_user.year); + setPrice(PricingData.plans[current].starting_at.year); + } else { + setUsers(PricingData.plans[current].users); + setPrice(PricingData.plans[current].starting_at.month); + setPricePerUser(PricingData.plans[current].price_per_user.month); + } + }, [currentActive, current]); + + function removeUsers() { + if (PricingData.plans[current].users === users) return; + + setUsers((prev) => prev - 1); + setPrice((prev) => prev - pricePerUser); + } + + function addUsers() { + if (PricingData.plans[current].limit === users) return; + setUsers((prev) => prev + 1); + setPrice((prev) => prev + pricePerUser); + } + + const getDelay = (step: number) => { + switch (step) { + case 0: + return 0; + case 1: + return 0.3; + case 2: + return 0.8; + default: + return 0; + } + } + + function handleIsAnnually(status: 'month' | 'year') { + return () => setCurrentActive(status); + } + + return { + current, + setCurrent, + currentActive, + price, + pricePerUser, + users, + removeUsers, + addUsers, + getDelay, + handleIsAnnually, + handleIsActive + }; +} + +export default usePricing; diff --git a/src/model/types/index.ts b/src/model/types/index.ts index c8d4c4b..ef54c3a 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -61,4 +61,40 @@ interface ShowCase { desc: string; option: string; } -export type {WhySalesAssistHeroSection,BenefitsSection,HowItWorksSection,WhySalesAssistCompleteSalesPainlessSection,Options,ShowCase}; \ No newline at end of file + +interface Plan { + name: string ; + desc: string; + code: string; + price_per_user: PricePer; + starting_at: PricePer; + perks: Perk[]; + features: Features; + custom?: Custom; + users: number + limit?: number +} + +interface Features { + name: string; + perks: string[]; +} + +interface Perk { + name: string; + perk: number | string; +} + +interface PricePer { + name?: string, + year: number; + month: number; +} +interface Custom { + contact_us: string; + pricing: string; + users: string; +} + + +export type {WhySalesAssistHeroSection,BenefitsSection,HowItWorksSection,WhySalesAssistCompleteSalesPainlessSection,Options,ShowCase,Plan}; \ No newline at end of file From 1fb8b021397d1df57e754cc5a44ff26e2609d865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20David=20S=C3=A1nchez?= <49158320+Arzoid29@users.noreply.github.com> Date: Mon, 16 Oct 2023 16:31:56 -0400 Subject: [PATCH 2/4] fix: adding the use of translate --- src/app/pricing/page.tsx | 2 +- .../sections/princing/princing-plan/index.tsx | 3 +- src/locales/lang/en.json | 41 ++++++++++++++- src/model/api/princing-data/data.ts | 50 +++++++++---------- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/app/pricing/page.tsx b/src/app/pricing/page.tsx index 6f0a031..930b7c2 100644 --- a/src/app/pricing/page.tsx +++ b/src/app/pricing/page.tsx @@ -11,7 +11,7 @@ export default function page() { const handleIsFull = () => setIsFull(!isFull); return (
- + {isFull && } diff --git a/src/components/organism/sections/princing/princing-plan/index.tsx b/src/components/organism/sections/princing/princing-plan/index.tsx index 02c307c..cc9aefa 100644 --- a/src/components/organism/sections/princing/princing-plan/index.tsx +++ b/src/components/organism/sections/princing/princing-plan/index.tsx @@ -9,6 +9,7 @@ import usePricing from "@/model/interactions/use-pricing"; import PricingMobile from "@/components/atoms/princing-mobile"; import ButtonPlans from "@/components/atoms/plan-buttons"; +import { translate } from "@/locales"; interface PricingHeroProps { isClicked: boolean, @@ -34,7 +35,7 @@ export function PricingPlans({ isClicked, onClick }:PricingHeroProps) { {!isClicked && - See Full Feature Comparison + {translate("pricing.pricingData.pricingButton")} }
diff --git a/src/locales/lang/en.json b/src/locales/lang/en.json index 81619bb..1453d22 100644 --- a/src/locales/lang/en.json +++ b/src/locales/lang/en.json @@ -357,8 +357,9 @@ "text": "Let’s Simplify How You Gather Info from Customers", "button": "Book Demo" }, - + "pricingData": { + "pricingButton": "See Full Feature Comparison", "plans": [ { "name": "Essential", @@ -432,6 +433,44 @@ "perks": ["Dedicated Account Management", "Custom-made Widgets"] } } + ], + "plans_names": [ + { "name": "Essential" }, + { "name": "Advanced" }, + { "name": "Enterprise" } + ], + "features": [ + { "name": "Action Dashboard" }, + { "name": "Template Gallery" }, + { "name": "Action Builder" }, + { "name": "Workflow Automation" }, + { "name": "Updates & Alerts" }, + { "name": "Action Open Tracking" }, + { "name": "Action Submit Tracking" }, + { "name": "Activity Timeline" }, + { "name": "Sales Actions" }, + { "name": "eSignatures" }, + { "name": "OCR Machine Learning" }, + { "name": "Autofilled Forms and PDFs" }, + { "name": "Custom Widgets" }, + { "name": "Two-way CRM Sync" }, + { "name": "Multiple Branches" }, + { + "name": "Native Mobile Android and iOS apps" + }, + { "name": "CRM Chrome Extension"}, + { "name": "API Access" }, + { "name": "Webhooks" }, + { "name": "Live Chat Support" }, + { "name": "Phone Support" }, + { + "name": "Onboarding Support", + "perks": [ + "Onboarding & Email Support", + "1:1 Team Trainings & CSM", + "Dedicated Account Management" + ] + } ] } } diff --git a/src/model/api/princing-data/data.ts b/src/model/api/princing-data/data.ts index 7bac198..a3881ae 100644 --- a/src/model/api/princing-data/data.ts +++ b/src/model/api/princing-data/data.ts @@ -107,37 +107,37 @@ export const PricingData = { export const PlansInfo = { title: "Full Feature Comparison", plans_names: [ - { name: "Essential", price: "$600" }, - { name: "Advanced", price: "$3600" }, - { name: "Enterprise", price: "$4800" }, + { name: `${translate('pricing.pricingData.plans_names[0].name')}`, }, + { name:`${translate('pricing.pricingData.plans_names[1].name')}`, }, + { name: `${translate('pricing.pricingData.plans_names[2].name')}`, }, ], features: [ - { name: "Action Dashboard", perks: ["yes", "yes", "yes"] }, - { name: "Template Gallery", perks: ["yes", "yes", "yes"] }, - { name: "Action Builder", perks: ["yes", "yes", "yes"] }, - { name: "Workflow Automation", perks: ["no", "yes", "yes"] }, - { name: "Updates & Alerts", perks: ["yes", "yes", "yes"] }, - { name: "Action Open Tracking", perks: ["yes", "yes", "yes"] }, - { name: "Action Submit Tracking", perks: ["yes", "yes", "yes"] }, - { name: "Activity Timeline", perks: ["yes", "yes", "yes"] }, - { name: "Sales Actions", perks: ["3", "10", "unlimited"] }, - { name: "eSignatures", perks: ["no", "yes", "yes"] }, - { name: "OCR Machine Learning", perks: ["no", "yes", "yes"] }, - { name: "Autofilled Forms and PDFs", perks: ["no", "yes", "yes"] }, - { name: "Custom Widgets", perks: ["no", "no", "yes"] }, - { name: "Two-way CRM Sync", perks: ["no", "yes", "yes"] }, - { name: "Multiple Branches", perks: ["no", "yes", "yes"] }, + { name:`${translate('pricing.pricingData.features[0].name')}`, perks: ["yes", "yes", "yes"] }, + { name:`${translate('pricing.pricingData.features[1].name')}`, perks: ["yes", "yes", "yes"] }, + { name:`${translate('pricing.pricingData.features[2].name')}`, perks: ["yes", "yes", "yes"] }, + { name:`${translate('pricing.pricingData.features[3].name')}`, perks: ["no", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[4].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[5].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[6].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[7].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[8].name')}`, perks: ["3", "10", "unlimited"] }, + { name: `${translate('pricing.pricingData.features[9].name')}`, perks: ["no", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[10].name')}`, perks: ["no", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[11].name')}`, perks: ["no", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[12].name')}`, perks: ["no", "no", "yes"] }, + { name: `${translate('pricing.pricingData.features[13].name')}`, perks: ["no", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[14].name')}`, perks: ["no", "yes", "yes"] }, { - name: "Native Mobile Android and iOS apps", + name: `${translate('pricing.pricingData.features[15].name')}`, perks: ["yes", "yes", "yes"], }, - { name: "CRM Chrome Extension", perks: ["yes", "yes", "yes"] }, - { name: "API Access", perks: ["yes", "yes", "yes"] }, - { name: "Webhooks", perks: ["yes", "yes", "yes"] }, - { name: "Live Chat Support", perks: ["yes", "yes", "yes"] }, - { name: "Phone Support", perks: ["no", "yes", "yes"] }, + { name:`${translate('pricing.pricingData.features[16].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[17].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[18].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[19].name')}`, perks: ["yes", "yes", "yes"] }, + { name: `${translate('pricing.pricingData.features[20].name')}`, perks: ["no", "yes", "yes"] }, { - name: "Onboarding Support", + name: `${translate('pricing.pricingData.features[21].name')}`, perks: [ "Onboarding & Email Support", "1:1 Team Trainings & CSM", From 952f232c072bb136707e1c16859af559594aafe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20David=20S=C3=A1nchez?= <49158320+Arzoid29@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:07:16 -0400 Subject: [PATCH 3/4] fix:exporting plan type --- src/model/types/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/types/index.ts b/src/model/types/index.ts index 07bbc35..882f86f 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -185,4 +185,4 @@ export const fade = { } } } -export type {WhySalesAssistHeroSection,BenefitsSection,HowItWorksSection,WhySalesAssistCompleteSalesPainlessSection,Options,ShowCase}; +export type {WhySalesAssistHeroSection,BenefitsSection,HowItWorksSection,WhySalesAssistCompleteSalesPainlessSection,Options,ShowCase,Plan}; From 828974adc57380b7d810d059d1b36c2c3399c2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20David=20S=C3=A1nchez?= <49158320+Arzoid29@users.noreply.github.com> Date: Wed, 18 Oct 2023 09:24:06 -0400 Subject: [PATCH 4/4] fix:adding the use of translate --- src/components/atoms/counter/index.tsx | 3 ++- src/components/atoms/plan-buttons/index.tsx | 5 +++-- src/locales/lang/en.json | 5 +++++ src/model/api/princing-data/data.ts | 6 +++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/atoms/counter/index.tsx b/src/components/atoms/counter/index.tsx index aaa9b21..8f3963b 100644 --- a/src/components/atoms/counter/index.tsx +++ b/src/components/atoms/counter/index.tsx @@ -1,4 +1,5 @@ +import { translate } from "@/locales"; import { MdAdd, MdRemove } from "react-icons/md"; interface CounterProps { @@ -13,7 +14,7 @@ interface CounterProps { export function Counter ({ enable = { remove: true, add: false }, add, remove }: CounterProps) { return (
- Unlimited users + {translate('pricing.pricingData.users')} diff --git a/src/components/atoms/plan-buttons/index.tsx b/src/components/atoms/plan-buttons/index.tsx index cbb4b1a..adb2f99 100644 --- a/src/components/atoms/plan-buttons/index.tsx +++ b/src/components/atoms/plan-buttons/index.tsx @@ -1,3 +1,4 @@ +import { translate } from '@/locales'; import classNames from 'classnames'; import React from 'react' @@ -14,9 +15,9 @@ export default function ButtonPlans({handleIsAnnually,currentActive}: Props) {
- +
) } \ No newline at end of file diff --git a/src/locales/lang/en.json b/src/locales/lang/en.json index 1453d22..0e2528d 100644 --- a/src/locales/lang/en.json +++ b/src/locales/lang/en.json @@ -359,6 +359,11 @@ }, "pricingData": { + "planButtons": { + "monthly": "Billed Monthly ", + "annually": "Billed Annually" + }, + "users":"Unlimited users", "pricingButton": "See Full Feature Comparison", "plans": [ { diff --git a/src/model/api/princing-data/data.ts b/src/model/api/princing-data/data.ts index a3881ae..23b1c85 100644 --- a/src/model/api/princing-data/data.ts +++ b/src/model/api/princing-data/data.ts @@ -139,9 +139,9 @@ export const PlansInfo = { { name: `${translate('pricing.pricingData.features[21].name')}`, perks: [ - "Onboarding & Email Support", - "1:1 Team Trainings & CSM", - "Dedicated Account Management", + `${translate('pricing.pricingData.features[21].perks[0]')}`, + `${translate('pricing.pricingData.features[21].perks[1]')}`, + `${translate('pricing.pricingData.features[21].perks[2]')}`, ], }, ],