Skip to content

feat: add pricing page#1018

Open
necatiozmen wants to merge 7 commits intomainfrom
add-pricing-page
Open

feat: add pricing page#1018
necatiozmen wants to merge 7 commits intomainfrom
add-pricing-page

Conversation

@necatiozmen
Copy link
Member

@necatiozmen necatiozmen commented Feb 4, 2026

PR Checklist

Please check if your PR fulfills the following requirements:

Bugs / Features

What is the current behavior?

What is the new behavior?

fixes (issue)

Notes for reviewers


Summary by cubic

Adds a new Pricing page with plan tiers, a usage calculator, a plan comparison table, and FAQ, and links it in the navbar. Updates pricing logic (Core 50k, Pro 250k included traces; Pro now $250) and refreshes related UI.

  • New Features

    • New /pricing page: Developer, Core, Pro, Enterprise plans with clear limits and “pay-as-you-scale.”
    • Pricing calculator modal with updated thresholds (Core 50k, Pro 250k) and $10 per 5,000 extra traces.
    • Plan comparison table with categorized features and enterprise highlights.
    • Navbar and Docusaurus config updated to include “Pricing.”
  • Refactors

    • ComparisonTable now uses Heroicons and simplified inline styles, plus a clearer legend.
    • PricingCalculatorModal restyled, keyboard-accessible buttons, dynamic slider max (100k/500k), and updated base costs (Core $50, Pro $250).
    • Range slider thumb and colors adjusted for consistency with new theme.

Written for commit 8556fe9. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Added a Pricing page and navbar link.
    • Pay-as-you-scale pricing calculator modal with updated plan inclusions (Core: 50K traces, Pro: 250K traces).
    • Data-driven pricing cards, enterprise variant, and GitHub CTA.
  • Style

    • Redesigned pricing layout with a darker theme and platform comparison flow.
    • Updated icons, comparison table visuals, and calculator slider/thumb styling.
    • Improved keyboard accessibility for interactive controls and modal elements.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 4, 2026

Deploying voltagent with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8556fe9
Status: ✅  Deploy successful!
Preview URL: https://3ba7babb.voltagent.pages.dev
Branch Preview URL: https://add-pricing-page.voltagent.pages.dev

View logs

@joggrbot

This comment has been minimized.

@changeset-bot
Copy link

changeset-bot bot commented Feb 4, 2026

⚠️ No Changeset found

Latest commit: 8556fe9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Added a top-level "Pricing" nav link and mobile menu entry; fully rewrote the pricing page into a data-driven, dark-themed layout with tiered cards, comparison data, and FAQ; replaced comparison icons and migrated table markup to inline styles; updated the Pricing Calculator modal (ranges, costs, accessibility, styling).

Changes

Cohort / File(s) Summary
Docusaurus / Navbar
website/docusaurus.config.ts, website/src/components/navbar/index.tsx
Added a left-positioned "Pricing" navbar item and mirrored the link in the mobile/expanded menu; removed an old redirect from /pricing/.
Pricing page (full rewrite)
website/src/pages/pricing.tsx
Replaced previous pricing UI with a data-driven, platform-first layout: pricingTiers, comparisonFeatures, enterpriseFeatures, dynamic cards, GitHub CTA, FAQ dataset, dark-theme styling, and retained modal integration.
Pricing calculator (logic & UI)
website/src/components/console/PricingCalculatorModal.tsx, website/src/components/console/PricingCalculatorModal.module.css
Updated planConfig (base costs, included traces), revised cost calculation and overage logic, slider max per plan, keyboard-accessible plan selector (div role="button"), UI/theme updates, and adjusted slider thumb styles.
Comparison table & icons
website/src/components/ComparisonTable.tsx
Replaced custom SVGs with Heroicons + a custom icon; switched from Tailwind classes to inline styles for table, cells, legend, and link interactions; refactored StatusIcon and cell rendering.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant PricingPage as Pricing Page
    participant Navbar as Navbar
    participant Modal as Pricing Calculator Modal
    participant PricingLogic as Pricing Logic

    User->>Navbar: click "Pricing" (or navigate)
    Navbar->>PricingPage: route to /pricing
    PricingPage->>User: render cards, comparison table, FAQ
    User->>PricingPage: click "Open Calculator"
    PricingPage->>Modal: mount modal
    User->>Modal: select plan / adjust slider
    Modal->>PricingLogic: compute breakdown (planConfig, traces)
    PricingLogic->>Modal: return costs (base, included, overage, total)
    Modal->>User: display updated cost breakdown
    User->>Modal: close modal
    Modal->>PricingPage: unmount modal
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰
I hopped onto the pricing glade tonight,
Cards shimmered under dark theme light,
Sliders hummed and numbers leapt,
Icons winked where features slept,
A tiny hop — the plans feel right!

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely incomplete: current/new behavior sections are empty, issue linking is missing, tests/docs/changesets are unchecked, and only an auto-generated summary provides substance. Fill in 'What is the current behavior?' and 'What is the new behavior?' sections; link related issues; verify and check off tests, docs, and changeset requirements; address the unchecked PR checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add pricing page' clearly and specifically describes the main change: a new pricing page feature added to the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-pricing-page

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 6 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="website/src/components/console/PricingCalculatorModal.tsx">

