import { useEffect, useState } from "react"; import { useForm } from "@tanstack/react-form"; import { Search } from "lucide-react"; import { createFormValidationErrors, getFieldError, getFormError, shouldValidateFieldOnChange, } from "@/client/lib/forms"; import type { BacklinksSearchState } from "./backlinksPageTypes"; import { resolveBacklinksSearchScope } from "./backlinksSearchScope"; type SearchDraft = Pick; function getBacklinksValidationErrors( value: SearchDraft, shouldValidateUntouchedField: boolean, canOpenSearch?: (value: SearchDraft) => boolean, tabLimit?: number, ) { if (!value.target.trim()) { if (!shouldValidateUntouchedField) { return null; } return createFormValidationErrors({ fields: { target: "Enter a domain or URL to analyze.", }, }); } const normalizedValue = { ...value, target: value.target.trim(), }; if (canOpenSearch && !canOpenSearch(normalizedValue)) { return createFormValidationErrors({ fields: { target: `Close a tab to open more searches (max ${tabLimit ?? 8}).`, }, }); } return null; } export function BacklinksSearchCard({ canOpenSearch, errorMessage, initialValues, onSubmit, tabLimit, }: { canOpenSearch?: (values: SearchDraft) => boolean; errorMessage: string | null; initialValues: SearchDraft; onSubmit: (values: SearchDraft) => void; tabLimit?: number; }) { const [userSelectedScope, setUserSelectedScope] = useState(false); const form = useForm({ defaultValues: initialValues, validators: { onChange: ({ formApi, value }) => getBacklinksValidationErrors( value, shouldValidateFieldOnChange(formApi, "target"), canOpenSearch, tabLimit, ), onSubmit: ({ value }) => getBacklinksValidationErrors(value, true, canOpenSearch, tabLimit), }, onSubmit: ({ value }) => { const target = value.target.trim(); const scope = resolveBacklinksSearchScope({ target, selectedScope: value.scope, userSelectedScope, }); onSubmit({ ...value, target, scope, }); }, }); useEffect(() => { form.reset(initialValues); setUserSelectedScope(false); }, [form, initialValues]); return (
{ event.preventDefault(); void form.handleSubmit(); }} >
{(field) => { const targetError = getFieldError(field.state.meta.errors); return ( ); }} state.isSubmitting}> {(isSubmitting) => ( )}
{(field) => { const targetError = getFieldError(field.state.meta.errors); return targetError ? (

{targetError}

) : null; }}
state.errorMap.onSubmit}> {(submitError) => { const formError = getFormError(submitError); return formError ? (

{formError}

) : null; }}
{(field) => ( <> )}
{errorMessage ? (
{errorMessage}
) : null}
); }