I’m making a custom customer churn survey component in React with Tailwind as my styling library:
const CustomerSurvey = ({ setOpen } : CustomerSurveyProps) => {
const [selectedReasons, setSelectedReasons] = useState<string[]>([]);
const [otherReason, setOtherReason] = useState("");
const handleReasonChange = (reason: string) => {
const isSelected = selectedReasons.includes(reason);
if (isSelected) {
setSelectedReasons(selectedReasons.filter((r) => r !== reason));
} else {
setSelectedReasons([...selectedReasons, reason]);
}
};
const handleOtherReasonChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
const value = event.target.value;
setOtherReason(value);
console.log("Other reason:", value);
};
const customerChurnReasonMutation = useMutation({
mutationFn: (reason: object) => {
return axios.post(
backendUrl + "/customer-churn",
reason
);
},
});
const handleSubmitBody = async () => {
try {
// Create a JSON object from selectedReasons and otherReason
const surveyData = {
selectedReasons,
others: selectedReasons.includes("Other") ? otherReason : "",
};
const { data, error } = await supabase.auth.getUser();
if (error) {
throw error;
}
const body = {
user_id: data.user.id,
user_email: data.user.email,
reason: surveyData,
};
await customerChurnReasonMutation.mutateAsync(body);
} catch (e) {
console.error(e);
}
};
return (
<>
<h2 className="text-xl font-bold mb-4">Let us know where we can improve on!</h2>
<div className="mb-6">
<p className="mb-2">We're sorry to see you go. What's your reason for unsubscribing?</p>
<div className="space-y-2">
<div
className={`p-2 border rounded cursor-pointer ${
selectedReasons.includes("I no longer need the product") ? "bg-gray-200" : ""
}`}
onClick={() => handleReasonChange("I no longer need the product")}
>
I no longer need the product
</div>
<div
className={`p-2 border rounded cursor-pointer ${
selectedReasons.includes("I found a better product") ? "bg-gray-200" : ""
}`}
onClick={() => handleReasonChange("I found a better product")}
>
I found a better product
</div>
<div
className={`p-2 border rounded cursor-pointer ${
selectedReasons.includes("I found the product too difficult to use") ? "bg-gray-200" : ""
}`}
onClick={() => handleReasonChange("I found the product too difficult to use")}
>
I found the product too difficult to use
</div>
<div
className={`p-2 border rounded cursor-pointer ${
selectedReasons.includes("Price is too high") ? "bg-gray-200" : ""
}`}
onClick={() => handleReasonChange("Price is too high")}
>
Price is too high
</div>
<div
className={`p-2 border rounded cursor-pointer ${
selectedReasons.includes("Other") ? "bg-gray-200" : ""
}`}
onClick={() => handleReasonChange("Other")}
>
Other
</div>
<div className={`mt-2 transition-all duration-300 ease-in-out ${
selectedReasons.includes("Other") ? "opacity-100 max-h-40" : "opacity-0 max-h-0"
}`}>
<textarea
className="w-full p-2 border rounded"
placeholder="Please provide more details"
value={otherReason}
onChange={handleOtherReasonChange}
/>
</div>
</div>
</div>
<button
type="button"
className="inline-flex w-full cursor-pointer justify-center rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 bg-indigo-600 hover:bg-indigo-500 focus-visible:outline-indigo-600"
onClick={handleSubmitBody}
>
Deactivate Subscription
</button>
</>
);
};
I explicitly put cursor-pointer
on the <button>
tag but it’s not showing and not making the button clickable. It only shows when “Other” is selected among the option pool – thus the button is also only clickable when “Other” is selected.
What seems to be the issue here?