"use client"; import React from "react"; function MainComponent() { const [formData, setFormData] = useState({ propertyType: "", pestType: "", frequency: "", address: "", }); const [price, setPrice] = useState(null); const [monthlyPrice, setMonthlyPrice] = useState(null); const [initialFee, setInitialFee] = useState(null); const [phoneNumber, setPhoneNumber] = useState(""); const [showDiscount, setShowDiscount] = useState(false); const [discountSubmitted, setDiscountSubmitted] = useState(false); const [addressSuggestions, setAddressSuggestions] = useState([]); const [addressInputValue, setAddressInputValue] = useState(""); const [isLoadingAddresses, setIsLoadingAddresses] = useState(false); const [showShareModal, setShowShareModal] = useState(false); const [quoteUrl, setQuoteUrl] = useState(""); const [quoteDescription, setQuoteDescription] = useState(""); const [isMapsLoaded, setIsMapsLoaded] = useState(false); const [selectedLocation, setSelectedLocation] = useState(null); const pestOptions = [ { value: "general", label: "General Pest Control", basePrice: 150 }, { value: "termites", label: "Termite Treatment", basePrice: 300 }, { value: "rodents", label: "Rodent Control", basePrice: 699 }, { value: "mosquitoes", label: "Mosquito Treatment", basePrice: 175 }, { value: "bedbugs", label: "Bed Bug Treatment", basePrice: 400 }, ]; const frequencyOptions = [ { value: "oneTime", label: "One-time Service", multiplier: 1 }, { value: "monthlyBilling", label: "Quarterly Service with Monthly Billing", multiplier: 0.85, }, { value: "quarterly", label: "Quarterly Service (Billed Quarterly)", multiplier: 0.9, }, ]; const POST_FALLS_ID_COORDS = { lat: 47.7127, lng: -116.9507, }; const calculatePrice = useCallback(() => { const { propertyType, pestType, frequency, address } = formData; if ( !propertyType || !pestType || !frequency || !address || !isAddressInServiceArea(address) ) { setPrice(null); setMonthlyPrice(null); setInitialFee(null); return; } if (frequency === "monthlyBilling") { let initialServiceFee = pestType === "rodents" ? 347 : 125; let monthlyRate = 41; const addressLower = address.toLowerCase(); if ( addressLower.includes("athol") || addressLower.includes("spirit lake") ) { initialServiceFee *= 1.15; monthlyRate *= 1.15; } setInitialFee(Math.round(initialServiceFee)); setMonthlyPrice(Math.round(monthlyRate)); setPrice(null); return; } const selectedPest = pestOptions.find((p) => p.value === pestType); let basePrice = selectedPest.basePrice; if (propertyType === "commercial") { basePrice *= 1.5; } const selectedFrequency = frequencyOptions.find( (f) => f.value === frequency ); let finalPrice = basePrice * selectedFrequency.multiplier; const addressLower = address.toLowerCase(); if ( addressLower.includes("athol") || addressLower.includes("spirit lake") ) { finalPrice *= 1.15; } setPrice(Math.round(finalPrice)); setMonthlyPrice(null); setInitialFee(null); }, [formData]); useEffect(() => { calculatePrice(); }, [formData, calculatePrice]); useEffect(() => { if ( !window.google && !document.querySelector('script[src*="maps.googleapis.com"]') ) { const script = document.createElement("script"); script.src = `https://maps.googleapis.com/maps/api/js?key=AIzaSyCC2zLeJZplWcswZAPFMn1fD839BQSeHXE&libraries=places`; script.async = true; script.defer = true; script.onload = () => { setIsMapsLoaded(true); }; document.head.appendChild(script); } else if (window.google) { setIsMapsLoaded(true); } }, []); useEffect(() => { if (isMapsLoaded && selectedLocation) { const mapContainer = document.getElementById("map"); if (mapContainer) { const map = new window.google.maps.Map(mapContainer, { center: selectedLocation, zoom: 15, mapTypeControl: false, streetViewControl: false, fullscreenControl: false, }); new window.google.maps.Marker({ position: selectedLocation, map: map, animation: window.google.maps.Animation.DROP, }); setTimeout(() => { map.setCenter(selectedLocation); }, 100); } } }, [isMapsLoaded, selectedLocation]); const handleInputChange = (e) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value, })); }; const formatPhoneNumber = (value) => { if (!value) return value; const phoneNumber = value.replace(/[^\d]/g, ""); const phoneNumberLength = phoneNumber.length; if (phoneNumberLength < 4) return phoneNumber; if (phoneNumberLength < 7) { return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice(3)}`; } return `(${phoneNumber.slice(0, 3)}) ${phoneNumber.slice( 3, 6 )}-${phoneNumber.slice(6, 10)}`; }; const handlePhoneChange = (e) => { const formattedPhoneNumber = formatPhoneNumber(e.target.value); setPhoneNumber(formattedPhoneNumber); }; const handlePhoneSubmit = (e) => { e.preventDefault(); if (phoneNumber.replace(/\D/g, "").length >= 10) { setShowDiscount(true); setDiscountSubmitted(true); } }; const isAllFieldsExceptAddressFilled = useCallback(() => { const { propertyType, squareFootage, pestType, frequency, address } = formData; return propertyType && squareFootage && pestType && frequency && !address; }, [formData]); const handleAddressInputChange = async (e) => { const value = e.target.value; setAddressInputValue(value); if (value.length > 2) { setIsLoadingAddresses(true); try { const response = await fetch( `/integrations/google-place-autocomplete/autocomplete/json?input=${encodeURIComponent( value )}&radius=40000&location=${POST_FALLS_ID_COORDS.lat},${ POST_FALLS_ID_COORDS.lng }` ); if (!response.ok) { throw new Error("Failed to fetch address suggestions"); } const data = await response.json(); setAddressSuggestions(data.predictions); } catch (error) { console.error("Error fetching address suggestions:", error); } finally { setIsLoadingAddresses(false); } } else { setAddressSuggestions([]); } }; const handleAddressSelect = (address) => { setFormData((prev) => ({ ...prev, address: address.description })); setAddressInputValue(address.description); setAddressSuggestions([]); }; const SERVICE_AREAS = [ "Post Falls", "Coeur d'Alene", "Hayden", "Rathdrum", "Spokane", "Spokane Valley", "Liberty Lake", "Dalton Gardens", "Hauser", "Spirit Lake", "Athol", "Hayden Lake", ]; const isAddressInServiceArea = (address) => { if (!address) return false; return SERVICE_AREAS.some((city) => address.toLowerCase().includes(city.toLowerCase()) ); }; const handleSMSClick = () => { let message = "Hi, I'd like to schedule pest control service."; if (formData.propertyType && formData.pestType) { const pestType = pestOptions.find( (p) => p.value === formData.pestType )?.label; message += ` I need ${pestType} for my ${formData.propertyType} property.`; } if (formData.address) { message += ` My address is: ${formData.address}`; } if (monthlyPrice !== null) { message += `. Quote: $${monthlyPrice}/month with $${initialFee} initial service fee`; } else if (price !== null) { message += `. Quote: $${price}`; } if (showDiscount) { message += `. Discount code SAVE10OFF will be auto-applied to your service.`; } const phoneNumber = "12084016122"; // For iOS, we'll create a simple message without special characters const simplifiedMessage = message.replace(/[^\w\s]/g, ""); // Create both links and try them in order const link1 = `sms:${phoneNumber}&body=${encodeURIComponent(message)}`; const link2 = `sms:${phoneNumber}?body=${encodeURIComponent(message)}`; const link3 = `sms:${phoneNumber};body=${simplifiedMessage}`; // Try each link in succession const tryLink = (link) => { const a = document.createElement("a"); a.href = link; a.style.display = "none"; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); }, 100); }; // Try each format tryLink(link1); setTimeout(() => tryLink(link2), 100); setTimeout(() => tryLink(link3), 200); }; return (

Pest Control Pricing Calculator

Get an instant quote for your pest control needs

{isLoadingAddresses && (
)} {addressSuggestions.length > 0 && (
    {addressSuggestions.map((suggestion) => (
  • handleAddressSelect(suggestion)} className="px-4 py-2 hover:bg-green-100 cursor-pointer text-sm text-black font-inter" > {suggestion.description}
  • ))}
)} {formData.address && !isAddressInServiceArea(formData.address) && (

Sorry, we currently don't service this area. Please select an address in one of our service areas.

)}

We service the following areas:

{SERVICE_AREAS.join(", ")}

Please enter your property details below

{(price !== null || monthlyPrice !== null) && isAddressInServiceArea(formData.address) && (

Estimated Price

{monthlyPrice !== null && ( <>

${monthlyPrice}/month

Initial service fee: ${initialFee}

Includes quarterly service with warranty between visits

)} {price !== null && (

${price}

)}
{!discountSubmitted && (

Enter your phone number to unlock a special discount code!

)} {showDiscount && (

Your Discount Code:

SAVE10OFF

Send an SMS to schedule and your discount code will be automatically applied!

)}
)}
{showShareModal && ( setShowShareModal(false)} title="Share Quote" url={quoteUrl} description={quoteDescription} /> )}
); } export default MainComponent;