<violation number="1" location="website/src/components/console/PricingCalculatorModal.tsx:156">
P2: When switching plans, `traceCount` can remain above the new max (e.g., 500k on Pro → Core max 100k), so the slider position no longer matches the displayed usage/cost. Clamp `traceCount` on plan changes to keep the UI and cost calculation consistent.</violation>
</file>

<file name="website/src/pages/pricing.tsx">

<violation number="1" location="website/src/pages/pricing.tsx:466">
P2: `window.open` to external URLs should include `noopener,noreferrer` to prevent reverse‑tabnabbing.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
website/src/components/console/PricingCalculatorModal.tsx (1)

11-19: ⚠️ Potential issue | 🟡 Minor

Clamp trace count when switching plans to avoid stale overage totals.

If a user switches from Pro to Core with a high trace count, the slider visually clamps but cost math still uses the stale value. Consider clamping traceCount when selectedPlan changes and reuse a shared maxTraces value.

🛠️ Suggested fix
-import { useState } from "react";
+import { useEffect, useState } from "react";
 
 const PricingCalculatorModal = ({ isOpen, onClose }: PricingCalculatorModalProps) => {
   const [traceCount, setTraceCount] = useState<number>(10000);
   const [selectedPlan, setSelectedPlan] = useState<"core" | "pro">("core");
+  const maxTraces = selectedPlan === "core" ? 100000 : 500000;
+
+  useEffect(() => {
+    setTraceCount((current) => Math.min(current, maxTraces));
+  }, [maxTraces]);
@@
-              max={selectedPlan === "core" ? 100000 : 500000}
+              max={maxTraces}
@@
-                background: `linear-gradient(to right, `#ffffff` 0%, `#ffffff` ${
-                  (traceCount / (selectedPlan === "core" ? 100000 : 500000)) * 100
-                }%, `#2b2d2f` ${(traceCount / (selectedPlan === "core" ? 100000 : 500000)) * 100}%, `#2b2d2f` 100%)`,
+                background: `linear-gradient(to right, `#ffffff` 0%, `#ffffff` ${
+                  (traceCount / maxTraces) * 100
+                }%, `#2b2d2f` ${(traceCount / maxTraces) * 100}%, `#2b2d2f` 100%)`,

Also applies to: 156-166

website/src/pages/pricing.tsx (1)

760-767: ⚠️ Potential issue | 🟠 Major

FAQ headers are not keyboard-focusable.

The clickable FAQ header is a plain div without role/tabIndex, so keyboard users can’t toggle it. Add role="button", tabIndex={0}, aria-expanded, and prevent default for Space.

♿ Suggested fix
-                  <div
+                  <div
+                    role="button"
+                    tabIndex={0}
+                    aria-expanded={openFAQ === index}
                     onClick={() => toggleFAQ(index)}
                     onKeyDown={(e) => {
                       if (e.key === "Enter" || e.key === " ") {
+                        e.preventDefault();
                         toggleFAQ(index);
                       }
                     }}
                     className="w-full text-left p-6 landing-xs:p-3 landing-sm:p-5 flex items-center justify-between focus:outline-none focus:bg-zinc-800/30 hover:bg-zinc-800/30 transition-colors cursor-pointer"
                   >
🤖 Fix all issues with AI agents
In `@website/docusaurus.config.ts`:
- Around line 668-672: The site has a new nav entry with to: "/pricing" and
label: "Pricing" but an existing redirect rule still maps "/pricing/" to "/"
which, with trailingSlash: true, will redirect users away from the new page;
locate the redirect that maps "/pricing/" -> "/" and either remove it or update
its target to the new pricing path (or normalize to "/pricing/" as appropriate)
so the nav item (to: "/pricing", label: "Pricing") is not overridden by the
redirect.

In `@website/src/components/console/PricingCalculatorModal.tsx`:
- Around line 108-138: The keyboard handlers for elements using role="button"
(e.g., the plan card handlers that call setSelectedPlan in the onKeyDown
callbacks) must call e.preventDefault() when the Space key is pressed to avoid
the page scrolling; update the onKeyDown callbacks for those plan divs (and any
other custom button divs like the close and action buttons) to check for e.key
=== " " or e.code === "Space" and call e.preventDefault() before invoking
setSelectedPlan or the respective action, ensuring keyboard activation still
occurs while preventing default scrolling behavior.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
website/src/pages/pricing.tsx (1)

768-785: ⚠️ Potential issue | 🟠 Major

FAQ toggle is not keyboard-accessible: missing role and tabIndex.

The FAQ toggle div has onClick and onKeyDown handlers but lacks role="button" and tabIndex={0}. Without these, keyboard users cannot focus the element, making the FAQ section inaccessible via keyboard navigation.

♿ Proposed fix
                   <div
                     onClick={() => toggleFAQ(index)}
                     onKeyDown={(e) => {
                       if (e.key === "Enter" || e.key === " ") {
+                        e.preventDefault();
                         toggleFAQ(index);
                       }
                     }}
+                    role="button"
+                    tabIndex={0}
                     className="w-full text-left p-6 landing-xs:p-3 landing-sm:p-5 flex items-center justify-between focus:outline-none focus:bg-zinc-800/30 hover:bg-zinc-800/30 transition-colors cursor-pointer"
                   >
🤖 Fix all issues with AI agents
In `@website/src/pages/pricing.tsx`:
- Around line 462-486: The onClick handler in the button checks tier.name ===
"Enterprise" which is unreachable because pricingTiers does not include an
Enterprise entry (pricingTiers) and the Enterprise tier is rendered separately,
so the branch and its form URL are dead code; remove the conditional branch
inside the onClick in the button (the check of tier.name and the window.open to
"https://forms.gle/BrnyFF4unP9pZxAh7") and instead either use a URL property on
the tier (e.g., add/use tier.href) or always open the console URL
("https://console.voltagent.dev") from this button (update the onClick in the
component that renders the button), and if you must link to an Enterprise form
ensure it uses the correct form id ("nmXKC7RbYhouBs2A6") where appropriate.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
website/src/pages/pricing.tsx (1)

760-776: ⚠️ Potential issue | 🟡 Minor

Add accessibility attributes to FAQ toggle.

The FAQ toggle <div> has onKeyDown handling for Enter/Space but lacks role="button" and tabIndex={0}. Without tabIndex, the element cannot receive keyboard focus, making the onKeyDown handler ineffective for keyboard-only users.

♿ Proposed fix for accessibility
                   <div
                     onClick={() => toggleFAQ(index)}
                     onKeyDown={(e) => {
                       if (e.key === "Enter" || e.key === " ") {
                         toggleFAQ(index);
                       }
                     }}
+                    role="button"
+                    tabIndex={0}
                     className="w-full text-left p-6 landing-xs:p-3 landing-sm:p-5 flex items-center justify-between focus:outline-none focus:bg-zinc-800/30 hover:bg-zinc-800/30 transition-colors cursor-pointer"
                   >
🧹 Nitpick comments (1)
website/src/pages/pricing.tsx (1)

55-134: Consider adding explicit TypeScript types for pricing data.

The pricingTiers array uses a complex structure where features can be strings or objects with different shapes. Adding explicit interfaces would improve type safety and developer experience.

💡 Suggested type definitions
interface FeatureWithPayAsYouScale {
  text: string;
  hasPayAsYouScale: true;
}

interface FeatureWithSubtext {
  text: string;
  subtext: string;
}

type PricingFeature = string | FeatureWithPayAsYouScale | FeatureWithSubtext;

interface PricingTier {
  name: string;
  price: string;
  period: string;
  description: string;
  trial: string | null;
  includesFrom?: string;
  features: PricingFeature[];
  buttonText: string;
  buttonVariant: "primary" | "outline";
  popular: boolean;
  hasCalculate: boolean;
  note: string | null;
}

const pricingTiers: PricingTier[] = [
  // ...existing data
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant