Skip to content

Commit 9ebaa85

Browse files
authored
fix: Refactor the careers page to handle a rate-limit issue from Github. (supabase#36443)
* Refactor the careers page to handle a rate-limit issue from Github. * Remove extra console.logs.
1 parent b399331 commit 9ebaa85

File tree

1 file changed

+58
-52
lines changed

1 file changed

+58
-52
lines changed

apps/www/pages/careers.tsx

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,59 @@
1-
import { GetServerSideProps, NextPage } from 'next'
1+
import { GlobeAltIcon } from '@heroicons/react/outline'
2+
import { Check } from 'lucide-react'
3+
import { GetServerSideProps } from 'next'
4+
import { NextSeo } from 'next-seo'
25
import Image from 'next/image'
36
import Link from 'next/link'
47
import { useRouter } from 'next/router'
5-
import { NextSeo } from 'next-seo'
6-
import { GlobeAltIcon } from '@heroicons/react/outline'
7-
import { Check } from 'lucide-react'
8-
import { Badge, Button, Separator, buttonVariants, cn } from 'ui'
98
import ReactMarkdown from 'react-markdown'
9+
import { Badge, Button, buttonVariants, cn, Separator } from 'ui'
10+
import { z } from 'zod'
1011
import Styles from '~/styles/career.module.css'
1112

1213
import Globe from '~/components/Globe'
1314
import DefaultLayout from '~/components/Layouts/Default'
1415
import SectionContainer from '~/components/Layouts/SectionContainer'
1516

16-
import { groupJobsByTeam, filterGenericJob, JobItemProps, PLACEHOLDER_JOB_ID } from '~/lib/careers'
1717
import career from '~/data/career.json'
18+
import { filterGenericJob, groupJobsByTeam, JobItemProps, PLACEHOLDER_JOB_ID } from '~/lib/careers'
19+
20+
const ContributorSchema = z.object({
21+
login: z.string(),
22+
avatar_url: z.string(),
23+
html_url: z.string(),
24+
})
25+
26+
type Contributor = z.infer<typeof ContributorSchema>
1827

1928
export const getServerSideProps: GetServerSideProps = (async ({ res }) => {
2029
// refresh every 5 minutes
2130
res.setHeader('Cache-Control', 'public, max-age=300, stale-while-revalidate=300')
2231

2332
const job_res = await fetch('https://api.ashbyhq.com/posting-api/job-board/supabase')
24-
const job_data = await job_res.json()
33+
const job_data = (await job_res.json()) as { jobs: JobItemProps[] }
2534

26-
const jobs = groupJobsByTeam(job_data.jobs.filter((job: JobItemProps) => !filterGenericJob(job)))
35+
const jobs = groupJobsByTeam(job_data.jobs.filter((job) => !filterGenericJob(job)))
2736
const placeholderJob = job_data.jobs.find(filterGenericJob)
2837

29-
const contributor_res = await fetch(
38+
const contributorResponse = await fetch(
3039
'https://api.github.com/repos/supabase/supabase/contributors?per_page=100'
3140
)
32-
const contributor_arr = await contributor_res.json()
41+
let contributorArray: Contributor[] = []
42+
try {
43+
const contributorResponseData = await contributorResponse.json()
44+
// if the response is not in the expected format, throw an error and return an empty array
45+
contributorArray = ContributorSchema.array().parse(contributorResponseData)
46+
} catch {}
3347

34-
const contributor_data = await contributor_arr.map(
35-
(contributor: { login: string; avatar_url: string; html_url: string }) => {
36-
return {
37-
login: contributor.login,
38-
avatar_url: contributor.avatar_url,
39-
html_url: contributor.html_url,
40-
}
48+
const contributor_data = contributorArray.map((contributor) => {
49+
return {
50+
login: contributor.login,
51+
avatar_url: contributor.avatar_url,
52+
html_url: contributor.html_url,
4153
}
42-
)
54+
})
4355

44-
const contributors = await contributor_data.filter((contributor: any) =>
56+
const contributors = await contributor_data.filter((contributor) =>
4557
career.contributors.includes(contributor.login)
4658
)
4759

@@ -74,11 +86,11 @@ export const getServerSideProps: GetServerSideProps = (async ({ res }) => {
7486

7587
interface CareersPageProps {
7688
jobs: Record<string, JobItemProps[]>
77-
placeholderJob: JobItemProps
89+
placeholderJob: JobItemProps | null
7890
contributors: { login: string; avatar_url: string; html_url: string }[]
7991
}
8092

81-
const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contributors }) => {
93+
const CareerPage = ({ jobs, placeholderJob, contributors }: CareersPageProps) => {
8294
const { basePath } = useRouter()
8395

8496
const meta_title = 'Careers | Supabase'
@@ -118,7 +130,7 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
118130

119131
<SectionContainer className="!pt-8">
120132
<div className="flex flex-wrap md:flex-nowrap -mt-6 md:mt-0 w-fit md:w-full mx-auto md:flex md:items-start justify-around lg:w-full lg:max-w-5xl">
121-
{career.company.map((company: { number: string; text: string }, i: number) => {
133+
{career.company.map((company, i) => {
122134
return (
123135
<div
124136
key={i}
@@ -284,18 +296,16 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
284296
our team effective:
285297
</p>
286298
<div className="grid pt-10 gap-8 grid-cols-2 md:grid-cols-3 lg:gap-16 lg:grid-cols-5">
287-
{career.humanPowered.map(
288-
(human: { icon: string; title: string; text: string }, i: number) => {
289-
return (
290-
<div key={i} className="flex flex-col gap-3">
291-
<div>
292-
<h3 className="text-base">{human.title}</h3>
293-
<p className="text-foreground-light text-xs lg:text-sm">{human.text}</p>
294-
</div>
299+
{career.humanPowered.map((human, i) => {
300+
return (
301+
<div key={i} className="flex flex-col gap-3">
302+
<div>
303+
<h3 className="text-base">{human.title}</h3>
304+
<p className="text-foreground-light text-xs lg:text-sm">{human.text}</p>
295305
</div>
296-
)
297-
}
298-
)}
306+
</div>
307+
)
308+
})}
299309
</div>
300310
</SectionContainer>
301311

@@ -312,7 +322,7 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
312322
</p>
313323
</div>
314324
<div className="w-[1080px] h-[370px] mx-auto sm:mt-10 md:mt-16 lg:mt-28 2xl:mt-60">
315-
{contributors.map((contributor: any, i: number) => {
325+
{contributors.map((contributor, i) => {
316326
return (
317327
<div
318328
className={`${
@@ -372,20 +382,16 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
372382
</h2>
373383
</div>
374384
<div className="mt-12 xl:mt-0 space-y-6 lg:space-y-0 sm:w-fit sm:mx-auto lg:grid lg:grid-cols-2 lg:gap-16">
375-
{career.benefits.map(
376-
(benefits: { icon: string; title: string; text: string }, i: number) => {
377-
return (
378-
<div className="h-full flex items-start space-x-6 w-full" key={i}>
379-
<div className="h-fit text-sm lg:text-base">
380-
<h3 className="text-sm">{benefits.title}</h3>
381-
<ReactMarkdown className="prose pt-1 text-sm">
382-
{benefits.text}
383-
</ReactMarkdown>
384-
</div>
385+
{career.benefits.map((benefits, i) => {
386+
return (
387+
<div className="h-full flex items-start space-x-6 w-full" key={i}>
388+
<div className="h-fit text-sm lg:text-base">
389+
<h3 className="text-sm">{benefits.title}</h3>
390+
<ReactMarkdown className="prose pt-1 text-sm">{benefits.text}</ReactMarkdown>
385391
</div>
386-
)
387-
}
388-
)}
392+
</div>
393+
)
394+
})}
389395
</div>
390396
</div>
391397
</SectionContainer>
@@ -401,7 +407,7 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
401407
</p>
402408
</div>
403409
<div className="mt-16 md:ml-36 lg:flex lg:items-start lg:w-fit lg:mx-auto">
404-
{career.hiring.map((hiring: { title: string; text: string }, i: number) => {
410+
{career.hiring.map((hiring, i) => {
405411
return (
406412
<div
407413
key={i + 1}
@@ -444,9 +450,9 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
444450
<div key={team}>
445451
<h3 className="text-foreground-lighter text-sm">{team}</h3>
446452
<div className="mt-2 -space-y-px">
447-
{(teamJobs as JobItemProps[])
448-
.filter((job: any) => !filterGenericJob(job))
449-
.map((job: JobItemProps) => (
453+
{teamJobs
454+
.filter((job) => !filterGenericJob(job))
455+
.map((job) => (
450456
<JobItem job={job} key={job.id} />
451457
))}
452458
</div>
@@ -481,7 +487,7 @@ const CareerPage: NextPage<CareersPageProps> = ({ jobs, placeholderJob, contribu
481487
)
482488
}
483489

484-
const JobItem: React.FC<{ job: JobItemProps }> = ({ job }) => {
490+
const JobItem = ({ job }: { job: JobItemProps }) => {
485491
const isPlaceholderJob = job.id === PLACEHOLDER_JOB_ID
486492

487493
return (

0 commit comments

Comments
 (0)