Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const highlights: CustomerHighlight[] = [

export default function CustomerHighlights() {
return (
<div className="min-h-[200px] flex items-center justify-center">
<div className="flex items-center justify-center">
<div className="w-full rounded-xl flex flex-col md:flex-row border border-border">
{highlights.map((highlight, index) => (
<div
Expand All @@ -66,7 +66,7 @@ export default function CustomerHighlights() {
}
`}
>
<div className="flex flex-col-reverse gap-8 px-6 py-9">
<div className="flex flex-col-reverse gap-3 px-5 py-4">
<div className="self-stretch">
<span className="text-xl text-slate-700 font-bold">
{highlight.metric}
Expand Down
215 changes: 60 additions & 155 deletions bifrost/app/components/templates/pricing/PricingComparisonTable.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { CheckIcon, ChevronDownIcon } from "@heroicons/react/20/solid";
import { CheckIcon } from "@heroicons/react/20/solid";
import Link from "next/link";
import {
StickyTable,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { useState, Fragment } from "react";
import {
GB_PRICING_TIERS,
REQUEST_PRICING_TIERS,
} from "@helicone-package/pricing";
import { Fragment } from "react";

interface PricingTier {
name: string;
Expand All @@ -29,28 +24,13 @@ interface Feature {
pro: string | boolean;
team: string | boolean;
enterprise: string | boolean;
tooltip?: "usage";
}

interface FeatureGroup {
title: string;
features: Feature[];
}

// Derive display data from shared pricing tiers
const USAGE_PRICING_GB = GB_PRICING_TIERS.map((tier) => ({
label: tier.label,
rate: `$${tier.ratePerGB.toFixed(2)}/GB`,
}));

const USAGE_PRICING_REQUESTS = REQUEST_PRICING_TIERS.map((tier) => ({
label: tier.label,
rate:
tier.ratePerLog === 0
? "Free"
: `$${tier.ratePerLog.toFixed(8).replace(/0+$/, "")}`,
}));

const tiers: PricingTier[] = [
{
name: "Hobby",
Expand Down Expand Up @@ -101,38 +81,30 @@ const featureGroups: FeatureGroup[] = [
{
name: "Requests",
hobby: "10,000/mo",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
},
{
name: "Usage-based pricing",
hobby: "10K requests",
pro: "Tiered pricing",
team: "Tiered pricing",
enterprise: "Volume discount",
tooltip: "usage",
pro: "10K free",
team: "10K free",
enterprise: "10K free",
},
{
name: "Sessions",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "User analytics",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "Custom properties",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "HQL (Query Language)",
Expand Down Expand Up @@ -162,31 +134,31 @@ const featureGroups: FeatureGroup[] = [
features: [
{
name: "Playground",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited (credits)",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "Prompts",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "Scores",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "Datasets",
hobby: "Unlimited",
pro: "Unlimited",
team: "Unlimited",
enterprise: "Unlimited",
hobby: true,
pro: true,
team: true,
enterprise: true,
},
{
name: "Webhooks",
Expand Down Expand Up @@ -233,6 +205,13 @@ const featureGroups: FeatureGroup[] = [
team: "3 months",
enterprise: "Forever",
},
{
name: "Storage",
hobby: "1 GB",
pro: "1 GB free",
team: "1 GB free",
enterprise: "1 GB free",
},
{
name: "Configurable retention",
hobby: false,
Expand Down Expand Up @@ -346,8 +325,6 @@ const featureGroups: FeatureGroup[] = [
];

export default function PricingComparisonTable() {
const [showUsageTiers, setShowUsageTiers] = useState(false);

return (
<div className="flex flex-col gap-6">
<h2 className="text-black text-4xl font-bold">Compare plans</h2>
Expand Down Expand Up @@ -419,95 +396,9 @@ export default function PricingComparisonTable() {
: ""
}`}
>
<div className="flex flex-col">
<div className="flex items-center gap-2">
<span className="text-slate-500 text-sm font-medium">
{feature.name}
</span>
{feature.tooltip === "usage" && (
<button
onClick={() => setShowUsageTiers(!showUsageTiers)}
className="p-1 hover:bg-slate-100 rounded-full transition-colors"
>
<ChevronDownIcon
className={`w-4 h-4 text-slate-400 transition-transform ${
showUsageTiers ? "rotate-180" : ""
}`}
/>
</button>
)}
</div>
{feature.tooltip === "usage" && showUsageTiers && (
<div className="pl-8 pt-4 space-y-4">
{/* Storage Pricing */}
<div>
<div className="text-slate-600 text-xs font-semibold mb-2">
Storage Pricing
</div>
<Table className="w-full">
<TableHeader>
<TableRow className="hover:bg-transparent">
<TableHead className="text-slate-500 font-medium px-0 py-1">
Usage
</TableHead>
<TableHead className="text-slate-500 font-medium px-0 py-1 text-right">
Rate
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{USAGE_PRICING_GB.map((tier, i) => (
<TableRow
key={i}
className="hover:bg-transparent"
>
<TableCell className="px-0 py-1 text-sm text-slate-500">
{tier.label}
</TableCell>
<TableCell className="px-0 py-1 text-right text-sm text-slate-500">
{tier.rate}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
{/* Request Pricing */}
<div>
<div className="text-slate-600 text-xs font-semibold mb-2">
Request Pricing
</div>
<Table className="w-full">
<TableHeader>
<TableRow className="hover:bg-transparent">
<TableHead className="text-slate-500 font-medium px-0 py-1">
Requests
</TableHead>
<TableHead className="text-slate-500 font-medium px-0 py-1 text-right">
Rate
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{USAGE_PRICING_REQUESTS.map((tier, i) => (
<TableRow
key={i}
className="hover:bg-transparent"
>
<TableCell className="px-0 py-1 text-sm text-slate-500">
{tier.label}
</TableCell>
<TableCell className="px-0 py-1 text-right text-sm text-slate-500">
{tier.rate}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
)}
</div>
<span className="text-slate-500 text-sm font-medium">
{feature.name}
</span>
</TableCell>
{[
feature.hobby,
Expand All @@ -526,9 +417,23 @@ export default function PricingComparisonTable() {
}`}
>
{typeof value === "string" ? (
<div className="text-slate-500 text-sm font-medium">
{value}
</div>
value.includes("free") ? (
<div className="flex flex-col">
<span className="text-slate-500 text-sm font-medium">
{value}
</span>
<Link
href="#calculator"
className="text-brand text-xs hover:underline"
>
+ usage-based ↑
</Link>
</div>
) : (
<div className="text-slate-500 text-sm font-medium">
{value}
</div>
)
) : value === true ? (
<CheckIcon className="w-5 h-5 text-slate-500" />
) : null}
Expand Down
4 changes: 2 additions & 2 deletions bifrost/app/components/templates/pricing/ScaleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ const ScaleCard: React.FC = () => {
{[
"Everything in Hobby",
"Unlimited seats",
"Unlimited requests",
"Tiered usage-based billing",
"Alerts & reports",
"HQL (Query Language)",
].map((feature, index) => (
<div key={index} className="py-1.5 flex items-center gap-2">
<div className="w-4 h-4 relative overflow-hidden">
Expand Down
5 changes: 4 additions & 1 deletion bifrost/app/components/templates/pricing/TeamCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const TeamCard: React.FC = () => {
"5 organizations",
"SOC-2 & HIPAA compliance",
"Dedicated Slack channel",
"Support engineer & SLAs",
].map((feature, index) => (
<div key={index} className="py-1.5 flex items-center gap-2">
<div className="w-4 h-4 relative overflow-hidden">
Expand All @@ -51,6 +50,10 @@ const TeamCard: React.FC = () => {
</Col>
</Col>

<div className="text-xs text-muted-foreground mt-2">
* Usage-based pricing applies
</div>

<Link href="https://us.helicone.ai/settings/billing">
<Button variant="secondary" className="w-full text-base py-5">
7-day free trial
Expand Down
Loading
Loading