Add pricing.json and integrate into PricingSection component

The pricing details, previously hardcoded in the PricingSection component, have been extracted to a separate JSON file in both English and French. They are now dynamically loaded into the PricingSection, enhancing maintainability and content management capabilities.
This commit is contained in:
Emil Gulamov 2024-03-29 00:46:57 +04:00
parent 1e4d5a63a7
commit d82473b35c
5 changed files with 117 additions and 58 deletions

View file

@ -3,10 +3,8 @@
import SecondaryCTA from "../../ui/buttons/SecondaryCTA.astro";
import Icon from "../../ui/icons/Icon.astro";
// Set heading and sub-heading for the pricing section
const title: string = "Simple, Transparent Pricing";
const subTitle: string =
"Boost efficiency with ScrewFast's clear, value-driven plans.";
// Define props from Astro
const { pricing } = Astro.props;
// Define TypeScript type for products.
type Product = {
@ -19,37 +17,20 @@ type Product = {
purchaseBtnTitle: string;
purchaseLink: string;
};
// Define two products for display - Starter Kit and Professional Toolbox.
const starterKit: Product = {
name: "Starter Kit",
description: "Best option for DIY projects",
price: "$49",
cents: ".00",
billingFrequency: "USD / monthly",
features: [
"Key hardware tools",
"Access to guides & tutorials",
"Standard support",
],
purchaseBtnTitle: "Get the Starter Kit",
purchaseLink: "#",
};
const professionalToolbox: Product = {
name: "Professional Toolbox",
description: "Best for large scale uses",
price: "$89",
cents: ".00",
billingFrequency: "USD / monthly",
features: [
"Premium tool selection",
"Priority support",
"Exclusive content & deals",
"Bulk order discounts",
],
purchaseBtnTitle: "Get the Professional Toolbox",
purchaseLink: "#",
};
interface PricingSectionProps {
title: string;
subTitle: string;
badge: string;
thirdOption: string;
btnText: string;
pricing: {
title: string;
subTitle: string;
starterKit: Product;
professionalToolbox: Product;
};
}
---
<section
@ -60,10 +41,10 @@ const professionalToolbox: Product = {
<h2
class="text-balance text-2xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 md:text-4xl md:leading-tight"
>
{title}
{pricing.title}
</h2>
<p class="mt-1 text-pretty text-neutral-600 dark:text-neutral-400">
{subTitle}
{pricing.subTitle}
</p>
</div>
<!-- Contains two main product blocks -->
@ -74,26 +55,26 @@ const professionalToolbox: Product = {
>
<div class="mb-4">
<h3 class="text-2xl font-bold text-neutral-100 sm:text-3xl">
{starterKit.name}
{pricing.starterKit.name}
</h3>
<p class="text-indigo-300">{starterKit.description}</p>
<p class="text-indigo-300">{pricing.starterKit.description}</p>
</div>
<div class="mb-4">
<span class="text-4xl font-bold text-neutral-200"
>{starterKit.price}</span
>{pricing.starterKit.price}</span
>
<span class="text-lg font-bold text-neutral-300"
>{starterKit.cents}</span
>{pricing.starterKit.cents}</span
>
<span class="ms-3 text-sm text-indigo-200"
>{starterKit.billingFrequency}</span
>{pricing.starterKit.billingFrequency}</span
>
</div>
<!-- Features list - automatically created by mapping over `features` array -->
<ul class="mb-6 space-y-2 text-neutral-300">
{
starterKit.features.map((feature) => (
pricing.starterKit.features.map((feature: string) => (
<li class="flex items-center gap-1.5">
<Icon name="checkCircle" />
@ -104,9 +85,9 @@ const professionalToolbox: Product = {
</ul>
<!-- CTA for purchasing the product -->
<a
href={starterKit.purchaseLink}
href={pricing.starterKit.purchaseLink}
class="block rounded-lg bg-gray-500 px-8 py-3 text-center text-sm font-bold text-gray-100 outline-none ring-indigo-300 transition duration-100 hover:bg-gray-600 focus-visible:ring active:text-gray-300 md:text-base"
>{starterKit.purchaseBtnTitle}</a
>{pricing.starterKit.purchaseBtnTitle}</a
>
</div>
<!-- Professional Toolbox product details -->
@ -118,32 +99,32 @@ const professionalToolbox: Product = {
>
<div>
<h3 class="text-2xl font-bold text-neutral-100 sm:text-3xl">
{professionalToolbox.name}
{pricing.professionalToolbox.name}
</h3>
<p class="text-orange-200">{professionalToolbox.description}</p>
<p class="text-orange-200">{pricing.professionalToolbox.description}</p>
</div>
<span
class="order-first inline-block rounded-full bg-orange-200 bg-opacity-50 px-3 py-1 text-xs font-bold uppercase tracking-wider text-orange-600 lg:order-none"
>Best value</span
class="order-first inline-block rounded-full bg-orange-200 bg-opacity-50 px-3 py-1 text-xs font-bold uppercase tracking-wider text-center text-orange-600 lg:order-none"
>{pricing.badge}</span
>
</div>
<div class="mb-4">
<span class="text-6xl font-bold text-neutral-200"
>{professionalToolbox.price}</span
>{pricing.professionalToolbox.price}</span
>
<span class="text-lg font-bold text-orange-100"
>{professionalToolbox.cents}</span
>{pricing.professionalToolbox.cents}</span
>
<span class="ms-3 text-orange-200"
>{professionalToolbox.billingFrequency}</span
>{pricing.professionalToolbox.billingFrequency}</span
>
</div>
<!-- Features list - automatically created by mapping over `features` array -->
<ul class="mb-6 space-y-2 text-orange-100">
{
professionalToolbox.features.map((feature) => (
pricing.professionalToolbox.features.map((feature: string) => (
<li class="flex items-center gap-1.5">
<Icon name="checkCircle" />
@ -154,18 +135,18 @@ const professionalToolbox: Product = {
</ul>
<!-- CTA for purchasing the product -->
<a
href={professionalToolbox.purchaseLink}
href={pricing.professionalToolbox.purchaseLink}
class="block rounded-lg bg-orange-200 bg-opacity-50 px-8 py-3 text-center text-sm font-bold text-neutral-100 outline-none ring-orange-300 transition duration-100 hover:bg-orange-300 hover:bg-opacity-50 focus-visible:ring active:bg-orange-400 md:text-base"
>{professionalToolbox.purchaseBtnTitle}</a
>{pricing.professionalToolbox.purchaseBtnTitle}</a
>
</div>
</div>
<!-- Call to action for Enterprise Solutions -->
<div class="mt-8 flex items-center justify-center gap-x-3 md:mt-12">
<p class="text-sm text-neutral-600 dark:text-neutral-400">
Enterprise Solutions?
{pricing.thirdOption}
</p>
<SecondaryCTA title="Get a Custom Quote" url="#" />
<SecondaryCTA title={pricing.btnText} url="#" />
</div>
</section>

View file

@ -0,0 +1,38 @@
{
"title": "Tarification Simple et Transparente",
"subTitle": "Augmentez l'efficacité avec les plans clairs et axés sur la valeur de ScrewFast.",
"badge": "Meilleure valeur",
"thirdOption": "Solutions Entreprise?",
"btnText": "Obtenez un Devis Personnalisé",
"starterKit": {
"name": "Kit de Démarrage",
"description": "Meilleure option pour les projets de bricolage",
"price": "$49",
"cents": ".00",
"billingFrequency": "USD / mensuel",
"features": [
"Outils matériels essentiels",
"Accès aux guides et tutoriels",
"Support standard"
],
"purchaseBtnTitle": "Obtenez le Kit de Démarrage",
"purchaseLink": "#"
},
"professionalToolbox": {
"name": "Boîte à Outils Professionnelle",
"description": "Idéale pour les utilisations à grande échelle",
"price": "$89",
"cents": ".00",
"billingFrequency": "USD / mensuel",
"features": [
"Sélection d'outils premium",
"Support prioritaire",
"Contenu et offres exclusifs",
"Remises sur les commandes en gros"
],
"purchaseBtnTitle": "Obtenez la Boîte à Outils Professionnelle",
"purchaseLink": "#"
}
}

View file

@ -0,0 +1,38 @@
{
"title": "Simple, Transparent Pricing",
"subTitle": "Boost efficiency with ScrewFast's clear, value-driven plans.",
"badge": "Best value",
"thirdOption": "Enterprise Solutions?",
"btnText": "Get a Custom Quote",
"starterKit": {
"name": "Starter Kit",
"description": "Best option for DIY projects",
"price": "$49",
"cents": ".00",
"billingFrequency": "USD / monthly",
"features": [
"Key hardware tools",
"Access to guides & tutorials",
"Standard support"
],
"purchaseBtnTitle": "Get the Starter Kit",
"purchaseLink": "#"
},
"professionalToolbox": {
"name": "Professional Toolbox",
"description": "Best for large scale uses",
"price": "$89",
"cents": ".00",
"billingFrequency": "USD / monthly",
"features": [
"Premium tool selection",
"Priority support",
"Exclusive content & deals",
"Bulk order discounts"
],
"purchaseBtnTitle": "Get the Professional Toolbox",
"purchaseLink": "#"
}
}

View file

@ -13,6 +13,7 @@ import AnnouncementBanner from "@/components/ui/banners/AnnouncementBanner.astro
import heroImage from "@/images/hero-image.avif";
import faqs from "@/data_files/fr/faqs.json";
import features from "@/data_files/fr/features.json";
import pricing from "@/data_files/fr/pricing.json";
import featureImage from "@/images/features-image.avif";
import construction from "@/images/construction-image.avif";
import tools from "@/images/automated-tools.avif";
@ -132,7 +133,7 @@ const avatarSrcs: Array<string> = [
]}
/>
<PricingSection />
<PricingSection pricing={pricing} />
<FAQ title="Questions<br />fréquemment posées" faqs={faqs} />

View file

@ -13,6 +13,7 @@ import AnnouncementBanner from "@/components/ui/banners/AnnouncementBanner.astro
import heroImage from "@/images/hero-image.avif";
import faqs from "@/data_files/faqs.json";
import features from "@/data_files/features.json";
import pricing from "@/data_files/pricing.json";
import featureImage from "@/images/features-image.avif";
import construction from "@/images/construction-image.avif";
import tools from "@/images/automated-tools.avif";
@ -132,7 +133,7 @@ const avatarSrcs: Array<string> = [
]}
/>
<PricingSection />
<PricingSection pricing={pricing} />
<FAQ title="Frequently<br />asked questions" faqs={faqs} />