"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;