From 3da1faef69f74314d92288047796f74930871686 Mon Sep 17 00:00:00 2001 From: jongomez Date: Tue, 24 Oct 2023 12:49:54 +0100 Subject: [PATCH] feat: implement job list --- .../docusaurus-playground/src/pages/index.mdx | 2 + .../components/mdx/JobList/JobList.scss | 0 .../client/components/mdx/JobList/JobList.tsx | 53 +++++++++ .../client/components/mdx/JobList/index.ts | 1 + .../components/mdx/JobList/useFetchJobs.ts | 108 ++++++++++++++++++ .../src/client/components/mdx/index.ts | 1 + 6 files changed, 165 insertions(+) create mode 100644 packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.scss create mode 100644 packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.tsx create mode 100644 packages/logos-docusaurus-theme/src/client/components/mdx/JobList/index.ts create mode 100644 packages/logos-docusaurus-theme/src/client/components/mdx/JobList/useFetchJobs.ts diff --git a/packages/docusaurus-playground/src/pages/index.mdx b/packages/docusaurus-playground/src/pages/index.mdx index a3b3b24..0a107ce 100644 --- a/packages/docusaurus-playground/src/pages/index.mdx +++ b/packages/docusaurus-playground/src/pages/index.mdx @@ -18,6 +18,7 @@ import { SectionHeader, TimelineItem, ShowcaseCard, + JobList, } from '../components/mdx' @@ -352,3 +353,4 @@ import { Build on Waku + diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.scss b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.tsx b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.tsx new file mode 100644 index 0000000..2f759b8 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/JobList.tsx @@ -0,0 +1,53 @@ +import React, { useState } from 'react' +import useFetchJobs, { JobBoard, Job } from './useFetchJobs' + +type Props = { + jobBoard: JobBoard + titleFilter?: string +} + +export const JobList: React.FC = ({ jobBoard, titleFilter = '' }) => { + const { data, error, fetchJobs } = useFetchJobs() + const [isLoading, setIsLoading] = useState(false) + + const handleFetchJobs = async () => { + setIsLoading(true) + await fetchJobs([jobBoard], titleFilter) + setIsLoading(false) + } + + React.useEffect(() => { + handleFetchJobs() + }, [jobBoard, titleFilter]) + + if (isLoading) { + return
Loading...
+ } + + if (error) { + return
Error: {error.message}
+ } + + if (!data) { + return
No data
+ } + + return ( +
+

Job List

+ +
+ ) +} diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/index.ts b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/index.ts new file mode 100644 index 0000000..22f40c2 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/index.ts @@ -0,0 +1 @@ +export * from './JobList' diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/useFetchJobs.ts b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/useFetchJobs.ts new file mode 100644 index 0000000..083aed0 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/JobList/useFetchJobs.ts @@ -0,0 +1,108 @@ +import { useState } from 'react' + +// Inspired by: +// https://github.com/acid-info/rnd-dynamic-list/blob/master/react/useFetchJobs.js + +const jobBoards = [ + 'acidtest', + 'logos', + 'status', + 'nimbus', + 'codex', + 'nomos', + 'statusnetwork', + 'ift', + 'vac', + 'waku', +] as const + +export type JobBoard = (typeof jobBoards)[number] + +const jobBoardMappings: Record = { + acidtest: 'testacidinfo', + logos: 'logos', + status: 'status72', + nimbus: 'nimbus', + codex: 'codex', + nomos: 'nomos', + statusnetwork: 'thestatusnetwork', + ift: 'instituteoffreetechnologies', + vac: 'vac', + waku: 'waku', +} + +export type Job = { + absolute_url: string + data_compliance?: { + type: string + requires_consent: boolean + requires_processing_consent: boolean + requires_retention_consent: boolean + retention_period: null | string // Assuming retention_period can be a string or null. + }[] + internal_job_id: number + location?: { + name: string + } + metadata?: any + id: number + updated_at: string + requisition_id: string + title: string +} + +type JobData = { + jobs: Job[] + meta: { + total: number + } +} | null + +type UseFetchJobs = { + data: JobData + error: any + fetchJobs: (jobBoardsToFetch: JobBoard[], titleFilter: string) => void +} + +export const useFetchJobs = (): UseFetchJobs => { + const [data, setData] = useState(null) + const [error, setError] = useState(null) + + const fetchJobs = async (jobBoardsToFetch: JobBoard[], titleFilter) => { + try { + const resultsPerBoard: Partial> = {} + + for (let board of jobBoardsToFetch) { + const response = await fetch( + `https://boards-api.greenhouse.io/v1/boards/${jobBoardMappings[board]}/jobs`, + ) + const jobData = await response.json() + resultsPerBoard[board] = jobData.jobs + } + + let jobs = Object.values(resultsPerBoard).flat() as unknown as Job[] + + if (titleFilter) { + jobs = jobs.filter( + (job) => job.title && job.title.includes(titleFilter), + ) + } + + setData({ jobs, meta: { total: jobs.length } }) + } catch (err) { + if (err instanceof Error) { + setError(err) + } else if (typeof err === 'string') { + setError(new Error(err)) + } else { + setError(new Error('Unknown error')) + } + + console.error(err) + } + } + + return { data, error, fetchJobs } +} + +export default useFetchJobs diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts b/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts index 24e703e..a09c986 100644 --- a/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts @@ -24,3 +24,4 @@ export * from './Showcase' export * from './ShowcaseCard' export * from './SocialCard' export * from './TimelineItem' +export * from './JobList'