Skip to content

Commit

Permalink
more pitch adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
emilwidlund committed Jan 16, 2025
1 parent de8add6 commit 0dd76f2
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 231 deletions.
4 changes: 2 additions & 2 deletions clients/apps/web/src/app/pitch/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ export default function PitchPage() {

return (
<div className="flex h-full flex-col justify-between gap-y-12 text-sm">
<div className="flex flex-grow flex-col gap-y-16 md:gap-y-32">
<div className="flex flex-grow flex-col gap-y-16">
<PitchNavigation activeIndex={index} setIndex={setIndex} />
<AnimatePresence key={index}>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.04, repeat: 2 }}
transition={{ duration: 0.07, repeat: 2 }}
>
{getActiveSection()}
</motion.div>
Expand Down
68 changes: 1 addition & 67 deletions clients/apps/web/src/components/Pitch/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,6 @@ import * as d3 from 'd3'
import { GeistMono } from 'geist/font/mono'
import { useCallback, useEffect, useMemo, useState } from 'react'

const primaryColor = 'rgb(0 98 255)'
const primaryColorFaded = 'rgba(0, 98, 255, 0.3)'
const gradientId = 'chart-gradient'
const createAreaGradient = (id: string) => {
// Create a <defs> element
const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')

// Create a <linearGradient> element
const linearGradient = document.createElementNS(
'http://www.w3.org/2000/svg',
'linearGradient',
)
linearGradient.setAttribute('id', id)
linearGradient.setAttribute('gradientTransform', 'rotate(90)')

// Create the first <stop> element
const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop')
stop1.setAttribute('offset', '0%')
stop1.setAttribute('stop-color', primaryColorFaded)
stop1.setAttribute('stop-opacity', '0.5')

// Create the second <stop> element
const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop')
stop2.setAttribute('offset', '100%')
stop2.setAttribute('stop-color', primaryColorFaded)
stop2.setAttribute('stop-opacity', '0')

// Append the <stop> elements to the <linearGradient> element
linearGradient.appendChild(stop1)
linearGradient.appendChild(stop2)

// Append the <linearGradient> element to the <defs> element
defs.appendChild(linearGradient)

return defs
}

class Callback extends Plot.Dot {
private callbackFunction: (index: number | undefined) => void

public constructor(
data: Plot.Data,
options: Plot.DotOptions,
callbackFunction: (data: any) => void,
) {
// @ts-ignore
super(data, options)
this.callbackFunction = callbackFunction
}

// @ts-ignore
public render(
index: number[],
_scales: Plot.ScaleFunctions,
_values: Plot.ChannelValues,
_dimensions: Plot.Dimensions,
_context: Plot.Context,
_next?: Plot.RenderFunction,
): SVGElement | null {
if (index.length) {
this.callbackFunction(index[0])
}
return null
}
}

