'use client' import { FormEvent, useMemo, useState } from 'react' import { useRouter } from 'next/navigation' import { Loader2, MapPin, Search, Send } from 'lucide-react' import { CROPS } from '@/lib/crops' import { US_STATES } from '@/lib/stateDiseaseMap' import { createFarmForUser, joinFarmByCode, requestFarmAccess, searchFarmsForAccess } from '@/src/lib/farms' import type { FarmSearchResult } from '@/src/lib/types' type Mode = 'create' | 'join' | 'request' type FarmSetupFormProps = { userId: string redirectTo?: string } function getErrorMessage(error: unknown, fallback: string) { return error instanceof Error ? error.message : fallback } export default function FarmSetupForm({ userId, redirectTo = '/' }: FarmSetupFormProps) { const router = useRouter() const cropOptions = useMemo(() => Object.keys(CROPS), []) const [mode, setMode] = useState('create') const [loading, setLoading] = useState(false) const [searching, setSearching] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(null) const [name, setName] = useState('') const [address, setAddress] = useState('') const [stateCode, setStateCode] = useState('IA') const [selectedCrops, setSelectedCrops] = useState([]) const [acreage, setAcreage] = useState('') const [lat, setLat] = useState('') const [lng, setLng] = useState('') const [joinCode, setJoinCode] = useState('') const [farmSearch, setFarmSearch] = useState('') const [farmSearchState, setFarmSearchState] = useState('IA') const [searchResults, setSearchResults] = useState([]) const [requestingFarmId, setRequestingFarmId] = useState(null) const toggleCrop = (crop: string) => { setSelectedCrops((current) => current.includes(crop) ? current.filter((item) => item !== crop) : [...current, crop] ) } const useCurrentLocation = () => { if (!navigator.geolocation) { setError('Geolocation is not available in this browser. You can enter latitude and longitude manually.') return } setError(null) navigator.geolocation.getCurrentPosition( (position) => { setLat(position.coords.latitude.toFixed(6)) setLng(position.coords.longitude.toFixed(6)) }, () => setError('Could not read your location. You can continue with address and state, or enter coordinates manually.') ) } const handleCreate = async (event: FormEvent) => { event.preventDefault() if (selectedCrops.length === 0) { setError('Select at least one crop grown on this farm.') return } setLoading(true) setError(null) try { await createFarmForUser(userId, { name, address, stateCode, crops: selectedCrops, acreage: acreage.trim() ? Number(acreage) : null, lat: lat.trim() ? Number(lat) : null, lng: lng.trim() ? Number(lng) : null, }) setSuccess('Farm created.') router.replace(redirectTo) } catch (err: unknown) { setError(getErrorMessage(err, 'Could not create this farm.')) } finally { setLoading(false) } } const handleJoin = async (event: FormEvent) => { event.preventDefault() setLoading(true) setError(null) try { await joinFarmByCode(userId, joinCode) setSuccess('Farm joined.') router.replace(redirectTo) } catch (err: unknown) { setError(getErrorMessage(err, 'That join code is invalid or expired.')) } finally { setLoading(false) } } const handleSearch = async (event: FormEvent) => { event.preventDefault() setSearching(true) setError(null) setSuccess(null) try { const results = await searchFarmsForAccess(farmSearch, farmSearchState) setSearchResults(results) if (results.length === 0) { setSuccess('No matching farms found. Check the name and state, then try again.') } } catch (err: unknown) { setError(getErrorMessage(err, 'Could not search farms.')) } finally { setSearching(false) } } const handleRequestAccess = async (farm: FarmSearchResult) => { setRequestingFarmId(farm.farmId) setError(null) setSuccess(null) try { await requestFarmAccess(userId, farm) setSuccess(`Access request sent to ${farm.name}.`) setSearchResults((current) => current.filter((item) => item.farmId !== farm.farmId)) } catch (err: unknown) { setError(getErrorMessage(err, 'Could not request access to this farm.')) } finally { setRequestingFarmId(null) } } return ( <>
{(['create', 'join', 'request'] as Mode[]).map((option) => ( ))}
{mode === 'create' ? (
setName(e.target.value)} className="field-input" />
setAddress(e.target.value)} className="field-input" />
setAcreage(e.target.value)} className="field-input" />
setLat(e.target.value)} className="field-input" />
setLng(e.target.value)} className="field-input" />
{cropOptions.map((crop) => ( ))}
{error &&

{error}

}
) : mode === 'join' ? (
setJoinCode(e.target.value.toUpperCase())} maxLength={6} required className="field-input font-mono uppercase tracking-[0.3em]" placeholder="ABC123" />
{error &&

{error}

} {success &&

{success}

}
) : (
setFarmSearch(event.target.value)} required minLength={2} maxLength={80} className="field-input" placeholder="Smith Family Farm" />
{error &&

{error}

} {success &&

{success}

}
{searchResults.length > 0 && (
{searchResults.map((farm) => (

{farm.name}

{farm.address}

{farm.stateCode}

))}
)}
)} ) }