post-completion flow: survey, referral program, review ask
- Migration 081: referral_codes, referral_uses, exit_surveys tables - API: POST /api/v1/survey, POST /api/v1/referral/check, GET /api/v1/referral/:email - Worker: completion_emails.py — sends completion + 24h follow-up (survey + referral) - Survey page: /survey/?order=X&rating=N — star rating, feedback, Google review ask - Referral: REF-FIRSTNAME codes, $25 credit per referred order, no limit - Low ratings (1-3 stars) trigger Telegram alert for admin follow-up - Cron: every 15 minutes
This commit is contained in:
parent
6b20ba7f08
commit
ad3d189b2b
6 changed files with 655 additions and 0 deletions
172
site/public/survey/index.html
Normal file
172
site/public/survey/index.html
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex">
|
||||
<title>How Did We Do? | Performance West</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<script>
|
||||
window.__PW_API = (function() {
|
||||
var h = window.location.hostname;
|
||||
if (h === "localhost" || h === "127.0.0.1") return "http://" + h + ":3001";
|
||||
if (h === "dev.performancewest.net") return "https://api.dev.performancewest.net";
|
||||
return "https://api.performancewest.net";
|
||||
})();
|
||||
</script>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: -apple-system, system-ui, sans-serif; background: #f8fafc; min-height: 100vh; display: flex; flex-direction: column; }
|
||||
.header { background: #1a2744; padding: 20px; text-align: center; }
|
||||
.header img { height: 40px; }
|
||||
.main { flex: 1; padding: 24px; max-width: 520px; margin: 0 auto; width: 100%; }
|
||||
.card { background: #fff; border: 1px solid #e2e8f0; border-radius: 12px; padding: 32px; margin-bottom: 16px; }
|
||||
h1 { font-size: 22px; color: #1a2744; margin-bottom: 8px; text-align: center; }
|
||||
.subtitle { font-size: 15px; color: #64748b; text-align: center; margin-bottom: 24px; }
|
||||
.stars { display: flex; justify-content: center; gap: 8px; margin-bottom: 24px; }
|
||||
.star { font-size: 40px; cursor: pointer; transition: transform 0.1s; opacity: 0.3; }
|
||||
.star.active { opacity: 1; }
|
||||
.star:hover { transform: scale(1.2); }
|
||||
textarea { width: 100%; padding: 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 14px; resize: vertical; min-height: 80px; font-family: inherit; }
|
||||
.btn { display: block; width: 100%; padding: 14px; background: #f97316; color: #fff; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; margin-top: 16px; }
|
||||
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.review-box { background: #f0fdf4; border: 2px solid #86efac; border-radius: 12px; padding: 24px; text-align: center; margin-top: 16px; }
|
||||
.referral-box { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 12px; padding: 20px; margin-top: 16px; }
|
||||
.referral-code { background: #fff; border: 2px dashed #3b82f6; border-radius: 8px; padding: 12px; text-align: center; margin: 12px 0; }
|
||||
.referral-code span { font-size: 24px; font-weight: 700; color: #1e3a5f; letter-spacing: 1px; }
|
||||
.footer { padding: 16px; text-align: center; font-size: 11px; color: #94a3b8; border-top: 1px solid #e2e8f0; }
|
||||
.hidden { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<img src="/images/logo.png" alt="Performance West">
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<!-- Survey form -->
|
||||
<div id="survey-form" class="card">
|
||||
<h1>How was your experience?</h1>
|
||||
<p class="subtitle">Your feedback helps us serve truckers better.</p>
|
||||
|
||||
<div class="stars" id="star-row">
|
||||
<span class="star" data-rating="1">⭐</span>
|
||||
<span class="star" data-rating="2">⭐</span>
|
||||
<span class="star" data-rating="3">⭐</span>
|
||||
<span class="star" data-rating="4">⭐</span>
|
||||
<span class="star" data-rating="5">⭐</span>
|
||||
</div>
|
||||
|
||||
<p id="rating-label" style="text-align:center;font-size:14px;color:#64748b;margin-bottom:16px"></p>
|
||||
|
||||
<label style="font-size:14px;font-weight:600;color:#374151;display:block;margin-bottom:6px">Anything you'd like us to know? <span style="color:#94a3b8">(optional)</span></label>
|
||||
<textarea id="feedback" placeholder="What went well? What could we improve?"></textarea>
|
||||
|
||||
<button type="button" id="submit-btn" class="btn" disabled>Submit Feedback</button>
|
||||
</div>
|
||||
|
||||
<!-- Thank you + review ask (shown after submit if rating >= 4) -->
|
||||
<div id="thank-you" class="hidden">
|
||||
<div class="card" style="text-align:center">
|
||||
<div style="font-size:48px;margin-bottom:12px">🙏</div>
|
||||
<h1>Thank you for your feedback!</h1>
|
||||
<p class="subtitle">We appreciate you taking the time.</p>
|
||||
</div>
|
||||
|
||||
<div id="review-ask" class="review-box hidden">
|
||||
<h3 style="font-size:16px;color:#166534;margin-bottom:8px">Glad you had a great experience!</h3>
|
||||
<p style="font-size:14px;color:#374151;margin-bottom:16px">Would you mind leaving us a quick Google review? It helps other truckers find us and takes about 30 seconds.</p>
|
||||
<a id="google-review-link" href="#" target="_blank" style="display:inline-block;padding:12px 28px;background:#059669;color:#fff;font-weight:600;border-radius:8px;text-decoration:none;font-size:15px">Leave a Google Review →</a>
|
||||
</div>
|
||||
|
||||
<div id="referral-section" class="referral-box hidden">
|
||||
<h3 style="font-size:16px;color:#1e3a5f;margin-bottom:6px">Know another trucker who needs help?</h3>
|
||||
<p style="font-size:14px;color:#1d4ed8;margin-bottom:4px">Share your referral code and earn <strong>$25 credit</strong> for each order they place.</p>
|
||||
<div class="referral-code">
|
||||
<p style="font-size:11px;color:#64748b;margin-bottom:4px">Your referral code:</p>
|
||||
<span id="referral-code-display"></span>
|
||||
</div>
|
||||
<p style="font-size:12px;color:#64748b">They enter this code at checkout. You earn $25 per order — no limit.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
Performance West Inc. · (888) 411-0383 · performancewest.net
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var API = window.__PW_API;
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var orderNumber = params.get("order") || "";
|
||||
var preRating = parseInt(params.get("rating") || "0");
|
||||
var selectedRating = 0;
|
||||
|
||||
var stars = document.querySelectorAll(".star");
|
||||
var ratingLabel = document.getElementById("rating-label");
|
||||
var submitBtn = document.getElementById("submit-btn");
|
||||
var labels = ["", "Poor", "Fair", "Good", "Great", "Excellent"];
|
||||
|
||||
function setRating(r) {
|
||||
selectedRating = r;
|
||||
stars.forEach(function(s, i) {
|
||||
s.classList.toggle("active", i < r);
|
||||
});
|
||||
ratingLabel.textContent = labels[r] || "";
|
||||
submitBtn.disabled = false;
|
||||
}
|
||||
|
||||
stars.forEach(function(s) {
|
||||
s.addEventListener("click", function() {
|
||||
setRating(parseInt(s.dataset.rating));
|
||||
});
|
||||
});
|
||||
|
||||
// Pre-select from URL param
|
||||
if (preRating >= 1 && preRating <= 5) {
|
||||
setRating(preRating);
|
||||
}
|
||||
|
||||
submitBtn.addEventListener("click", function() {
|
||||
if (!selectedRating || !orderNumber) return;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = "Submitting...";
|
||||
|
||||
fetch(API + "/api/v1/survey", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
order_number: orderNumber,
|
||||
rating: selectedRating,
|
||||
feedback: document.getElementById("feedback").value,
|
||||
would_recommend: selectedRating >= 4,
|
||||
}),
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
document.getElementById("survey-form").classList.add("hidden");
|
||||
document.getElementById("thank-you").classList.remove("hidden");
|
||||
|
||||
// Show Google review if high rating
|
||||
if (d.show_review && d.google_review_url) {
|
||||
var reviewEl = document.getElementById("review-ask");
|
||||
reviewEl.classList.remove("hidden");
|
||||
document.getElementById("google-review-link").href = d.google_review_url;
|
||||
}
|
||||
|
||||
// Show referral code
|
||||
if (d.referral_code) {
|
||||
document.getElementById("referral-section").classList.remove("hidden");
|
||||
document.getElementById("referral-code-display").textContent = d.referral_code;
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
submitBtn.textContent = "Submit Feedback";
|
||||
submitBtn.disabled = false;
|
||||
alert("Something went wrong. Please try again.");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue