Public Access
static sites for ODOO
This commit is contained in:
@@ -0,0 +1,447 @@
|
||||
<!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: 1.05em;
|
||||
color: #444;
|
||||
margin-bottom: 32px;
|
||||
letter-spacing: 0.01em;
|
||||
line-height: 1.7;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.plans-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 18px;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.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;
|
||||
position: relative;
|
||||
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);
|
||||
}
|
||||
|
||||
#card-ontherise {
|
||||
border: 3px dotted #e0e0e0;
|
||||
}
|
||||
|
||||
.plan-card.current {
|
||||
border-color: #4caf50;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(76, 175, 80, 0.2),
|
||||
0 4px 16px rgba(76, 175, 80, 0.15);
|
||||
}
|
||||
|
||||
.plan-badge {
|
||||
position: absolute;
|
||||
top: -13px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #4caf50;
|
||||
color: #fff;
|
||||
font-size: 0.68em;
|
||||
font-weight: 700;
|
||||
padding: 3px 11px;
|
||||
border-radius: 20px;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 2px 6px rgba(76, 175, 80, 0.35);
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.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: #4caf50;
|
||||
}
|
||||
|
||||
.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: auto;
|
||||
padding-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-subtitle">
|
||||
You <b>immediately</b> unlock all new features and higher limits.<br />
|
||||
Any extra time is <b>added</b> to your existing subscription.
|
||||
</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"> </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
|
||||
>
|
||||
Trial
|
||||
</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"> </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">
|
||||
Upgrade Now
|
||||
</button>
|
||||
<ul class="plan-features">
|
||||
<li>ODOO CE hosting</li>
|
||||
<li>Space for 1 Backup</li>
|
||||
<li>Connect 1 domain with SSL</li>
|
||||
<li>No module installation</li>
|
||||
<li>One Year of Sercice</li>
|
||||
</ul>
|
||||
</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">Upgrade Now</button>
|
||||
<ul class="plan-features">
|
||||
<li>ODOO CE hosting</li>
|
||||
<li>Space for 4 Backups</li>
|
||||
<li>Connect 3 domain with SSL</li>
|
||||
<li>Install custom modules</li>
|
||||
<li>One Year of Sercice</li>
|
||||
</ul>
|
||||
</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">
|
||||
Upgrade Now
|
||||
</button>
|
||||
<ul class="plan-features">
|
||||
<li>All of On the Rise</li>
|
||||
<li>ODOO Enterprise Ready</li>
|
||||
<li>2 Workers</li>
|
||||
<li>One Year of Sercice</li>
|
||||
</ul>
|
||||
</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;">✅</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 badgeLabel = 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 – green frame, badge with expiry date
|
||||
card.classList.add("current");
|
||||
var badge = document.createElement("div");
|
||||
badge.className = "plan-badge";
|
||||
badge.textContent = badgeLabel;
|
||||
card.insertBefore(badge, card.firstChild);
|
||||
// Trial is always green with no text – skip button changes
|
||||
if (plan !== "Trial") {
|
||||
btn.textContent = "Add 1 Year";
|
||||
btn.disabled = false;
|
||||
btn.classList.add("is-current-plan");
|
||||
}
|
||||
} else if (idx < currentIdx) {
|
||||
// Lower tier – hide entirely
|
||||
card.style.display = "none";
|
||||
}
|
||||
// Higher tiers: leave as "Upgrade Now" (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.contract_name) {
|
||||
applyPlanState(record.contract_name, 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>
|
||||
Reference in New Issue
Block a user