Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Founder stack page #10458

Merged
merged 10 commits into from
Feb 6, 2025
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
45 changes: 27 additions & 18 deletions plugins/gatsby-mapbox-locations/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ const MapboxClient = require('@mapbox/mapbox-sdk')
const { chunk } = require('lodash')

const locationForProfile = (profile) => {
return profile.location ?
{ q: profile.location, types: ['place', 'region', 'country'] } :
{ q: profile.country, types: ['country'] }
return profile.location
? { q: profile.location, types: ['place', 'region', 'country'] }
: { q: profile.country, types: ['country'] }
}

const sourceNodes = async (options, pluginOptions) => {
const { actions: { createNode }, createNodeId, createContentDigest, getNodes, reporter } = options
const {
actions: { createNode },
createNodeId,
createContentDigest,
getNodes,
reporter,
} = options
const { mapboxToken } = pluginOptions

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

const profiles = getNodes()
.filter(node =>
node.internal.type === 'SqueakProfile' && // For all Squeak profiles
node.teams?.data?.length > 0 && // Implement the following to avoid old profiles: filter: { teams: { data: { elemMatch: { id: { ne: null } } } } }
(node.location || node.country) // Only process profiles with a location or country
.filter(
(node) =>
node.internal.type === 'SqueakProfile' && // For all Squeak profiles
node.teams?.data?.length > 0 && // Implement the following to avoid old profiles: filter: { teams: { data: { elemMatch: { id: { ne: null } } } } }
(node.location || node.country) // Only process profiles with a location or country
)
.map(node => ({
.map((node) => ({
id: node.id,
location: node.location,
country: node.country,
Expand All @@ -45,11 +52,13 @@ const sourceNodes = async (options, pluginOptions) => {
reporter.info(`Processing batch ${index + 1}/${batches.length}`)

try {
const response = await mapboxClient.createRequest({
method: 'POST',
path: '/search/geocode/v6/batch',
body: batch.map(locationForProfile)
}).send()
const response = await mapboxClient
.createRequest({
method: 'POST',
path: '/search/geocode/v6/batch',
body: batch.map(locationForProfile),
})
.send()

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

Expand All @@ -63,8 +72,8 @@ const sourceNodes = async (options, pluginOptions) => {
location: locationForProfile(batch[i]).q,
coordinates: {
latitude,
longitude
}
longitude,
},
})
}
}
Expand All @@ -77,7 +86,7 @@ const sourceNodes = async (options, pluginOptions) => {
reporter.info(`Successfully processed ${locations.length} locations`)

// Create nodes directly here, not in a separate function
locations.forEach(location => {
locations.forEach((location) => {
const nodeContent = {
...location,
}
Expand Down Expand Up @@ -114,4 +123,4 @@ const createSchemaCustomization = ({ actions }) => {
createTypes(typeDefs)
}

module.exports = { sourceNodes, createSchemaCustomization }
module.exports = { sourceNodes, createSchemaCustomization }
9 changes: 5 additions & 4 deletions src/components/About/AboutTeam/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { useStaticQuery, graphql } from 'gatsby'

// Avoid displaying two locations that are too close to each other
const isOverlapping = (location: Location, locations: Location[], offset = 2) => {
return locations.some(otherLocation => {
return Math.abs(otherLocation.coordinates.latitude - location.coordinates.latitude) < offset &&
return locations.some((otherLocation) => {
return (
Math.abs(otherLocation.coordinates.latitude - location.coordinates.latitude) < offset &&
Math.abs(otherLocation.coordinates.longitude - location.coordinates.longitude) < offset
)
})
}

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

const allLocations: Location[] = data.allMapboxLocation.nodes
const nonOverlappingLocations: Location[] = allLocations.reduce((otherLocations, location) => {
if (isOverlapping(location, otherLocations))
return otherLocations
if (isOverlapping(location, otherLocations)) return otherLocations

return [...otherLocations, location]
}, [] as Location[])
Expand Down
1 change: 0 additions & 1 deletion src/components/About/AboutTeam/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const AboutTeam = (): JSX.Element => {
name={name}
country={country}
/>

)
})}
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ const linklist: IProps[] = [
title: 'How we do "sales"',
url: '/sales',
},
{
title: 'Founder stack',
url: '/founder-stack',
},
],
},
{
Expand Down
68 changes: 40 additions & 28 deletions src/components/Home/Board/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import { AnimatePresence, motion } from 'framer-motion'
import Slider from 'components/Slider'
import { PlayerEvents, DotLottiePlayer } from '@dotlottie/react-player'
import { MenuContainer } from 'components/PostLayout/MobileNav'
import Link from 'components/Link'

type Product = {
name: string
Expand Down Expand Up @@ -863,34 +864,45 @@ export default function Hero(): JSX.Element {
</Slider>
</div>
<div className="flex px-2 md:px-0 md:space-x-6 items-start">
<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">
{groupedProducts.map(([type, products]) =>
type === 'Sales' ? null : (
<li key={type}>
<ProductButton
type={type}
products={products}
activeProduct={activeProduct}
activeStatus={activeStatus}
setActiveProduct={setActiveProduct}
setProductModalOpen={setProductModalOpen}
/>
{type === 'Support' ? (
<div className="mt-2">
<ProductButton
type={'Sales'}
products={groupedProducts.find(([type]) => type === 'Sales')[1]}
activeProduct={activeProduct}
activeStatus={activeStatus}
setActiveProduct={setActiveProduct}
setProductModalOpen={setProductModalOpen}
/>
</div>
) : null}
</li>
)
)}
</ul>
<div className="@container flex-1">
<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">
{groupedProducts.map(([type, products]) =>
type === 'Sales' ? null : (
<li key={type}>
<ProductButton
type={type}
products={products}
activeProduct={activeProduct}
activeStatus={activeStatus}
setActiveProduct={setActiveProduct}
setProductModalOpen={setProductModalOpen}
/>
{type === 'Support' ? (
<div className="mt-2">
<ProductButton
type={'Sales'}
products={groupedProducts.find(([type]) => type === 'Sales')[1]}
activeProduct={activeProduct}
activeStatus={activeStatus}
setActiveProduct={setActiveProduct}
setProductModalOpen={setProductModalOpen}
/>
</div>
) : null}
</li>
)
)}
</ul>

<div className="mr-8 mx-4 md:mx-0">
<p className="text-sm text-primary/70 dark:text-primary-dark/70 mt-8 pb-3 mb-0">
Each product offers the lowest pricing vs. every competitor at scale.
</p>
</div>
<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">
Just starting out? <Link to="/founder-stack">Explore our founder stack.</Link>
</div>
</div>
<div className="hidden md:block flex-[0_0_550px]">
{activeProduct && (
<div>
Expand Down
8 changes: 4 additions & 4 deletions src/components/NotFoundPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export default function NotFoundPage(): JSX.Element {
useEffect(() => {
// Fetch the JSON file from the external domain
fetch('https://res.cloudinary.com/dmukukwp6/raw/upload/astrohog_a46fc15855.json')
.then(response => response.json())
.then(data => setHogData(data))
.catch(error => console.error('Error loading animation data:', error))
.then((response) => response.json())
.then((data) => setHogData(data))
.catch((error) => console.error('Error loading animation data:', error))

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

<p className="mt-8 text-sm text-white/70">
Think this is a mistake? {' '}
Think this is a mistake?{' '}
<a href="https://github.com/PostHog/posthog.com/issues" className="text-yellow">
Raise an issue
</a>{' '}
Expand Down
6 changes: 6 additions & 0 deletions src/navs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3378,6 +3378,12 @@ export const pricingMenu = {
color: 'green',
url: '/sales',
},
{
name: 'Founder stack',
icon: 'IconStack',
color: 'salmon',
url: '/founder-stack',
},
],
}

Expand Down
Loading