Skip to content

Commit 4d86d5b

Browse files
Founder stack page (#10458)
* created founder stack page * link from homepage * footer link * mention lowest prices * lets do this instead * adds links * better responsiveness * responsive adjustments * quick fix --------- Co-authored-by: Eli Kinsey <[email protected]>
1 parent 954812f commit 4d86d5b

File tree

11 files changed

+303
-68
lines changed

11 files changed

+303
-68
lines changed

plugins/gatsby-mapbox-locations/gatsby-node.js

+27-18
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ const MapboxClient = require('@mapbox/mapbox-sdk')
22
const { chunk } = require('lodash')
33

44
const locationForProfile = (profile) => {
5-
return profile.location ?
6-
{ q: profile.location, types: ['place', 'region', 'country'] } :
7-
{ q: profile.country, types: ['country'] }
5+
return profile.location
6+
? { q: profile.location, types: ['place', 'region', 'country'] }
7+
: { q: profile.country, types: ['country'] }
88
}
99

1010
const sourceNodes = async (options, pluginOptions) => {
11-
const { actions: { createNode }, createNodeId, createContentDigest, getNodes, reporter } = options
11+
const {
12+
actions: { createNode },
13+
createNodeId,
14+
createContentDigest,
15+
getNodes,
16+
reporter,
17+
} = options
1218
const { mapboxToken } = pluginOptions
1319

1420
if (!mapboxToken) {
@@ -23,12 +29,13 @@ const sourceNodes = async (options, pluginOptions) => {
2329
// Implement the filter below to guarantee we're not processing profiles that don't have a team
2430

2531
const profiles = getNodes()
26-
.filter(node =>
27-
node.internal.type === 'SqueakProfile' && // For all Squeak profiles
28-
node.teams?.data?.length > 0 && // Implement the following to avoid old profiles: filter: { teams: { data: { elemMatch: { id: { ne: null } } } } }
29-
(node.location || node.country) // Only process profiles with a location or country
32+
.filter(
33+
(node) =>
34+
node.internal.type === 'SqueakProfile' && // For all Squeak profiles
35+
node.teams?.data?.length > 0 && // Implement the following to avoid old profiles: filter: { teams: { data: { elemMatch: { id: { ne: null } } } } }
36+
(node.location || node.country) // Only process profiles with a location or country
3037
)
31-
.map(node => ({
38+
.map((node) => ({
3239
id: node.id,
3340
location: node.location,
3441
country: node.country,
@@ -45,11 +52,13 @@ const sourceNodes = async (options, pluginOptions) => {
4552
reporter.info(`Processing batch ${index + 1}/${batches.length}`)
4653

4754
try {
48-
const response = await mapboxClient.createRequest({
49-
method: 'POST',
50-
path: '/search/geocode/v6/batch',
51-
body: batch.map(locationForProfile)
52-
}).send()
55+
const response = await mapboxClient
56+
.createRequest({
57+
method: 'POST',
58+
path: '/search/geocode/v6/batch',
59+
body: batch.map(locationForProfile),
60+
})
61+
.send()
5362

5463
console.log(JSON.stringify(response.body.batch, null, 2))
5564

@@ -63,8 +72,8 @@ const sourceNodes = async (options, pluginOptions) => {
6372
location: locationForProfile(batch[i]).q,
6473
coordinates: {
6574
latitude,
66-
longitude
67-
}
75+
longitude,
76+
},
6877
})
6978
}
7079
}
@@ -77,7 +86,7 @@ const sourceNodes = async (options, pluginOptions) => {
7786
reporter.info(`Successfully processed ${locations.length} locations`)
7887

7988
// Create nodes directly here, not in a separate function
80-
locations.forEach(location => {
89+
locations.forEach((location) => {
8190
const nodeContent = {
8291
...location,
8392
}
@@ -114,4 +123,4 @@ const createSchemaCustomization = ({ actions }) => {
114123
createTypes(typeDefs)
115124
}
116125

117-
module.exports = { sourceNodes, createSchemaCustomization }
126+
module.exports = { sourceNodes, createSchemaCustomization }

src/components/About/AboutTeam/Map.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { useStaticQuery, graphql } from 'gatsby'
44

55
// Avoid displaying two locations that are too close to each other
66
const isOverlapping = (location: Location, locations: Location[], offset = 2) => {
7-
return locations.some(otherLocation => {
8-
return Math.abs(otherLocation.coordinates.latitude - location.coordinates.latitude) < offset &&
7+
return locations.some((otherLocation) => {
8+
return (
9+
Math.abs(otherLocation.coordinates.latitude - location.coordinates.latitude) < offset &&
910
Math.abs(otherLocation.coordinates.longitude - location.coordinates.longitude) < offset
11+
)
1012
})
1113
}
1214

@@ -38,8 +40,7 @@ export default function Map(): JSX.Element {
3840

3941
const allLocations: Location[] = data.allMapboxLocation.nodes
4042
const nonOverlappingLocations: Location[] = allLocations.reduce((otherLocations, location) => {
41-
if (isOverlapping(location, otherLocations))
42-
return otherLocations
43+
if (isOverlapping(location, otherLocations)) return otherLocations
4344

4445
return [...otherLocations, location]
4546
}, [] as Location[])

src/components/About/AboutTeam/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export const AboutTeam = (): JSX.Element => {
5151
name={name}
5252
country={country}
5353
/>
54-
5554
)
5655
})}
5756
</div>

src/components/Footer/Footer.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ const linklist: IProps[] = [
6767
title: 'How we do "sales"',
6868
url: '/sales',
6969
},
70+
{
71+
title: 'Founder stack',
72+
url: '/founder-stack',
73+
},
7074
],
7175
},
7276
{

src/components/Home/Board/index.tsx

+40-28
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import { AnimatePresence, motion } from 'framer-motion'
6565
import Slider from 'components/Slider'
6666
import { PlayerEvents, DotLottiePlayer } from '@dotlottie/react-player'
6767
import { MenuContainer } from 'components/PostLayout/MobileNav'
68+
import Link from 'components/Link'
6869

6970
type Product = {
7071
name: string
@@ -863,34 +864,45 @@ export default function Hero(): JSX.Element {
863864
</Slider>
864865
</div>
865866
<div className="flex px-2 md:px-0 md:space-x-6 items-start">
866-
<ul className="flex-1 grid grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-x-2 gap-y-6 lg:gap-y-8 md:gap-4 list-none m-0 p-0 flex-grow flex-shrink-0">
867-
{groupedProducts.map(([type, products]) =>
868-
type === 'Sales' ? null : (
869-
<li key={type}>
870-
<ProductButton
871-
type={type}
872-
products={products}
873-
activeProduct={activeProduct}
874-
activeStatus={activeStatus}
875-
setActiveProduct={setActiveProduct}
876-
setProductModalOpen={setProductModalOpen}
877-
/>
878-
{type === 'Support' ? (
879-
<div className="mt-2">
880-
<ProductButton
881-
type={'Sales'}
882-
products={groupedProducts.find(([type]) => type === 'Sales')[1]}
883-
activeProduct={activeProduct}
884-
activeStatus={activeStatus}
885-
setActiveProduct={setActiveProduct}
886-
setProductModalOpen={setProductModalOpen}
887-
/>
888-
</div>
889-
) : null}
890-
</li>
891-
)
892-
)}
893-
</ul>
867+
<div className="@container flex-1">
868+
<ul className="grid @sm:grid-cols-2 @xl:grid-cols-3 md:gap-x-2 gap-y-6 @2xl:gap-y-8 @3xl:gap-y-10 list-none m-0 p-0 flex-grow flex-shrink-0 sm:max-h-[65vh] overflow-y-auto">
869+
{groupedProducts.map(([type, products]) =>
870+
type === 'Sales' ? null : (
871+
<li key={type}>
872+
<ProductButton
873+
type={type}
874+
products={products}
875+
activeProduct={activeProduct}
876+
activeStatus={activeStatus}
877+
setActiveProduct={setActiveProduct}
878+
setProductModalOpen={setProductModalOpen}
879+
/>
880+
{type === 'Support' ? (
881+
<div className="mt-2">
882+
<ProductButton
883+
type={'Sales'}
884+
products={groupedProducts.find(([type]) => type === 'Sales')[1]}
885+
activeProduct={activeProduct}
886+
activeStatus={activeStatus}
887+
setActiveProduct={setActiveProduct}
888+
setProductModalOpen={setProductModalOpen}
889+
/>
890+
</div>
891+
) : null}
892+
</li>
893+
)
894+
)}
895+
</ul>
896+
897+
<div className="mr-8 mx-4 md:mx-0">
898+
<p className="text-sm text-primary/70 dark:text-primary-dark/70 mt-8 pb-3 mb-0">
899+
Each product offers the lowest pricing vs. every competitor at scale.
900+
</p>
901+
</div>
902+
<div className="border-t border-border dark:border-dark pt-3 mx-4 md:mx-0 text-sm text-primary/70 dark:text-primary-dark/70">
903+
Just starting out? <Link to="/founder-stack">Explore our founder stack.</Link>
904+
</div>
905+
</div>
894906
<div className="hidden md:block flex-[0_0_550px]">
895907
{activeProduct && (
896908
<div>

src/components/NotFoundPage/index.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export default function NotFoundPage(): JSX.Element {
1414
useEffect(() => {
1515
// Fetch the JSON file from the external domain
1616
fetch('https://res.cloudinary.com/dmukukwp6/raw/upload/astrohog_a46fc15855.json')
17-
.then(response => response.json())
18-
.then(data => setHogData(data))
19-
.catch(error => console.error('Error loading animation data:', error))
17+
.then((response) => response.json())
18+
.then((data) => setHogData(data))
19+
.catch((error) => console.error('Error loading animation data:', error))
2020

2121
// Capture the event only if posthog is available
2222
if (posthog) {
@@ -79,7 +79,7 @@ export default function NotFoundPage(): JSX.Element {
7979
</CallToAction>
8080

8181
<p className="mt-8 text-sm text-white/70">
82-
Think this is a mistake? {' '}
82+
Think this is a mistake?{' '}
8383
<a href="https://github.com/PostHog/posthog.com/issues" className="text-yellow">
8484
Raise an issue
8585
</a>{' '}

src/navs/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -3382,6 +3382,12 @@ export const pricingMenu = {
33823382
color: 'green',
33833383
url: '/sales',
33843384
},
3385+
{
3386+
name: 'Founder stack',
3387+
icon: 'IconStack',
3388+
color: 'salmon',
3389+
url: '/founder-stack',
3390+
},
33853391
],
33863392
}
33873393

0 commit comments

Comments
 (0)