<?php
/**
* Website Audit Funnel
*/
add_shortcode( 'code_snippets_export_5', function () {
ob_start();
?>
<div id="website-funnel-audit-container"></div>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
const {useState} = React;
const WebsiteFunnelAudit = () => {
const [currentStep, setCurrentStep] = useState(0);
const [answers, setAnswers] = useState({});
const [score, setScore] = useState(0);
const [category, setCategory] = useState("");
const [userInfo, setUserInfo] = useState({
name: "",
email: "",
subscribeNewsletter: false
});
const questions = [
{
id: 'cta',
question: "Does your website have clear calls-to-action (CTAs) on every page?",
options: [
{ value: 3, label: "Yes, each page has a clear primary CTA that guides visitors to the next step" },
{ value: 2, label: "Some pages have CTAs, but they're not always clear or consistent" },
{ value: 0, label: "No, we don't have many CTAs or they're hard to find" }
]
},
{
id: 'load_time',
question: "How fast does your website load on mobile devices?",
options: [
{ value: 3, label: "Under 2 seconds (fast)" },
{ value: 2, label: "2-4 seconds (average)" },
{ value: 0, label: "More than 4 seconds (slow)" }
]
},
{
id: 'mobile',
question: "Is your website fully optimized for mobile devices?",
options: [
{ value: 3, label: "Yes, it looks great and functions perfectly on all devices" },
{ value: 1, label: "It's somewhat responsive but has some issues on mobile" },
{ value: 0, label: "No, it's primarily designed for desktop users" }
]
},
{
id: 'value_prop',
question: "Is your unique value proposition clearly stated on your homepage?",
options: [
{ value: 3, label: "Yes, visitors immediately understand what we offer and why it matters" },
{ value: 1, label: "It's mentioned but could be clearer or more prominent" },
{ value: 0, label: "No, visitors would struggle to understand what makes us special" }
]
},
{
id: 'lead_capture',
question: "Do you have lead capture forms or email opt-ins strategically placed on your site?",
options: [
{ value: 3, label: "Yes, with targeted lead magnets relevant to different visitor needs" },
{ value: 1, label: "We have a basic newsletter signup but nothing specifically targeted" },
{ value: 0, label: "No lead capture forms or they're poorly implemented" }
]
},
{
id: 'user_path',
question: "Does your website have a clear user path that guides visitors toward conversion?",
options: [
{ value: 3, label: "Yes, we've mapped out specific journeys for different visitor types" },
{ value: 1, label: "There's a basic path but it's not always clear where to go next" },
{ value: 0, label: "No, visitors likely feel lost or overwhelmed by options" }
]
},
{
id: 'social_proof',
question: "Does your website showcase testimonials, reviews, or other social proof?",
options: [
{ value: 3, label: "Yes, we display targeted testimonials relevant to different services/pages" },
{ value: 1, label: "We have some testimonials but they're not prominently featured" },
{ value: 0, label: "No social proof or very limited testimonials" }
]
},
{
id: 'analytics',
question: "Are you actively tracking conversion metrics and user behavior on your website?",
options: [
{ value: 3, label: "Yes, we have comprehensive analytics and regularly optimize based on data" },
{ value: 1, label: "Basic tracking is set up but we don't analyze it regularly" },
{ value: 0, label: "No tracking or very limited metrics being monitored" }
]
},
{
id: 'content',
question: "Does your website content speak directly to your ideal customer's pain points?",
options: [
{ value: 3, label: "Yes, our content strategy is built around solving specific customer problems" },
{ value: 1, label: "Some content addresses pain points but it's not consistently focused" },
{ value: 0, label: "Content is mostly about us rather than customer challenges" }
]
},
{
id: 'follow_up',
question: "Do you have automated follow-up systems for website visitors who don't immediately convert?",
options: [
{ value: 3, label: "Yes, we have targeted nurture sequences based on visitor behavior" },
{ value: 1, label: "We follow up but it's the same message for everyone" },
{ value: 0, label: "No follow-up system in place" }
]
}
];
const maxPossibleScore = questions.length * 3;
const handleAnswer = (value) => {
const updatedAnswers = {...answers, [questions[currentStep].id]: value};
setAnswers(updatedAnswers);
if (currentStep < questions.length - 1) {
setCurrentStep(currentStep + 1);
} else {
// Move to user information collection step
setCurrentStep(questions.length);
}
};
const handleUserInfoSubmit = (e) => {
e.preventDefault();
// Calculate final score
const totalScore = Object.values(answers).reduce((sum, val) => sum + val, 0);
setScore(totalScore);
// Determine category
const percentage = (totalScore / maxPossibleScore) * 100;
if (percentage >= 80) {
setCategory("great");
} else if (percentage >= 40) {
setCategory("needs_improvement");
} else {
setCategory("bad");
}
// Format strengths and areas for improvement
const strengths = Object.entries(answers)
.filter(([key, value]) => value === 3)
.map(([key]) => {
const question = questions.find(q => q.id === key);
return question.question.replace(/\?$/, '');
})
.join("; ");
const improvements = Object.entries(answers)
.filter(([key, value]) => value < 2)
.map(([key]) => {
const question = questions.find(q => q.id === key);
return question.question.replace(/\?$/, '');
})
.join("; ");
// Send data to Google Sheet
const formData = new URLSearchParams();
formData.append('name', userInfo.name);
formData.append('email', userInfo.email);
formData.append('score', totalScore);
formData.append('percentage', percentage);
formData.append('category', category);
formData.append('newsletter', userInfo.subscribeNewsletter ? 'Yes' : 'No');
formData.append('strengths', strengths || 'None identified');
formData.append('improvements', improvements || 'None identified');
// Your Web App URL
const googleScriptUrl = 'https://script.google.com/macros/s/AKfycbx3Jv2lUwwj-tD3qHI82x_htnNykFCe-8hetiq1HrVBC0ZStdjwJIBhJv5T5P5wqssl/exec';
// Submit data to Google Sheet
fetch(googleScriptUrl, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData
}).catch(error => console.error('Error:', error));
// Move to results page
setCurrentStep(questions.length + 1);
};
const resetQuiz = () => {
setCurrentStep(0);
setAnswers({});
setScore(0);
setCategory("");
setUserInfo({
name: "",
email: "",
subscribeNewsletter: false
});
};
const renderUserInfoForm = () => {
return (
<div className="p-6 bg-white rounded-lg shadow-lg max-w-2xl mx-auto">
<div className="mb-6">
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-500">Final Step</span>
<span className="text-sm font-bold" style={{color: '#3e2f5b'}}>Almost done!</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5">
<div className="h-2.5 rounded-full" style={{width: `90%`, backgroundColor: '#3e2f5b'}}></div>
</div>
</div>
<h2 className="text-xl font-bold mb-6" style={{color: '#3e2f5b'}}>Before we show your results...</h2>
<form onSubmit={handleUserInfoSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">Your Name</label>
<input
type="text"
id="name"
className="w-full p-3 border border-gray-300 rounded-md"
value={userInfo.name}
onChange={(e) => setUserInfo({...userInfo, name: e.target.value})}
required
placeholder="Jane Smith"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">Your Email</label>
<input
type="email"
id="email"
className="w-full p-3 border border-gray-300 rounded-md"
value={userInfo.email}
onChange={(e) => setUserInfo({...userInfo, email: e.target.value})}
required
placeholder="jane@example.com"
/>
</div>
<div className="flex items-start mt-4">
<input
type="checkbox"
id="subscribe"
className="mt-1"
checked={userInfo.subscribeNewsletter}
onChange={(e) => setUserInfo({...userInfo, subscribeNewsletter: e.target.checked})}
/>
<label htmlFor="subscribe" className="ml-2 block text-sm text-gray-700">
Sign me up for The Wilder Shoppe newsletter for actionable tips on improving my digital presence
</label>
</div>
<div className="pt-4">
<button
type="submit"
className="w-full px-4 py-3 bg-purple-700 text-white font-bold rounded-md hover:bg-purple-800"
style={{backgroundColor: '#3e2f5b'}}
>
See My Results
</button>
</div>
<p className="text-xs text-gray-500 mt-3">
We respect your privacy and will never share your information. You can unsubscribe from our newsletter at any time.
</p>
</form>
<button
onClick={() => setCurrentStep(currentStep - 1)}
className="mt-6 px-4 py-2 rounded text-gray-600 font-medium flex items-center"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
Back to Questions
</button>
</div>
);
};
const renderResults = () => {
const percentage = Math.round((score / maxPossibleScore) * 100);
return (
<div className="p-6 bg-white rounded-lg shadow-lg max-w-2xl mx-auto">
<h2 className="text-2xl font-bold mb-4 text-center" style={{color: '#3e2f5b'}}>Hi {userInfo.name}, Your Website Funnel Score: {percentage}%</h2>
{category === "great" && (
<div className="mb-6">
<div className="flex justify-center mb-4">
<div className="w-16 h-16 rounded-full bg-green-500 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" className="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
</div>
</div>
<h3 className="text-xl font-bold text-green-600 mb-2 text-center">Looking Good, Boss!</h3>
<p className="mb-4">Your website is working hard for you! You've got the foundations of a solid conversion funnel that's probably bringing in customers while you sleep (or at least while you're busy doing literally anything else).</p>
<p className="mb-4">But let's be honest — there's always room to level up. Even the best websites need fresh eyes and new strategies to stay ahead.</p>
<div className="bg-purple-100 p-4 rounded-lg mb-4" style={{backgroundColor: 'rgba(62, 47, 91, 0.1)'}}>
<h4 className="font-bold mb-2" style={{color: '#3e2f5b'}}>Ready to take your digital presence from good to unforgettable?</h4>
<p>Join our free BROWSER tier in The Thrifty Shoppe community for resources that will help you maintain your website's momentum and stay ahead of the digital curve.</p>
<div className="mt-4">
<a href="https://thrifty-shoppe.thewildershoppe.com/product/the-browser/" className="inline-block px-4 py-2 rounded font-bold text-white" style={{backgroundColor: '#3e2f5b'}}>Join The Thrifty Shoppe (Free)</a>
</div>
{userInfo.subscribeNewsletter &&
<p className="mt-4 text-sm">
<span className="font-bold">Thank you for subscribing to our newsletter!</span> We've sent a welcome email to {userInfo.email} with your audit results and some bonus resources.
</p>
}
</div>
</div>
)}
{category === "needs_improvement" && (
<div className="mb-6">
<div className="flex justify-center mb-4">
<div className="w-16 h-16 rounded-full bg-yellow-500 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" className="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
</div>
</div>
<h3 className="text-xl font-bold text-yellow-600 mb-2 text-center">We See Potential!</h3>
<p className="mb-4">Your website has some solid elements, but it's not converting visitors into customers as effectively as it could be. You're leaving money on the table with these missed opportunities.</p>
<p className="mb-4">The good news? These are fixable problems with the right strategy and support.</p>
<div className="bg-purple-100 p-4 rounded-lg mb-4" style={{backgroundColor: 'rgba(62, 47, 91, 0.1)'}}>
<h4 className="font-bold mb-2" style={{color: '#3e2f5b'}}>Ready to transform your website into a customer-generating machine?</h4>
<p>You have two great options:</p>
<ul className="list-disc pl-5 mb-4">
<li className="mb-2">Join our BOSS tier in The Thrifty Shoppe for $24.99/month and get access to advanced resources, monthly website audits, and quarterly 1:1 strategy sessions.</li>
<li>Check out our Growth Guild service for a complete website transformation that turns browsers into buyers.</li>
</ul>
<div className="mt-4 flex flex-wrap gap-3">
<a href="https://thrifty-shoppe.thewildershoppe.com/product/the-boss/" className="inline-block px-4 py-2 rounded font-bold text-white" style={{backgroundColor: '#3e2f5b'}}>Join The BOSS Tier</a>
<a href="https://thewildershoppe.com/growth-guild-home/" className="inline-block px-4 py-2 rounded font-bold text-white" style={{backgroundColor: '#950714'}}>Explore Growth Guild</a>
</div>
{userInfo.subscribeNewsletter &&
<p className="mt-4 text-sm">
<span className="font-bold">Thank you for subscribing to our newsletter!</span> We've sent a welcome email to {userInfo.email} with your audit results and some exclusive resources for improving your website.
</p>
}
</div>
</div>
)}
{category === "bad" && (
<div className="mb-6">
<div className="flex justify-center mb-4">
<div className="w-16 h-16 rounded-full bg-red-500 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" className="h-10 w-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</div>
</div>
<h3 className="text-xl font-bold text-red-600 mb-2 text-center">Let's Fix This ASAP!</h3>
<p className="mb-4">We're not going to sugarcoat it — your website is likely costing you customers rather than creating them. But don't panic! Even the most broken funnels can be transformed with the right expertise.</p>
<p className="mb-4">Your website needs strategic intervention to start working for your business rather than against it.</p>
<div className="bg-purple-100 p-4 rounded-lg mb-4" style={{backgroundColor: 'rgba(62, 47, 91, 0.1)'}}>
<h4 className="font-bold mb-2" style={{color: '#3e2f5b'}}>Ready for a website that actually brings in business?</h4>
<p className="mb-4">Your situation calls for expert help. Our Growth Guild service will completely transform your website into a conversion-focused business asset that turns visitors into customers.</p>
<p className="mb-4">Let's schedule a no-obligation call to discuss how we can help you build a website that makes you money while you sleep.</p>
<div className="mt-4">
<a href="https://thewildershoppe.com/growth-guild-home/" className="inline-block px-4 py-2 rounded font-bold text-white" style={{backgroundColor: '#950714'}}>Book a Strategy Call</a>
</div>
{userInfo.subscribeNewsletter &&
<p className="mt-4 text-sm">
<span className="font-bold">Thank you for subscribing to our newsletter!</span> We've sent a welcome email to {userInfo.email} with your audit results and some critical next steps for your website.
</p>
}
</div>
</div>
)}
<div className="mt-6">
<h3 className="text-lg font-bold mb-2" style={{color: '#3e2f5b'}}>Where Your Website Shines:</h3>
<ul className="list-disc pl-5 mb-4">
{Object.entries(answers).map(([key, value]) => {
const question = questions.find(q => q.id === key);
if (value === 3) {
return <li key={key}>{question.question.replace(/\?$/, '')}</li>;
}
return null;
}).filter(Boolean)}
{!Object.values(answers).includes(3) &&
<li>We need to find your website's strengths! Let's chat about how to create some.</li>
}
</ul>
<h3 className="text-lg font-bold mb-2" style={{color: '#950714'}}>Opportunities for Improvement:</h3>
<ul className="list-disc pl-5 mb-4">
{Object.entries(answers).map(([key, value]) => {
const question = questions.find(q => q.id === key);
if (value < 2) {
return <li key={key}>{question.question.replace(/\?$/, '')}</li>;
}
return null;
}).filter(Boolean)}
{!Object.values(answers).filter(v => v < 2).length &&
<li>You're ahead of the curve! Keep up the great work.</li>
}
</ul>
</div>
<button
onClick={resetQuiz}
className="mt-6 px-4 py-2 w-full rounded font-bold text-white"
style={{backgroundColor: '#ead94c', color: '#3e2f5b'}}
>
Take the Quiz Again
</button>
</div>
);
};
const renderQuestion = () => {
const currentQuestion = questions[currentStep];
return (
<div className="p-6 bg-white rounded-lg shadow-lg max-w-2xl mx-auto">
<div className="mb-6">
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-500">Question {currentStep + 1} of {questions.length}</span>
<span className="text-sm font-bold" style={{color: '#3e2f5b'}}>{Math.round(((currentStep) / questions.length) * 100)}% complete</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5">
<div className="h-2.5 rounded-full" style={{width: `${(currentStep / questions.length) * 100}%`, backgroundColor: '#3e2f5b'}}></div>
</div>
</div>
<h2 className="text-xl font-bold mb-6" style={{color: '#3e2f5b'}}>{currentQuestion.question}</h2>
<div className="space-y-3">
{currentQuestion.options.map((option, index) => (
<button
key={index}
onClick={() => handleAnswer(option.value)}
className="w-full text-left p-4 rounded border border-gray-300 hover:border-purple-500 transition-colors"
>
{option.label}
</button>
))}
</div>
{currentStep > 0 && (
<button
onClick={() => setCurrentStep(currentStep - 1)}
className="mt-6 px-4 py-2 rounded text-gray-600 font-medium flex items-center"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
Previous Question
</button>
)}
</div>
);
};
return (
<div className="min-h-screen bg-gray-50 py-8">
<div className="max-w-4xl mx-auto px-4">
<div className="text-center mb-8">
<h1 className="text-3xl font-bold mb-2" style={{color: '#3e2f5b'}}>Is Your Website a Funnel or a Dead End?</h1>
<p className="text-gray-600 max-w-2xl mx-auto">Take this 2-minute audit to discover if your website is actively converting visitors into customers or just sitting there looking pretty (while costing you money).</p>
</div>
{currentStep < questions.length ? renderQuestion() :
currentStep === questions.length ? renderUserInfoForm() :
renderResults()}
</div>
</div>
);
};
// Render the component
const container = document.getElementById('website-funnel-audit-container');
const root = ReactDOM.createRoot(container);
root.render(<WebsiteFunnelAudit />);
</script>
<style>
/* Basic styling for the container */
#website-funnel-audit-container {
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
/* Utility classes used in the component */
.min-h-screen { min-height: 100vh; }
.bg-gray-50 { background-color: #fafafa; }
.py-8 { padding-top: 2rem; padding-bottom: 2rem; }
.max-w-4xl { max-width: 56rem; }
.mx-auto { margin-left: auto; margin-right: auto; }
.px-4 { padding-left: 1rem; padding-right: 1rem; }
.text-center { text-align: center; }
.mb-8 { margin-bottom: 2rem; }
.text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
.font-bold { font-weight: 700; }
.mb-2 { margin-bottom: 0.5rem; }
.text-gray-600 { color: #4b5563; }
.max-w-2xl { max-width: 42rem; }
.p-6 { padding: 1.5rem; }
.bg-white { background-color: #ffffff; }
.rounded-lg { border-radius: 0.5rem; }
.shadow-lg { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); }
.mb-6 { margin-bottom: 1.5rem; }
.flex { display: flex; }
.justify-between { justify-content: space-between; }
.items-center { align-items: center; }
.text-sm { font-size: 0.875rem; line-height: 1.25rem; }
.text-gray-500 { color: #6b7280; }
.w-full { width: 100%; }
.bg-gray-200 { background-color: #e5e7eb; }
.rounded-full { border-radius: 9999px; }
.h-2\.5 { height: 0.625rem; }
.text-xl { font-size: 1.25rem; line-height: 1.75rem; }
.space-y-3 > * + * { margin-top: 0.75rem; }
.text-left { text-align: left; }
.p-4 { padding: 1rem; }
.rounded { border-radius: 0.25rem; }
.border { border-width: 1px; }
.border-gray-300 { border-color: #d1d1d1; }
.transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
.mt-6 { margin-top: 1.5rem; }
.text-gray-600 { color: #4b5563; }
.medium { font-weight: 500; }
.h-4 { height: 1rem; }
.w-4 { width: 1rem; }
.mr-1 { margin-right: 0.25rem; }
.space-y-4 > * + * { margin-top: 1rem; }
.block { display: block; }
.font-medium { font-weight: 500; }
.text-gray-700 { color: #374151; }
.mb-1 { margin-bottom: 0.25rem; }
.border-gray-300 { border-color: #d1d1d1; }
.rounded-md { border-radius: 0.375rem; }
.items-start { align-items: flex-start; }
.mt-4 { margin-top: 1rem; }
.mt-1 { margin-top: 0.25rem; }
.ml-2 { margin-left: 0.5rem; }
.pt-4 { padding-top: 1rem; }
.text-white { color: #ffffff; }
.rounded-md { border-radius: 0.375rem; }
.text-xs { font-size: 0.75rem; line-height: 1rem; }
.mt-3 { margin-top: 0.75rem; }
.text-2xl { font-size: 1.5rem; line-height: 2rem; }
.justify-center { justify-content: center; }
.w-16 { width: 4rem; }
.h-16 { height: 4rem; }
.bg-green-500 { background-color: #22c55e;
.bg-green-500 { background-color: #22c55e; }
.h-10 { height: 2.5rem; }
.w-10 { width: 2.5rem; }
.text-green-600 { color: #16a34a; }
.bg-purple-100 { background-color: #f3e8ff; }
.mb-4 { margin-bottom: 1rem; }
.list-disc { list-style-type: disc; }
.pl-5 { padding-left: 1.25rem; }
.gap-3 { gap: 0.75rem; }
.flex-wrap { flex-wrap: wrap; }
.inline-block { display: inline-block; }
.bg-yellow-500 { background-color: #eab308; }
.text-yellow-600 { color: #ca8a04; }
.bg-red-500 { background-color: #ef4444; }
.text-red-600 { color: #dc2626; }
.mt-6 { margin-top: 1.5rem; }
.text-lg { font-size: 1.125rem; line-height: 1.75rem; }
.hover\:border-purple-500:hover { border-color: #8b5cf6; }
.hover\:bg-purple-800:hover { background-color: #5b21b6; }
</style>
<?php
return ob_get_clean();
} );