import React from "react" import { useFormContext, Controller } from "react-hook-form" import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" import { Checkbox } from "@/components/ui/checkbox" import { Separator } from "@/components/ui/separator" import { UpdateSettingsInput } from "@shared/settings-schema" import type { JobspyValues } from "@client/pages/settings/types" import { SettingsInput } from "@client/pages/settings/components/SettingsInput" type JobspySectionProps = { values: JobspyValues isLoading: boolean isSaving: boolean } export const JobspySection: React.FC = ({ values, isLoading, isSaving, }) => { const { sites, location, resultsWanted, hoursOld, countryIndeed, linkedinFetchDescription, } = values const { control, register, formState: { errors } } = useFormContext() return ( JobSpy Scraper
Scraped Sites
( { const current = field.value ?? sites.default let next = [...current] if (checked) { if (!next.includes('indeed')) next.push('indeed') } else { next = next.filter(s => s !== 'indeed') } field.onChange(next) }} disabled={isLoading || isSaving} /> )} />
( { const current = field.value ?? sites.default let next = [...current] if (checked) { if (!next.includes('linkedin')) next.push('linkedin') } else { next = next.filter(s => s !== 'linkedin') } field.onChange(next) }} disabled={isLoading || isSaving} /> )} />
{errors.jobspySites &&

{errors.jobspySites.message}

}
Select which sites JobSpy should scrape.
Effective: {(sites.effective || []).join(', ') || "None"} Default: {(sites.default || []).join(', ')}
( { const value = parseInt(event.target.value, 10) if (Number.isNaN(value)) { field.onChange(null) } else { field.onChange(Math.min(1000, Math.max(1, value))) } }, }} disabled={isLoading || isSaving} error={errors.jobspyResultsWanted?.message as string | undefined} helper={`Number of results to fetch per term per site. Default: ${resultsWanted.default}. Max 1000.`} current={`Effective: ${resultsWanted.effective} | Default: ${resultsWanted.default}`} /> )} /> ( { const value = parseInt(event.target.value, 10) if (Number.isNaN(value)) { field.onChange(null) } else { field.onChange(Math.min(720, Math.max(1, value))) } }, }} disabled={isLoading || isSaving} error={errors.jobspyHoursOld?.message as string | undefined} helper={`Max age of jobs in hours (e.g. 72 for 3 days). Default: ${hoursOld.default}. Max 720.`} current={`Effective: ${hoursOld.effective}h | Default: ${hoursOld.default}h`} /> )} />
( field.onChange(!!checked)} disabled={isLoading || isSaving} /> )} />

If enabled, JobSpy will make extra requests to fetch full descriptions. Slower but better data.

Effective: {linkedinFetchDescription.effective ? "Yes" : "No"} Default: {linkedinFetchDescription.default ? "Yes" : "No"}
) }