From 38c236d281f63064cfb2413e671d3ded58c64f29 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Mon, 4 Apr 2022 23:42:54 -0700 Subject: [PATCH] Create JobDropdown --- components/JobDropdown/index.scss | 0 components/JobDropdown/index.tsx | 97 +++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 components/JobDropdown/index.scss create mode 100644 components/JobDropdown/index.tsx diff --git a/components/JobDropdown/index.scss b/components/JobDropdown/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/components/JobDropdown/index.tsx b/components/JobDropdown/index.tsx new file mode 100644 index 00000000..b0a6019f --- /dev/null +++ b/components/JobDropdown/index.tsx @@ -0,0 +1,97 @@ +import React, { useCallback, useEffect, useState } from 'react' +import { useRouter } from 'next/router' + +import api from '~utils/api' +import { appState } from '~utils/appState' +import { jobGroups } from '~utils/jobGroups' + +import './index.scss' + +// Props +interface Props { + currentJob?: string + onChange?: (job?: Job) => void + onBlur?: (event: React.ChangeEvent) => void +} + +type GroupedJob = { [key: string]: Job[] } + +const JobDropdown = React.forwardRef(function useFieldSet(props, ref) { + // Set up router for locale + const router = useRouter() + const locale = router.locale || 'en' + + // Set up local states for storing jobs + const [currentJob, setCurrentJob] = useState() + const [jobs, setJobs] = useState() + const [sortedJobs, setSortedJobs] = useState() + + // Organize jobs into groups on mount + const organizeJobs = useCallback((jobs: Job[]) => { + const jobGroups = jobs.map(job => job.row).filter((value, index, self) => self.indexOf(value) === index) + let groupedJobs: GroupedJob = {} + + jobGroups.forEach(group => { + groupedJobs[group] = jobs.filter(job => job.row === group) + }) + + setJobs(jobs) + setSortedJobs(groupedJobs) + appState.jobs = jobs + }, []) + + // Fetch all jobs on mount + useEffect(() => { + api.endpoints.jobs.getAll() + .then(response => organizeJobs(response.data)) + }, [organizeJobs]) + + // Set current job on mount + useEffect(() => { + if (jobs && props.currentJob) { + const job = jobs.find(job => job.id === props.currentJob) + setCurrentJob(job) + } + }, [jobs, props.currentJob]) + + // Enable changing select value + function handleChange(event: React.ChangeEvent) { + if (jobs) { + const job = jobs.find(job => job.id === event.target.value) + if (props.onChange) props.onChange(job) + setCurrentJob(job) + } + } + + // Render JSX for each job option, sorted into optgroups + function renderJobGroup(group: string) { + const options = sortedJobs && sortedJobs[group].length > 0 && + sortedJobs[group].sort((a, b) => a.order - b.order).map((item, i) => { + return ( + + ) + }) + + const groupName = jobGroups.find(g => g.slug === group)?.name[locale] + + return ( + + {options} + + ) + } + + return ( + + ) +}) + +export default JobDropdown