Files
static/upsell.html
T
Your Name 97b1d256ea u
2026-04-11 06:59:52 -03:00

429 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Your Plan</title>
<style>
body {
font-family: "Inter", "Segoe UI", Arial, sans-serif;
background-color: #f4f5f7;
color: #333;
margin: 0;
padding: 32px 16px;
}
.page-title {
text-align: center;
color: #262626;
font-size: 1.45em;
font-weight: 700;
margin-bottom: 6px;
}
.page-subtitle {
text-align: center;
font-size: 0.82em;
color: #999;
margin-bottom: 32px;
letter-spacing: 0.01em;
}
.plans-row {
display: flex;
flex-wrap: wrap;
gap: 18px;
justify-content: center;
align-items: flex-start;
}
.plan-card {
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 14px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
padding: 26px 22px 20px;
width: 200px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
transition:
box-shadow 0.2s,
border-color 0.2s,
transform 0.2s;
}
.plan-card:hover {
box-shadow: 0 6px 22px rgba(0, 0, 0, 0.11);
transform: scale(1.03);
}
.plan-card.current {
border-color: #875a7b;
box-shadow:
0 0 0 3px rgba(135, 90, 123, 0.18),
0 4px 16px rgba(135, 90, 123, 0.12);
}
.plan-name {
font-size: 1.05em;
font-weight: 700;
color: #262626;
margin-bottom: 14px;
letter-spacing: 0.02em;
text-transform: uppercase;
}
.plan-price {
font-size: 1.55em;
font-weight: 800;
color: #875a7b;
line-height: 1.1;
margin-bottom: 2px;
}
.plan-price-period {
font-size: 0.75em;
color: #aaa;
margin-bottom: 14px;
}
.plan-tagline {
font-size: 0.8em;
color: #666;
font-style: italic;
margin-bottom: 16px;
line-height: 1.5;
min-height: 52px;
display: flex;
align-items: center;
justify-content: center;
}
.plan-btn {
background-color: #875a7b;
color: #fff;
border: none;
border-radius: 7px;
padding: 9px 0;
font-size: 0.88em;
font-weight: 600;
cursor: pointer;
width: 100%;
margin-bottom: 18px;
transition:
background-color 0.2s,
transform 0.1s;
letter-spacing: 0.01em;
}
.plan-btn:hover:not(:disabled) {
background-color: #744e6a;
transform: translateY(-1px);
}
.plan-btn:disabled {
background-color: #bdbdbd;
color: #fff;
cursor: not-allowed;
transform: none;
}
.plan-btn.is-current-plan:disabled {
background-color: #6d9f71;
}
.plan-features {
list-style: none;
padding: 0;
margin: 0;
width: 100%;
text-align: left;
}
.plan-features li {
font-size: 0.78em;
color: #555;
padding: 5px 0 5px 18px;
border-top: 1px solid #f2f2f2;
position: relative;
line-height: 1.4;
}
.plan-features li:first-child {
border-top: none;
}
.plan-features li::before {
content: "";
position: absolute;
left: 0;
color: #875a7b;
font-weight: 700;
}
.plan-guarantee {
font-size: 0.68em;
color: #bbb;
margin-top: 14px;
font-style: italic;
min-height: 18px;
}
.footer-uuid {
text-align: center;
font-size: 0.75em;
color: #ccc;
margin-top: 40px;
user-select: all;
}
</style>
</head>
<body>
<div class="page-title">Your Plan, Your Timing: Upgrade Anytime</div>
<div class="page-subtitle">
Get <b>instant access</b> to all upgraded features, including for
your current contract period, while the additional time is
<b>added</b> to your existing term.
</div>
<div class="plans-row" id="plansRow">
<!-- ── Trial ─────────────────────────────────────────────────── -->
<div class="plan-card" id="card-trial">
<div class="plan-name">Trial</div>
<div class="plan-price">4 weeks free</div>
<div class="plan-price-period">&nbsp;</div>
<div class="plan-tagline">
"I want to see what ODOO can do for my company."
</div>
<button
class="plan-btn is-current-plan"
id="btn-trial"
disabled
>
Your Plan
</button>
<ul class="plan-features">
<li>ODOO CE hosting</li>
<li>0 Backup Slots</li>
<li>No Domain Mapping</li>
<li>No module installation</li>
</ul>
<div class="plan-guarantee">&nbsp;</div>
</div>
<!-- ── Side Hustle ───────────────────────────────────────────── -->
<div class="plan-card" id="card-sidehustle">
<div class="plan-name">Side Hustle</div>
<div class="plan-price">$214.00</div>
<div class="plan-price-period">/ year</div>
<div class="plan-tagline">
"ODOO Standard .. that is all my business needs"
</div>
<button class="plan-btn" id="btn-sidehustle">Buy Now</button>
<ul class="plan-features">
<li>ODOO CE hosting</li>
<li>1 Backup Slot</li>
<li>1 Domain Mapping, SSL Cert</li>
<li>No module installation</li>
</ul>
<div class="plan-guarantee">
Get <b>instant access</b> to all upgraded features,
including for your current contract period, while the
additional time is <b>added</b> to your existing term.
</div>
</div>
<!-- ── On the Rise ───────────────────────────────────────────── -->
<div class="plan-card" id="card-ontherise">
<div class="plan-name">On the Rise</div>
<div class="plan-price">$395.00</div>
<div class="plan-price-period">/ year</div>
<div class="plan-tagline">
"I need some modules and professional reports"
</div>
<button class="plan-btn" id="btn-ontherise">Buy Now</button>
<ul class="plan-features">
<li>ODOO CE hosting</li>
<li>4 Backup Slots</li>
<li>3 Domain Mappings, SSL Cert</li>
<li>Module installation via git</li>
</ul>
<div class="plan-guarantee">
Get <b>instant access</b> to all upgraded features,
including for your current contract period, while the
additional time is <b>added</b> to your existing term.
</div>
</div>
<!-- ── Powerhouse ────────────────────────────────────────────── -->
<div class="plan-card" id="card-powerhouse">
<div class="plan-name">Powerhouse</div>
<div class="plan-price">$595.00</div>
<div class="plan-price-period">/ year</div>
<div class="plan-tagline">
"ODOO Enterprise is a must have!"
</div>
<button class="plan-btn" id="btn-powerhouse">Buy Now</button>
<ul class="plan-features">
<li>All of On the Rise</li>
<li>ODOO Enterprise Ready</li>
<li>2 Workers</li>
</ul>
<div class="plan-guarantee">
Get <b>instant access</b> to all upgraded features,
including for your current contract period, while the
additional time is <b>added</b> to your existing term.
</div>
</div>
</div>
<div class="footer-uuid">UUID: <span id="uuidText"></span></div>
<script>
// ── Webhooks ─────────────────────────────────────────────────────────────
const getContract_Webhook =
"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/0c8536be-d175-4740-8e78-123159193b23";
const buy_webhook =
"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/2366cc41-bfd9-41c0-b9b4-bea1e60726f1";
// ── Plan hierarchy (index = tier, lower = cheaper) ────────────────────────
const PLAN_ORDER = [
"Trial",
"Side Hustle",
"On the Rise",
"Powerhouse",
];
const PLAN_META = {
Trial: {
cardId: "card-trial",
btnId: "btn-trial",
productId: null,
},
"Side Hustle": {
cardId: "card-sidehustle",
btnId: "btn-sidehustle",
productId: "sidehustle",
},
"On the Rise": {
cardId: "card-ontherise",
btnId: "btn-ontherise",
productId: "ontherise",
},
Powerhouse: {
cardId: "card-powerhouse",
btnId: "btn-powerhouse",
productId: "powerhouse",
},
};
// ── UUID from URL ─────────────────────────────────────────────────────────
const params = new URLSearchParams(window.location.search);
const uuid = params.get("uuid") || "";
document.getElementById("uuidText").textContent = uuid || "";
// ── Buy handler ───────────────────────────────────────────────────────────
async function buyProduct(productId) {
if (!uuid) {
alert("Missing uuid parameter in URL.");
return;
}
try {
const res = await fetch(buy_webhook, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ uuid, product_id: productId }),
});
if (!res.ok) throw new Error("HTTP " + res.status);
document.body.innerHTML = `
<div style="text-align:center;padding:80px 20px;background:#fff;border-radius:14px;
max-width:560px;margin:60px auto;box-shadow:0 4px 20px rgba(0,0,0,0.1);
font-family:'Inter','Segoe UI',Arial,sans-serif;">
<div style="font-size:3em;margin-bottom:16px;">&#x2705;</div>
<h2 style="color:#262626;font-weight:700;margin-bottom:10px;">Request sent!</h2>
<p style="color:#777;line-height:1.6;">
Please check your email for the payment link and confirmation.<br>
New features will be active as soon as the payment is complete.
</p>
</div>`;
} catch (err) {
console.error(err);
alert(
"Something went wrong. Please try again or contact support.",
);
}
}
// ── Wire buy buttons ──────────────────────────────────────────────────────
document
.getElementById("btn-sidehustle")
.addEventListener("click", () => buyProduct("sidehustle"));
document
.getElementById("btn-ontherise")
.addEventListener("click", () => buyProduct("ontherise"));
document
.getElementById("btn-powerhouse")
.addEventListener("click", () => buyProduct("powerhouse"));
// ── Apply current-plan state ──────────────────────────────────────────────
function applyPlanState(contractName, expires) {
const currentIdx = PLAN_ORDER.indexOf(contractName);
if (currentIdx === -1) return; // unknown plan leave defaults
const expiresLabel = expires ? "✅ " + expires : "✅";
PLAN_ORDER.forEach(function (plan, idx) {
var meta = PLAN_META[plan];
if (!meta) return;
var btn = document.getElementById(meta.btnId);
var card = document.getElementById(meta.cardId);
if (!btn || !card) return;
if (idx === currentIdx) {
// Current plan
card.classList.add("current");
btn.textContent = expiresLabel;
btn.disabled = true;
btn.classList.add("is-current-plan");
} else if (idx < currentIdx) {
// Lower tier no downgrade
btn.textContent = expiresLabel;
btn.disabled = true;
btn.classList.remove("is-current-plan");
}
// Higher tiers: leave as "Buy Now" / "Contact Us" (enabled)
});
}
// ── Load contract from webhook ────────────────────────────────────────────
async function loadContract() {
if (!uuid) return;
try {
const res = await fetch(getContract_Webhook, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ uuid }),
});
if (!res.ok) throw new Error("HTTP " + res.status);
const payload = await res.json();
// Webhook returns: [{ "expires": "YYYY-MM-DD", "contractName": "Trial" }]
const record = Array.isArray(payload)
? payload[0]
: payload;
if (record && record.contractName) {
applyPlanState(record.contractName, record.expires);
}
} catch (err) {
console.error("Could not load contract data:", err);
// Graceful degradation: page remains usable with default button states
}
}
loadContract();
</script>
</body>
</html>