2026-01-21 19:47:11 +00:00

78 lines
3.2 KiB
TypeScript

import React from "react"
import { useFormContext, Controller } from "react-hook-form"
import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
import { Separator } from "@/components/ui/separator"
import { UpdateSettingsInput } from "@shared/settings-schema"
import type { SearchTermsValues } from "@client/pages/settings/types"
type SearchTermsSectionProps = {
values: SearchTermsValues
isLoading: boolean
isSaving: boolean
}
export const SearchTermsSection: React.FC<SearchTermsSectionProps> = ({
values,
isLoading,
isSaving,
}) => {
const { default: defaultSearchTerms, effective: effectiveSearchTerms } = values
const { control, formState: { errors } } = useFormContext<UpdateSettingsInput>()
return (
<AccordionItem value="search-terms" className="border rounded-lg px-4">
<AccordionTrigger className="hover:no-underline py-4">
<span className="text-base font-semibold">Search Terms</span>
</AccordionTrigger>
<AccordionContent className="pb-4">
<div className="space-y-4">
<div className="space-y-2">
<div className="text-sm font-medium">Global search terms</div>
<Controller
name="searchTerms"
control={control}
render={({ field }) => (
<textarea
className="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
value={field.value ? field.value.join('\n') : (defaultSearchTerms ?? []).join('\n')}
onChange={(event) => {
const text = event.target.value
const terms = text.split('\n')
field.onChange(terms)
}}
onBlur={() => {
if (field.value) {
field.onChange(field.value.map(t => t.trim()).filter(Boolean))
}
}}
placeholder="e.g. web developer"
disabled={isLoading || isSaving}
rows={5}
/>
)}
/>
{errors.searchTerms && <p className="text-xs text-destructive">{errors.searchTerms.message}</p>}
<div className="text-xs text-muted-foreground">
One term per line. Applies to UKVisaJobs and other supported extractors.
</div>
</div>
<Separator />
<div className="grid gap-2 text-sm sm:grid-cols-2">
<div>
<div className="text-xs text-muted-foreground">Effective</div>
<div className="break-words font-mono text-xs">{(effectiveSearchTerms || []).join(', ') || "—"}</div>
</div>
<div>
<div className="text-xs text-muted-foreground">Default (env)</div>
<div className="break-words font-mono text-xs">{(defaultSearchTerms || []).join(', ') || "—"}</div>
</div>
</div>
</div>
</AccordionContent>
</AccordionItem>
)
}