const getTicks = (timestamps: Date[], maxTicks: number = 10): Date[] => {
const step = Math.ceil(timestamps.length / maxTicks)
return timestamps.filter((_, index) => index % step === 0)
Expand Down Expand Up @@ -172,7 +106,6 @@ export const Chart: React.FC<ChartProps> = ({
width,
height,
marks: [
() => createAreaGradient(gradientId),
Plot.axisX({
tickFormat: getTickFormat(interval, ticks),
ticks,
Expand All @@ -191,6 +124,7 @@ export const Chart: React.FC<ChartProps> = ({
y: metric.slug,
stroke: 'currentColor',
strokeWidth: 1,
marker: 'circle-fill',
}),
Plot.ruleX(data, {
x: 'timestamp',
Expand Down
26 changes: 14 additions & 12 deletions clients/apps/web/src/components/Pitch/Console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ import { twMerge } from 'tailwind-merge'

export interface ConsoleProps {
className?: string
title?: string
input?: string
output?: string
}

export const Console = ({ className, input, output }: ConsoleProps) => {
export const Console = ({ className, title, input, output }: ConsoleProps) => {
return (
<div
className={twMerge('border-polar-200 flex flex-col border', className)}
>
<div className="bg-polar-200 flex flex-row px-3 py-1 text-xs text-black">
<span>Polar VM</span>
</div>
<div className="flex flex-col p-4 font-mono text-sm">
<pre className="flex flex-col gap-y-2">
<code>{'$ ' + input}</code>
<code className="text-polar-500">{output}</code>
</pre>
<div className={twMerge('relative flex flex-col', className)}>
<div className="border-polar-600 absolute right-6 top-6 h-full w-full transform border"></div>
<div className="border-polar-200 bg-polar-900 relative h-full w-full border-2">
<div className="bg-polar-200 flex flex-row justify-between px-3 py-1 text-xs text-black">
<span className="font-bold">{title ?? 'Polar VM'}</span>
</div>
<div className="flex flex-col p-4 font-mono text-sm">
<pre className="flex flex-col gap-y-2">
<code>{input}</code>
<code className="text-polar-500">{output}</code>
</pre>
</div>
</div>
</div>
)
Expand Down
6 changes: 3 additions & 3 deletions clients/apps/web/src/components/Pitch/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { sections } from './Navigation'
export const Footer = ({ className }: { className?: string }) => {
return (
<div
className={twMerge('hidden flex-row gap-x-8 text-xs md:flex', className)}
className={twMerge('hidden flex-row gap-x-12 text-xs md:flex', className)}
>
<NavigationLegend />
<SectionsLegend />
Expand Down Expand Up @@ -71,7 +71,7 @@ const OpenSourceLegend = () => {
const ContactUsLegend = () => {
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'm') {
if (event.key === 'c') {
window.open('mailto:[email protected]', '_blank')
}
}
Expand All @@ -86,7 +86,7 @@ const ContactUsLegend = () => {
return (
<div className="flex flex-col gap-y-2">
<div className="flex flex-row gap-x-2">
<Button variant="icon">M</Button>
<Button variant="icon">C</Button>
</div>
<span>Contact Us</span>
</div>
Expand Down
27 changes: 27 additions & 0 deletions clients/apps/web/src/components/Pitch/Section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export interface SectionProps {
header: {
index: string
name: string
}
title: string
children: React.ReactNode
context?: React.ReactNode
}

export const Section = ({ header, title, children, context }: SectionProps) => {
return (
<div className="flex flex-col gap-y-16 md:flex-row md:gap-x-32">
<div className="flex max-w-lg flex-col gap-y-8">
<div className="flex flex-row items-center gap-x-4">
<span className="bg-polar-200 px-1 py-0.5 text-sm leading-none text-black">
{header.index}.
</span>
<h1 className="text-lg">{header.name}</h1>
</div>
<h1 className="text-balance text-4xl leading-normal">{title}</h1>
{children}
</div>
{context}
</div>
)
}
47 changes: 22 additions & 25 deletions clients/apps/web/src/components/Pitch/sections/IndexSection.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
import { Console } from '../Console'
import { Link } from '../Link'
import { Section } from '../Section'

export const IndexSection = () => {
return (
<div className="flex flex-col gap-y-16 md:flex-row md:gap-x-32">
<div className="flex max-w-lg flex-col gap-y-8">
<h1 className="text-lg">00. Index</h1>
<h1 className="text-4xl">Integrating payments is a mess</h1>
<p>
What used to be a simple way to pay for things has become a complex
mess.
</p>
<p>
Software as a Service (SaaS) has become the norm, but the underlying
payment infrastructure has not evolved.
</p>
<p>
This is why we are building Polar 2.0, payment infrastructure for the
21st century.
</p>
<Link href="/pitch/what">What we are building →</Link>
</div>

<Console
className="aspect-video w-full max-w-lg"
input="polar-init"
output="Initializing seed round..."
/>
</div>
<Section
header={{ index: '00', name: 'Index' }}
title="Integrating payments is a mess"
context={
<Console
className="flex aspect-video max-w-lg flex-grow"
input="$ polar-init"
output="Initializing seed round..."
/>
}
>
<p>
What used to be a simple way to pay for things has become a complex
mess.
</p>
<p>
Software as a Service (SaaS) has become the norm, but the underlying
payment infrastructure has not evolved.
</p>
<Link href="/pitch/what">What we are building →</Link>
</Section>
)
}
35 changes: 16 additions & 19 deletions clients/apps/web/src/components/Pitch/sections/InvestorsSection.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import { Link } from '../Link'
import { Section } from '../Section'

export const InvestorsSection = () => {
return (
<div className="flex flex-col gap-y-16 md:flex-row md:gap-x-32">
<div className="flex max-w-lg flex-col gap-y-8">
<h1 className="text-lg">06. Investors</h1>
<h1 className="text-4xl">Our Angels</h1>
<p>
What used to be a simple way to pay for things has become a complex
mess.
</p>
<p>
Software as a Service (SaaS) has become the norm, but the underlying
payment infrastructure has not evolved.
</p>
<p>
This is why we are building Polar 2.0, payment infrastructure for the
21st century.
</p>
<Link href="/pitch/what">Why →</Link>
</div>
</div>
<Section header={{ index: '06', name: 'Investors' }} title="Our Angels">
<p>
What used to be a simple way to pay for things has become a complex
mess.
</p>
<p>
Software as a Service (SaaS) has become the norm, but the underlying
payment infrastructure has not evolved.
</p>
<p>
This is why we are building Polar 2.0, payment infrastructure for the
21st century.
</p>
<Link href="/pitch/what">Why →</Link>
</Section>
)
}
53 changes: 34 additions & 19 deletions clients/apps/web/src/components/Pitch/sections/Polar20.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
import { Console } from '../Console'
import { Link } from '../Link'
import { Section } from '../Section'

export const Polar20Section = () => {
return (
<div className="flex flex-col gap-y-16 md:flex-row md:gap-x-32">
<div className="flex max-w-lg flex-col gap-y-8">
<h1 className="text-lg">03. Polar 2.0</h1>
<h1 className="text-4xl">The future of payments is usage based</h1>
<p>
What used to be a simple way to pay for things has become a complex
mess.
</p>
<p>
Software as a Service (SaaS) has become the norm, but the underlying
payment infrastructure has not evolved.
</p>
<p>
This is why we are building Polar 2.0, payment infrastructure for the
21st century.
</p>
<Link href="/pitch/what">Why →</Link>
</div>
</div>
<Section
header={{ index: '03', name: 'Polar 2.0' }}
title="The future of payments is usage based"
context={
<Console
title="NextJS Adapter"
input={`import { Usage } from '@polar-sh/nextjs'
import { openai } from '@ai-sdk/openai'
export const POST = Usage()
.customer(req => req.headers.get('X-Polar-Customer-Id'))
.model(openai('gpt-4o'))
.increment('gpt-4o-inputs', ctx => ctx.usage.inputTokens)
.increment('gpt-4o-outputs', ctx => ctx.usage.completionTokens)
.handler((req, res, model) => /** Use model... */)`}
/>
}
>
<p>
What used to be a simple way to pay for things has become a complex
mess.
</p>
<p>
Software as a Service (SaaS) has become the norm, but the underlying
payment infrastructure has not evolved.
</p>
<p>
This is why we are building Polar 2.0, payment infrastructure for the
21st century.
</p>
<Link href="/pitch/what">Why →</Link>
</Section>
)
}
Loading

0 comments on commit 0dd76f2

Please sign in to comment.