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
11 changes: 9 additions & 2 deletions apps/www/components/Solutions/CtaSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button, cn } from 'ui'

import SectionContainer from '@/components/Layouts/SectionContainer'

interface Props {
export interface CtaSectionProps {
id: string
title: string | React.ReactNode
subtitle?: string
Expand All @@ -25,7 +25,14 @@ interface Props {
className?: string
}

const CtaSection = ({ id, title, subtitle, primaryCta, secondaryCta, className }: Props) => {
const CtaSection = ({
id,
title,
subtitle,
primaryCta,
secondaryCta,
className,
}: CtaSectionProps) => {
return (
<SectionContainer
id={id}
Expand Down
58 changes: 35 additions & 23 deletions apps/www/components/Solutions/FeatureGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import SectionContainer from '~/components/Layouts/SectionContainer'
import type { IconType } from '~/data/solutions/solutions.utils'
import React from 'react'
import { cn } from 'ui'
import SectionContainer from '~/components/Layouts/SectionContainer'

interface Feature {
id: string
title: string
description: string | React.ReactNode
icon: string
icon: string | IconType
iconNoStroke?: boolean
className?: string
}

export interface FeatureGridProps {
id: string
features: Feature[]
heading?: React.ReactNode
subheading?: React.ReactNode
className?: string
}

const FeatureGrid = ({ id, features, className }: FeatureGridProps) => {
const FeatureGrid = ({ id, features, heading, subheading, className }: FeatureGridProps) => {
return (
<SectionContainer id={id} className={cn('flex flex-col gap-12 py-16 md:py-24', className)}>
{(heading || subheading) && (
<div className="flex flex-col gap-2 max-w-xl">
{heading && <h2 className="h2 text-foreground-lighter m-0!">{heading}</h2>}
{subheading && <p className="text-foreground-lighter">{subheading}</p>}
</div>
)}
<div
className="
grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3
Expand All @@ -41,26 +50,29 @@ const FeatureGrid = ({ id, features, className }: FeatureGridProps) => {
)}
>
<div className="flex items-center gap-2">
{feature.icon && (
<svg
width="18"
height="18"
viewBox="0 0 25 25"
fill={feature.iconNoStroke ? 'currentColor' : 'none'}
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d={feature.icon}
stroke={feature.iconNoStroke ? 'none' : 'currentColor'}
strokeMiterlimit="10"
strokeLinejoin="round"
strokeLinecap="round"
strokeWidth="1.5"
/>
</svg>
)}
{feature.icon &&
(typeof feature.icon === 'string' ? (
<svg
width="18"
height="18"
viewBox="0 0 25 25"
fill={feature.iconNoStroke ? 'currentColor' : 'none'}
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d={feature.icon}
stroke={feature.iconNoStroke ? 'none' : 'currentColor'}
strokeMiterlimit="10"
strokeLinejoin="round"
strokeLinecap="round"
strokeWidth="1.5"
/>
</svg>
) : (
<feature.icon className="w-[18px] h-[18px]" strokeWidth={1.5} />
))}
<h3 className="">{feature.title}</h3>
</div>
<p className="text-base">{feature.description}</p>
Expand Down
121 changes: 121 additions & 0 deletions apps/www/components/Solutions/PricingComparisonSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { Check, Minus } from 'lucide-react'
import React, { type FC, type ReactNode } from 'react'
import { cn } from 'ui'
import { TextLink } from 'ui-patterns/TextLink'

import SectionContainer from '@/components/Layouts/SectionContainer'

export interface PricingComparisonPlan {
name: string
/** Highlights the column visually (eg. the recommended plan). */
highlight?: boolean
}

export interface PricingComparisonRow {
feature: ReactNode
/** One value per plan, in the same order as `plans`. Booleans render as a check or dash. */
values: (ReactNode | boolean)[]
}

export interface PricingComparisonSectionProps {
id?: string
heading: ReactNode
subheading?: ReactNode
plans: PricingComparisonPlan[]
rows: PricingComparisonRow[]
cta?: {
label: string
url: string
}
className?: string
}

const PlanValue = ({ value }: { value: ReactNode | boolean }) => {
if (value === true) {
return <Check className="w-4 h-4 text-brand" strokeWidth={2} aria-label="Included" />
}
if (value === false) {
return (
<Minus className="w-4 h-4 text-foreground-muted" strokeWidth={2} aria-label="Not included" />
)
}
return <span className="text-sm text-foreground">{value}</span>
}

const PricingComparisonSection: FC<PricingComparisonSectionProps> = ({
id,
heading,
subheading,
plans,
rows,
cta,
className,
}) => {
return (
<SectionContainer id={id} className={cn('flex flex-col gap-8 py-16 md:py-24', className)}>
<div className="flex flex-col gap-2 max-w-xl">
<h2 className="h2 text-foreground-lighter m-0!">{heading}</h2>
{subheading && <p className="text-foreground-lighter">{subheading}</p>}
</div>

<div className="w-full overflow-x-auto border border-default rounded-lg bg-surface-75">
<table className="w-full min-w-[480px] border-collapse text-left">
<thead>
<tr className="border-b border-default">
<th
scope="col"
className="py-4 px-4 md:px-6 text-sm font-normal text-foreground-light"
>
What you get
</th>
{plans.map((plan) => (
<th
key={plan.name}
scope="col"
className={cn(
'py-4 px-4 md:px-6 text-sm font-medium text-center',
plan.highlight ? 'text-foreground bg-surface-100' : 'text-foreground'
)}
>
{plan.name}
</th>
))}
</tr>
</thead>
<tbody>
{rows.map((row, rowIndex) => (
<tr
key={rowIndex}
className="border-b border-default last:border-b-0 hover:bg-surface-100/50 transition-colors"
>
<th
scope="row"
className="py-3 px-4 md:px-6 text-sm font-normal text-foreground-light"
>
{row.feature}
</th>
{row.values.map((value, valueIndex) => (
<td
key={valueIndex}
className={cn(
'py-3 px-4 md:px-6 text-center',
plans[valueIndex]?.highlight && 'bg-surface-100'
)}
>
<span className="flex items-center justify-center">
<PlanValue value={value} />
</span>
</td>
))}
</tr>
))}
</tbody>
</table>
</div>

{cta && <TextLink hasChevron label={cta.label} url={cta.url} className="mt-2" />}
</SectionContainer>
)
}

export default PricingComparisonSection
4 changes: 4 additions & 0 deletions apps/www/data/Footer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ const footerData = [
{
title: 'Solutions',
links: [
{
text: 'Hosted Postgres',
url: '/solutions/hosted-postgres',
},
...skillBasedSolutions.solutions.map((solution) => ({
text: solution.text,
url: solution.url,
Expand Down
9 changes: 9 additions & 0 deletions apps/www/data/Solutions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
BotIcon,
Building2Icon,
Code2Icon,
Database,
HammerIcon,
Heart,
LightbulbIcon,
Expand Down Expand Up @@ -33,6 +34,7 @@ export enum Solutions {
finserv = 'finserv',
healthcare = 'healthcare',
agents = 'agents',
hostedPostgres = 'hosted-postgres',
}

export const skillBasedSolutions = {
Expand Down Expand Up @@ -154,6 +156,13 @@ export const useCaseSolutions = {
export const appTypeSolutions = {
label: 'Solutions',
solutions: [
{
id: Solutions.hostedPostgres,
text: 'Hosted Postgres',
description: '',
url: '/solutions/hosted-postgres',
icon: Database,
},
{
id: Solutions.b2bSaaS,
text: 'B2B SaaS',
Expand Down
12 changes: 6 additions & 6 deletions apps/www/data/company-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
// Number is used for animated components (eg. AnimatedCounter)
export const companyStats = {
databasesManaged: {
number: 16_000_000,
text: '16,000,000+',
number: 44_000_000,
text: '44,000,000+',
label: 'Databases Created',
},
databasesLaunchedDaily: {
number: 90_000,
text: '90,000+',
number: 200_000,
text: '200,000+',
label: 'Databases launched daily',
},
developersRegistered: {
number: 7_000_000,
text: '7,000,000+',
number: 9_000_000,
text: '9,000,000+',
label: 'Users',
},
developersRegisteredChange: {
Expand Down
Loading
Loading