Public Access
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a54dc22bd1 | ||
|
|
ca89d8e7b7 | ||
|
|
29127d4025 | ||
|
|
b4e0faa62e | ||
|
|
575e3efece | ||
|
|
62f92769a1 | ||
|
|
3637094896 | ||
|
|
609f9d64bf | ||
|
|
1ab6c47df6 | ||
|
|
354799b9ca | ||
|
|
04d39157b8 | ||
|
|
5cc0c06a11 |
No files matched your search
+1
-1
@@ -24,7 +24,7 @@ Enterprise-grade Odoo Community hosting without the enterprise price tag. Commun
|
||||
|
||||
- Static site (index.html, support.html, legal.html, blog/) deployed via git push to git.odoo4projects.com; auto-deploys on every change.
|
||||
- Order flow: inline order widget on the homepage opens Stripe checkout; coupon FREE TRIAL = 1 month free; yearly billing saves roughly 8-10%; "Satisfied or reimbursed" guarantee; server location chosen at checkout (US, Brazil, India, Australia, Netherlands, UK).
|
||||
- Support: AI support bot (agent.js from static.odoo4projects.com) plus human team; email support@odoo4projects.com; /contactus route.
|
||||
- Support: AI support bot (agent.js from static.odoo4projects.com) plus human team; email support@odoo4projects.com; contact form on support.html#contact.
|
||||
- Blog with guides and news (10 posts); homepage renders it with search and pagination.
|
||||
|
||||
## Capabilities and Constraints
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
<p>
|
||||
<a href="https://odoo4projects.com/legal/privacy">Privacy</a> •
|
||||
<a href="https://odoo4projects.com/legal/terms">Terms</a> •
|
||||
<a href="https://odoo4projects.com/contactus">Contact</a>
|
||||
<a href="https://ODOO4projects.com/support.html#contact">Contact</a>
|
||||
</p>
|
||||
<p class="unsubscribe">
|
||||
<a href="https://odoo4projects.com/unsubscribe?token=USER_TOKEN">Unsubscribe</a> from these emails
|
||||
|
||||
+35
-13
@@ -20,7 +20,7 @@
|
||||
"url": "https://ODOO4projects.com/",
|
||||
"description": "Odoo hosting with fully managed infrastructure. Deploy in 5 minutes with automatic backups, SSL, and Git-based modules.",
|
||||
"foundingDate": "2020",
|
||||
"contactPoint": { "@type": "ContactPoint", "contactType": "customer support", "url": "https://ODOO4projects.com/contactus" },
|
||||
"contactPoint": { "@type": "ContactPoint", "contactType": "customer support", "url": "https://ODOO4projects.com/support.html#contact" },
|
||||
"sameAs": ["https://www.linkedin.com/company/odoo4projects/"],
|
||||
"offers": [
|
||||
{ "@type": "Offer", "name": "Side Hustle", "price": "214.00", "priceCurrency": "USD", "url": "https://ODOO4projects.com/#pricing" },
|
||||
@@ -117,6 +117,13 @@
|
||||
.hero-sub{font-size:1.05rem;color:rgba(255,255,255,.7);max-width:560px;line-height:1.7;margin-bottom:1.5rem}
|
||||
.hero-stats{display:flex;gap:1.5rem;margin-bottom:2rem;flex-wrap:wrap}.hero-stat{display:flex;align-items:center;gap:.4rem;color:rgba(255,255,255,.65);font-size:.85rem}.hero-stat i{color:var(--brass);font-size:.75rem}
|
||||
.hero-actions{display:flex;gap:1rem;flex-wrap:wrap;margin-bottom:2rem}
|
||||
.hero-notice{position:absolute;top:1.25rem;right:1.25rem;z-index:3;display:flex;align-items:center;gap:.55rem;max-width:min(360px,calc(100% - 2rem));padding:.6rem .85rem .6rem 1rem;background:#f5c542;color:var(--midnight);border:1px solid rgba(13,27,46,.14);border-radius:var(--radius);box-shadow:0 8px 24px rgba(13,27,46,.3);font-family:Inter,sans-serif;font-size:.82rem;line-height:1.4;animation:heroNoticeIn .4s cubic-bezier(.16,1,.3,1)}
|
||||
.hero-notice[hidden]{display:none}
|
||||
.hero-notice i{color:var(--midnight);font-size:.9rem;flex-shrink:0}
|
||||
.hero-notice-text{flex:1;min-width:0;overflow-wrap:anywhere}
|
||||
.hero-notice-close{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.35rem;height:1.35rem;padding:0;border:0;border-radius:50%;background:rgba(13,27,46,.12);color:var(--midnight);font-size:1rem;line-height:1;cursor:pointer;transition:background .2s}
|
||||
.hero-notice-close:hover{background:rgba(13,27,46,.24)}
|
||||
@keyframes heroNoticeIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
|
||||
.server-banner{background:var(--midnight);padding:2rem 0 1.5rem;border-top:1px solid var(--line-brass);border-bottom:1px solid var(--line-brass);position:relative;overflow:hidden}
|
||||
.server-banner::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 60% 80% at 50% 100%,rgba(201,162,39,.06) 0%,transparent 70%);pointer-events:none}
|
||||
.server-banner-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.25rem;flex-wrap:wrap;gap:.5rem}
|
||||
@@ -138,7 +145,7 @@
|
||||
.pricing-server-select{padding:.5rem 1rem;border-radius:var(--radius);border:1px solid var(--line-brass);background:rgba(255,255,255,.08);color:#fff;font-family:Inter,sans-serif;font-size:.85rem;outline:none;cursor:pointer;min-width:180px}
|
||||
.pricing-server-select option{background:var(--midnight);color:#fff}
|
||||
@media(max-width:992px){.server-grid{grid-template-columns:repeat(3,1fr)}}
|
||||
@media(max-width:768px){.hero{min-height:auto;padding:3rem 0 0}.hero-actions{flex-direction:column}.hero-actions .btn{width:100%;text-align:center}.hero-stats{gap:.75rem}.hero-city-label{bottom:1rem;right:1rem;font-size:.78rem;padding:.5rem .9rem}}
|
||||
@media(max-width:768px){.hero{min-height:auto;padding:3rem 0 0}.hero.has-hero-notice{padding-top:4.75rem}.hero-actions{flex-direction:column}.hero-actions .btn{width:100%;text-align:center}.hero-stats{gap:.75rem}.hero-city-label{bottom:1rem;right:1rem;font-size:.78rem;padding:.5rem .9rem}.hero-notice{top:.75rem;left:.75rem;right:.75rem;max-width:none;font-size:.78rem}}
|
||||
@media(max-width:576px){.server-grid{grid-template-columns:repeat(2,1fr)}.server-banner-header{flex-direction:column;align-items:flex-start}}
|
||||
.status-dot{width:7px;height:7px;border-radius:50%;background:var(--brass);display:inline-block;animation:statusPulse 1.2s ease-in-out infinite}
|
||||
@keyframes statusPulse{0%,100%{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1.2)}}
|
||||
@@ -182,7 +189,7 @@
|
||||
.oca-empty{text-align:center;padding:2rem;color:rgba(255,255,255,.4);font-style:italic;display:none}
|
||||
.oca-loading{text-align:center;padding:2rem;color:rgba(255,255,255,.4);font-size:.88rem}
|
||||
/* Custom Quote Modal */
|
||||
.ow-sub{font-size:.95rem;color:rgba(255,255,255,.7);margin-bottom:1.5rem}
|
||||
.ow-sub{font-size:.95rem;color:var(--midnight);margin-bottom:1.5rem}
|
||||
.ow-panel input[type="text"],.ow-panel textarea{width:100%;padding:.8rem 1rem;border-radius:var(--radius);border:1px solid var(--line-brass);background:rgba(255,255,255,.05);color:#171c26;font-family:Inter,sans-serif;font-size:.88rem;outline:none;transition:border-color .2s,background .2s;box-sizing:border-box}
|
||||
.ow-panel input[type="text"]:focus,.ow-panel textarea:focus{border-color:var(--brass);background:rgba(255,255,255,.08)}
|
||||
.ow-panel textarea{min-height:100px;resize:vertical}
|
||||
@@ -198,6 +205,9 @@
|
||||
#customQuoteModal .biz-field input[type="email"]::placeholder{color:rgba(23,28,38,.3)}
|
||||
#customQuoteModal .biz-field input[type="text"]{color:#171c26}
|
||||
#customQuoteModal .biz-field input[type="text"]::placeholder{color:rgba(23,28,38,.3)}
|
||||
/* Success message sits on the light modal panel, so it needs dark text (the global .biz-success rules target the dark wizard section) */
|
||||
#customQuoteModal .biz-success h3{color:var(--midnight)}
|
||||
#customQuoteModal .biz-success p{color:var(--midnight)}
|
||||
@media(max-width:600px){.oca-table td,.oca-table th{padding:.5rem .65rem;font-size:.8rem}.ow-panel{left:5%;right:5%}.ow-close{top:.5rem;right:.5rem;font-size:1.6rem}}
|
||||
</style>
|
||||
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'" />
|
||||
@@ -208,14 +218,19 @@
|
||||
THESIS: The homepage as a global business lounge concierge desk — midnight blue, brass, marble, city placards for the six regions. The category default (hero + feature grid + pricing grid) is reframed as hospitality: the visitor checks in, reads the rate card, and books a suite.
|
||||
OWN-WORLD: Midnight blue (#0d1b2e) ground, brass (#c9a227) for every accent and CTA, cream (#f4f0e8) for light surfaces. Marcellus serif for display, Inter for body. Six city photos (Amsterdam, Boston, London, Mumbai, São Paulo, Sydney) as circular placards. Hairline brass rules. Concierge-card features.
|
||||
STORY: The visitor understands: "I can deploy Odoo in 5 minutes, globally, without DevOps. This is enterprise-grade, but the concierge handles everything." They believe it from the city photos (real regions), the partner logos, the brass CTA, and the "No setup fee. Stripe Payment. Cancel at any time" footer.
|
||||
FIRST VIEWPORT: Midnight hero with faint Amsterdam skyline. Brass kicker "FULLY MANAGED ODOO HOSTING". Large serif h1 "Deploy Odoo in 5 Minutes — Fully Managed Hosting". Stats row with brass checks. Brass CTA button "See Plans & Pricing" + ghost "How It Works". Bottom: six city placards (photo + name + region) in a horizontal strip.
|
||||
FIRST VIEWPORT: Midnight hero with faint Amsterdam skyline. Brass kicker "FULLY MANAGED ODOO COMMUNITY HOSTING". Large serif h1 "Deploy Odoo in 5 Minutes — Fully Managed Hosting". Stats row with brass checks. Brass CTA button "See Plans & Pricing" + ghost "How It Works". Bottom: six city placards (photo + name + region) in a horizontal strip.
|
||||
FORM: The Grand Hotel Business Lounge (model-pick, user-chosen). Seed key: 7db4dced.
|
||||
FINISH: unreviewed and undocumented is unfinished; this build ends with the finish review, the verdict, and DESIGN.md.
|
||||
-->
|
||||
<!-- Hero -->
|
||||
<section class="hero">
|
||||
<div class="hero-notice" id="heroConfirmNotice" role="status" aria-live="polite" hidden>
|
||||
<i class="fas fa-check-circle" aria-hidden="true"></i>
|
||||
<span class="hero-notice-text"></span>
|
||||
<button type="button" class="hero-notice-close" aria-label="Dismiss notification">×</button>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="hero-kicker">Fully Managed Odoo Hosting</div>
|
||||
<div class="hero-kicker">Fully Managed Odoo Community Hosting</div>
|
||||
<h1>Deploy Odoo in <span>5 Minutes</span> — Fully Managed Hosting</h1>
|
||||
<p class="hero-sub">Launch a production-ready Odoo Community instance with automatic backups, free SSL, and Git-based module management. No DevOps required.</p>
|
||||
<div class="hero-stats">
|
||||
@@ -369,7 +384,7 @@
|
||||
<label for="pricingOdooVersion">Odoo Version</label>
|
||||
<select id="pricingOdooVersion" class="pricing-server-select">
|
||||
<option value="19.0">19.0 — Tons of OCA supported modules</option>
|
||||
<option value="20.0">20.0 — Latest Greatest</option>
|
||||
<option value="20.0" selected>20.0 — Latest Greatest</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="pricing-grid">
|
||||
@@ -383,7 +398,7 @@
|
||||
<div class="price-save">Save 8%</div>
|
||||
</div>
|
||||
<p class="desc">"ODOO Standard .. that is all my business needs"</p>
|
||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="54">Buy Now</a>
|
||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="6">Buy Now</a>
|
||||
<ul>
|
||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
||||
@@ -402,7 +417,7 @@
|
||||
<div class="price-save">Save 9%</div>
|
||||
</div>
|
||||
<p class="desc">"I need some modules and professional reports"</p>
|
||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="55">Buy Now</a>
|
||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="4">Buy Now</a>
|
||||
<ul>
|
||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
||||
@@ -422,7 +437,7 @@
|
||||
<div class="price-save">Save 10%</div>
|
||||
</div>
|
||||
<p class="desc">"ODOO Enterprise is a must have!"</p>
|
||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="56">Buy Now</a>
|
||||
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="5">Buy Now</a>
|
||||
<ul>
|
||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Launch Odoo CE in 5 minutes</li>
|
||||
<li><i class="fas fa-check" style="color: var(--success)"></i> Automatic backups — no remembering</li>
|
||||
@@ -486,7 +501,7 @@
|
||||
</div>
|
||||
<p class="ow-coupon-status" id="orderCouponStatus">✓ Coupon applied</p>
|
||||
</div>
|
||||
<a id="orderBuyBtn" href="/contactus" class="btn btn-brass ow-buy">Continue to Stripe →</a>
|
||||
<a id="orderBuyBtn" href="/support.html#contact" class="btn btn-brass ow-buy">Continue to Stripe →</a>
|
||||
<p class="ow-note">🔒 Secure Stripe checkout · Credit card required</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -611,7 +626,7 @@
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="support.html">Support</a></li>
|
||||
<li><a href="legal.html">Legal</a></li>
|
||||
<li><a href="/contactus">Contact us</a></li>
|
||||
<li><a href="/support.html#contact">Contact us</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
@@ -624,9 +639,8 @@
|
||||
</div>
|
||||
<div class="fcol-desc">
|
||||
<h4>About us</h4>
|
||||
<p>We build smart, scalable business solutions by combining the <strong>stability</strong> of Odoo ERP with the <strong>power</strong> of AI and N8N automation.</p>
|
||||
<p>We build smart, scalable business solutions by combining the <strong>stability</strong> of Odoo ERP with the <strong>power</strong> of AI Agents and N8N automations.</p>
|
||||
<p>From streamlined sales to global rollouts, our <strong>lean, eco-friendly</strong> approach helps businesses cut costs, boost efficiency, and grow without limits.</p>
|
||||
<p><a href="mailto:support@odoo4projects.com" class="footer-email">support@odoo4projects.com</a></p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Follow us on</h4>
|
||||
@@ -634,6 +648,14 @@
|
||||
<a href="https://www.linkedin.com/company/odoo4projects/" target="_blank" aria-label="LinkedIn"><i class="fab fa-linkedin-in"></i></a>
|
||||
<a href="https://www.youtube.com/@ODOO4projects" target="_blank" aria-label="YouTube"><i class="fab fa-youtube"></i></a>
|
||||
</div>
|
||||
<form class="footer-contact-form" id="footerContactForm">
|
||||
<input type="email" id="footerContactEmail" placeholder="Your email address" required />
|
||||
<div class="footer-textarea-wrap">
|
||||
<textarea id="footerContactText" placeholder="Your message..." required></textarea>
|
||||
<button type="submit" class="footer-send-btn" aria-label="Send message"><i class="fas fa-paper-plane"></i></button>
|
||||
</div>
|
||||
<div class="footer-form-status" id="footerFormStatus" role="status"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fcopy">Copyright © ODOO4projects LLC</div>
|
||||
|
||||
+9
-13
@@ -20,7 +20,7 @@
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;background:linear-gradient(180deg,var(--bg),#eef2f8);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:28px}
|
||||
|
||||
.app{width:960px;max-width:96vw;background:transparent;display:grid;grid-template-columns:320px 1fr;gap:20px}
|
||||
.app{width:1146px;max-width:96vw;background:transparent;display:grid;grid-template-columns:320px 1fr;gap:20px;align-items:stretch}
|
||||
|
||||
/* Left column - user list / details */
|
||||
.sidebar{background:linear-gradient(180deg,rgba(255,255,255,0.9),var(--card));border-radius:var(--radius);padding:20px;box-shadow:0 6px 20px rgba(24,39,75,0.06);overflow:hidden}
|
||||
@@ -55,17 +55,16 @@
|
||||
.sidebar .hint{margin-top:14px;padding:10px;border-radius:10px;background:#fbf8ff;color:#5b4160;font-size:13px}
|
||||
|
||||
/* Chat area */
|
||||
.chat-card{background:var(--card);border-radius:var(--radius);display:flex;flex-direction:column;height:70vh;box-shadow:0 10px 30px rgba(24,39,75,0.06);overflow:hidden}
|
||||
.chat-card{background:var(--card);border-radius:var(--radius);display:flex;flex-direction:column;height:100%;min-height:0;box-shadow:0 10px 30px rgba(24,39,75,0.06);overflow:hidden}
|
||||
.chat-header{display:flex;align-items:center;gap:12px;padding:18px;border-bottom:1px solid #eef1f6}
|
||||
.chat-header .title{font-weight:600;color:var(--odoo-dark)}
|
||||
.chat-header .sub{font-size:13px;color:var(--muted)}
|
||||
|
||||
.messages{flex:1;padding:22px;overflow:auto;background:linear-gradient(180deg,#fbfcff, #f7f9fc)}
|
||||
.messages{flex:1;min-height:0;padding:22px;overflow:auto;background:linear-gradient(180deg,#fbfcff, #f7f9fc)}
|
||||
.messages-inner{max-width:760px;margin:0 auto;display:flex;flex-direction:column;gap:12px}
|
||||
|
||||
.msg{display:flex;gap:10px;align-items:flex-end}
|
||||
.msg.me{justify-content:flex-end}
|
||||
.bubble{max-width:68%;padding:12px 14px;border-radius:12px;background:white;border:1px solid #eef1f6;font-size:14px;color:#222}
|
||||
.msg{display:flex;gap:10px;align-items:flex-end;width:100%}
|
||||
.bubble{width:100%;max-width:100%;padding:12px 14px;border-radius:12px;background:white;border:1px solid #eef1f6;font-size:14px;color:#222}
|
||||
.bubble.me{background:linear-gradient(90deg,var(--odoo-purple),#9b6fa0);color:white;border:none}
|
||||
.meta-time{font-size:11px;color:var(--muted);margin-top:6px}
|
||||
|
||||
@@ -204,16 +203,13 @@ Please note: it does not cover general Odoo usage or functional questions.
|
||||
const col = document.createElement('div');
|
||||
col.style.display = 'flex';
|
||||
col.style.flexDirection = 'column';
|
||||
col.style.flex = '1';
|
||||
col.style.minWidth = '0';
|
||||
col.appendChild(bubble);
|
||||
col.appendChild(meta);
|
||||
|
||||
if(who==='me'){
|
||||
wrap.appendChild(col);
|
||||
wrap.appendChild(avatar);
|
||||
} else {
|
||||
wrap.appendChild(avatar);
|
||||
wrap.appendChild(col);
|
||||
}
|
||||
wrap.appendChild(avatar);
|
||||
wrap.appendChild(col);
|
||||
|
||||
messagesEl.appendChild(wrap);
|
||||
messagesEl.parentElement.scrollTop = messagesEl.parentElement.scrollHeight;
|
||||
|
||||
+48
-9
@@ -297,7 +297,7 @@
|
||||
<script>
|
||||
// ── Webhooks ─────────────────────────────────────────────────────────────
|
||||
const getContract_Webhook =
|
||||
"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/0c8536be-d175-4740-8e78-123159193b23";
|
||||
"https://n8n.odoo4projects.com/webhook/ODOO4projects/upsell";
|
||||
|
||||
// ── Plan hierarchy (index = tier, lower = cheaper) ────────────────────────
|
||||
const PLAN_ORDER = [
|
||||
@@ -337,11 +337,46 @@
|
||||
|
||||
// ── Product ID mapping ─────────────────────────────────────────
|
||||
const PRODUCT_IDS = {
|
||||
sidehustle: 54,
|
||||
ontherise: 55,
|
||||
powerhouse: 56,
|
||||
sidehustle: 6,
|
||||
ontherise: 4,
|
||||
powerhouse: 5,
|
||||
};
|
||||
|
||||
// ── UTM tracking (source / medium / campaign) ─────────────────────────────
|
||||
const UTM_KEYS = ["source", "medium", "campaign"];
|
||||
|
||||
function getCookie(name) {
|
||||
const match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
|
||||
return match ? decodeURIComponent(match[2]) : null;
|
||||
}
|
||||
|
||||
function setCookie(name, value, days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
document.cookie =
|
||||
name + "=" + encodeURIComponent(value) +
|
||||
"; expires=" + date.toUTCString() +
|
||||
"; path=/; SameSite=Lax";
|
||||
}
|
||||
|
||||
UTM_KEYS.forEach(function (key) {
|
||||
const val = params.get("utm_" + key);
|
||||
if (val) setCookie("utm_" + key, val, 90);
|
||||
});
|
||||
|
||||
function appendUTM(form) {
|
||||
UTM_KEYS.forEach(function (key) {
|
||||
const val = getCookie("utm_" + key);
|
||||
if (val) {
|
||||
const input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = "utm_" + key;
|
||||
input.value = val;
|
||||
form.appendChild(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ── Buy handler ───────────────────────────────────────────────────────────
|
||||
function buyProduct(productId) {
|
||||
if (!uuid) {
|
||||
@@ -355,7 +390,7 @@
|
||||
}
|
||||
var form = document.createElement("form");
|
||||
form.method = "POST";
|
||||
form.action = window.location.origin + "/shop/post_basket";
|
||||
form.action = "https://20.odoo4projects.com/shop/post_basket";
|
||||
form.target = "_blank";
|
||||
form.style.display = "none";
|
||||
var basket = document.createElement("input");
|
||||
@@ -369,6 +404,7 @@
|
||||
clear.name = "clear";
|
||||
clear.value = "1";
|
||||
form.appendChild(clear);
|
||||
appendUTM(form);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
document.body.removeChild(form);
|
||||
@@ -390,7 +426,7 @@
|
||||
const currentIdx = PLAN_ORDER.indexOf(contractName);
|
||||
if (currentIdx === -1) return; // unknown plan – leave defaults
|
||||
|
||||
const badgeLabel = expires ? "✅ " + expires : "✅";
|
||||
const badgeLabel = expires ? "✅ Expires " + expires : "✅";
|
||||
|
||||
PLAN_ORDER.forEach(function (plan, idx) {
|
||||
var meta = PLAN_META[plan];
|
||||
@@ -432,12 +468,15 @@
|
||||
if (!res.ok) throw new Error("HTTP " + res.status);
|
||||
|
||||
const payload = await res.json();
|
||||
// Webhook returns: [{ "expires": "YYYY-MM-DD", "contractName": "Trial" }]
|
||||
// Webhook returns: { "expires": "YYYY-MM-DD", "contractName": "Trial" }
|
||||
// (tolerate an array wrapper and snake_case keys as well)
|
||||
const record = Array.isArray(payload)
|
||||
? payload[0]
|
||||
: payload;
|
||||
if (record && record.contract_name) {
|
||||
applyPlanState(record.contract_name, record.expires);
|
||||
const contractName =
|
||||
record && (record.contractName || record.contract_name);
|
||||
if (contractName) {
|
||||
applyPlanState(contractName, record.expires);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Could not load contract data:", err);
|
||||
|
||||
@@ -57,7 +57,33 @@ var si = 0,
|
||||
return data;
|
||||
}
|
||||
|
||||
window.UTM = { parse: parseUTM, getStored: getStoredUTM, inject: injectUTM };
|
||||
function appendToForm(form) {
|
||||
var stored = getStoredUTM();
|
||||
var keys = ['source', 'medium', 'campaign'];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (stored[keys[i]]) {
|
||||
var input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = 'utm_' + keys[i];
|
||||
input.value = stored[keys[i]];
|
||||
form.appendChild(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toQuery() {
|
||||
var stored = getStoredUTM();
|
||||
var parts = [];
|
||||
var keys = ['source', 'medium', 'campaign'];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (stored[keys[i]]) {
|
||||
parts.push('utm_' + keys[i] + '=' + encodeURIComponent(stored[keys[i]]));
|
||||
}
|
||||
}
|
||||
return parts.join('&');
|
||||
}
|
||||
|
||||
window.UTM = { parse: parseUTM, getStored: getStoredUTM, inject: injectUTM, appendToForm: appendToForm, toQuery: toQuery };
|
||||
window.UTM.parse(); // Parse on page load
|
||||
})();
|
||||
|
||||
@@ -70,6 +96,30 @@ var si = 0,
|
||||
}
|
||||
})();
|
||||
|
||||
/* ---- Hero confirmation notice (shown when ?confirm=...) ---- */
|
||||
(function () {
|
||||
var message = new URLSearchParams(window.location.search).get('confirm');
|
||||
if (!message || !message.trim()) return;
|
||||
|
||||
var notice = document.getElementById('heroConfirmNotice');
|
||||
if (!notice) return;
|
||||
|
||||
var text = notice.querySelector('.hero-notice-text');
|
||||
var close = notice.querySelector('.hero-notice-close');
|
||||
var hero = notice.closest('.hero');
|
||||
|
||||
text.textContent = message.trim();
|
||||
notice.hidden = false;
|
||||
if (hero) hero.classList.add('has-hero-notice');
|
||||
|
||||
if (close) {
|
||||
close.addEventListener('click', function () {
|
||||
notice.hidden = true;
|
||||
if (hero) hero.classList.remove('has-hero-notice');
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
if (slides.length > 0 && dots.length > 0) {
|
||||
function show(i, direction) {
|
||||
if (direction === undefined) return;
|
||||
@@ -196,13 +246,15 @@ var si = 0,
|
||||
yearlySave.style.display = "block";
|
||||
var buyBtn = document.getElementById("orderBuyBtn");
|
||||
var loc = document.getElementById("orderServerLocation").value;
|
||||
var utmQuery = UTM.toQuery();
|
||||
buyBtn.href =
|
||||
"/3/" +
|
||||
price.toFixed(2) +
|
||||
"/4/" +
|
||||
encodeURIComponent(plan) +
|
||||
"?location=" +
|
||||
encodeURIComponent(loc);
|
||||
encodeURIComponent(loc) +
|
||||
(utmQuery ? "&" + utmQuery : "");
|
||||
widget.style.display = "flex";
|
||||
orderPopupShown = true;
|
||||
}
|
||||
@@ -233,13 +285,15 @@ var si = 0,
|
||||
.trim();
|
||||
var price = parseFloat(priceText);
|
||||
var loc = this.value;
|
||||
var utmQuery = UTM.toQuery();
|
||||
document.getElementById("orderBuyBtn").href =
|
||||
"/3/" +
|
||||
price.toFixed(2) +
|
||||
"/4/" +
|
||||
encodeURIComponent(plan) +
|
||||
"?location=" +
|
||||
encodeURIComponent(loc);
|
||||
encodeURIComponent(loc) +
|
||||
(utmQuery ? "&" + utmQuery : "");
|
||||
});
|
||||
function applyCoupon() {
|
||||
var input = document.getElementById("orderCouponInput");
|
||||
@@ -701,7 +755,7 @@ var si = 0,
|
||||
var version = verSelect ? verSelect.value : '';
|
||||
var form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.action = 'https://odoo.odoo4projects.com/shop/post_basket';
|
||||
form.action = 'https://20.odoo4projects.com/shop/post_basket';
|
||||
form.target = '_blank';
|
||||
form.style.display = 'none';
|
||||
var basket = document.createElement('input');
|
||||
@@ -719,6 +773,7 @@ var si = 0,
|
||||
clear.name = 'clear';
|
||||
clear.value = '1';
|
||||
form.appendChild(clear);
|
||||
UTM.appendToForm(form);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
document.body.removeChild(form);
|
||||
@@ -810,6 +865,9 @@ var si = 0,
|
||||
document.getElementById('customQuoteForm').reset();
|
||||
document.getElementById('customQuoteSuccess').style.display = 'none';
|
||||
}
|
||||
/* Expose to global scope so the inline onclick handlers in the modal markup can reach them */
|
||||
window.openCustomQuoteModal = openCustomQuoteModal;
|
||||
window.closeCustomQuoteModal = closeCustomQuoteModal;
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
var modal = document.getElementById('customQuoteModal');
|
||||
@@ -840,9 +898,11 @@ var si = 0,
|
||||
body: JSON.stringify(UTM.inject({
|
||||
name: name,
|
||||
email: email,
|
||||
requirements: requirements
|
||||
requirements: requirements,
|
||||
area: 'quote'
|
||||
}))
|
||||
}).then(function() {
|
||||
}).then(function(r) {
|
||||
if (!r.ok) throw new Error('bad status ' + r.status);
|
||||
customQuoteForm.style.display = 'none';
|
||||
document.getElementById('customQuoteSuccess').style.display = 'block';
|
||||
submitBtn.textContent = 'Submit Request';
|
||||
@@ -867,3 +927,47 @@ var si = 0,
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
/* ---- Footer contact form ---- */
|
||||
(function () {
|
||||
var form = document.getElementById('footerContactForm');
|
||||
if (!form) return;
|
||||
var emailInput = document.getElementById('footerContactEmail');
|
||||
var textInput = document.getElementById('footerContactText');
|
||||
var submitBtn = form.querySelector('.footer-send-btn');
|
||||
var status = document.getElementById('footerFormStatus');
|
||||
|
||||
function showStatus(message, isError) {
|
||||
status.textContent = message;
|
||||
status.classList.toggle('error', !!isError);
|
||||
status.classList.add('visible');
|
||||
}
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var email = emailInput.value.trim();
|
||||
var text = textInput.value.trim();
|
||||
if (!email || !text) return;
|
||||
|
||||
submitBtn.disabled = true;
|
||||
status.classList.remove('visible');
|
||||
|
||||
fetch('https://n8n.odoo4projects.com/webhook/ODOO4projects/crm', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(UTM.inject({
|
||||
email: email,
|
||||
requirements: text,
|
||||
area: 'message'
|
||||
}))
|
||||
}).then(function (r) {
|
||||
if (!r.ok) throw new Error('bad status ' + r.status);
|
||||
form.reset();
|
||||
submitBtn.disabled = false;
|
||||
showStatus("Thanks! We'll get back to you shortly.", false);
|
||||
}).catch(function () {
|
||||
submitBtn.disabled = false;
|
||||
showStatus('Something went wrong. Please try again.', true);
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -920,23 +920,76 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
|
||||
}
|
||||
.fcopy a { color: rgba(255,255,255,0.4); }
|
||||
.fcopy a:hover { color: var(--brass); }
|
||||
.footer-email {
|
||||
display: inline-block;
|
||||
margin-top: 0.75rem;
|
||||
padding: 0.5rem 0.8rem;
|
||||
background: rgba(201,162,39,0.08);
|
||||
border: 1px solid rgba(201,162,39,0.25);
|
||||
.footer-contact-form {
|
||||
margin-top: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.6rem;
|
||||
}
|
||||
.footer-contact-form input[type="email"],
|
||||
.footer-contact-form textarea {
|
||||
width: 100%;
|
||||
padding: 0.6rem 0.8rem;
|
||||
border-radius: var(--radius);
|
||||
color: var(--brass);
|
||||
font-family: Inter, sans-serif;
|
||||
font-size: 0.85rem;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.footer-email:hover {
|
||||
background: rgba(201,162,39,0.12);
|
||||
border-color: var(--brass);
|
||||
border: 1px solid var(--line-brass);
|
||||
background: rgba(255,255,255,0.06);
|
||||
color: #fff;
|
||||
font-family: Inter, sans-serif;
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.6;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
transition: border-color 0.2s, background 0.2s;
|
||||
}
|
||||
.footer-contact-form input[type="email"]:focus,
|
||||
.footer-contact-form textarea:focus {
|
||||
border-color: var(--brass);
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
.footer-contact-form input[type="email"]::placeholder,
|
||||
.footer-contact-form textarea::placeholder {
|
||||
color: rgba(255,255,255,0.3);
|
||||
}
|
||||
.footer-textarea-wrap { position: relative; }
|
||||
.footer-contact-form textarea {
|
||||
min-height: 84px;
|
||||
padding-right: 2.6rem;
|
||||
resize: vertical;
|
||||
}
|
||||
.footer-send-btn {
|
||||
position: absolute;
|
||||
right: 0.45rem;
|
||||
bottom: 0.45rem;
|
||||
width: 1.9rem;
|
||||
height: 1.9rem;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: var(--brass);
|
||||
color: var(--midnight);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.72rem;
|
||||
transition: background 0.2s, transform 0.2s;
|
||||
}
|
||||
.footer-send-btn:hover {
|
||||
background: var(--brass-bright);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.footer-send-btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: default;
|
||||
transform: none;
|
||||
}
|
||||
.footer-form-status {
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.4;
|
||||
color: #4ade80;
|
||||
display: none;
|
||||
}
|
||||
.footer-form-status.visible { display: block; }
|
||||
.footer-form-status.error { color: #ef4444; }
|
||||
@media (max-width: 768px) {
|
||||
.fgrid { grid-template-columns: 1fr; }
|
||||
.footer { padding-top: 2.5rem; padding-bottom: 5rem; }
|
||||
|
||||
+19
-12
@@ -8,11 +8,11 @@
|
||||
content="Support and FAQ for ODOO4projects hosting. Get help with your Odoo instance, modules, backups, domains, and more."
|
||||
/>
|
||||
<title>Support | ODOO4projects</title>
|
||||
<link rel="canonical" href="https://ODOO4projects.com/support" />
|
||||
<link rel="canonical" href="https://ODOO4projects.com/support.html" />
|
||||
<meta property="og:title" content="Support | ODOO4projects" />
|
||||
<meta property="og:description" content="Support and FAQ for ODOO4projects hosting." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://ODOO4projects.com/support" />
|
||||
<meta property="og:url" content="https://ODOO4projects.com/support.html" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<link rel="icon" href="images/favicon.ico" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
@@ -474,8 +474,7 @@
|
||||
<section class="contact-section" id="contact">
|
||||
<div class="container">
|
||||
<h2>Still questions? Contact our support.</h2>
|
||||
<form class="contact-form" id="supportForm" action="https://ODOO4projects.com/website/form/" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" id="csrfToken" value="" />
|
||||
<form class="contact-form" id="supportForm">
|
||||
<div class="form-group">
|
||||
<label>Your Name <span class="required">*</span></label>
|
||||
<input type="text" id="contactName" name="contact_name" required placeholder="Your Name" />
|
||||
@@ -528,23 +527,31 @@
|
||||
var form = document.getElementById("supportForm");
|
||||
var submitBtn = form.querySelector(".btn");
|
||||
var successDiv = document.getElementById("formSuccess");
|
||||
fetch("https://ODOO4projects.com/web/csrf_token")
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (data) {
|
||||
document.getElementById("csrfToken").value = data.result || data.csrf_token || "";
|
||||
}).catch(function () {});
|
||||
form.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
var name = document.getElementById("contactName").value.trim();
|
||||
var email = document.getElementById("contactEmail").value.trim();
|
||||
var uuid = document.getElementById("contactUuid").value.trim();
|
||||
var subject = document.getElementById("contactSubject").value.trim();
|
||||
var question = document.getElementById("contactQuestion").value.trim();
|
||||
if (!name || !email || !subject || !question) { alert("Please fill in all required fields."); return; }
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = "Submitting...";
|
||||
fetch(form.action, { method: "POST", body: new FormData(form) })
|
||||
.then(function () { submitBtn.style.display = "none"; successDiv.classList.add("visible"); })
|
||||
.catch(function () { submitBtn.disabled = false; submitBtn.textContent = "Submit"; alert("Could not submit. Please try again."); });
|
||||
var payload = { name: name, email: email, subject: subject, requirements: question, area: "support" };
|
||||
if (uuid) payload.uuid = uuid;
|
||||
fetch("https://n8n.odoo4projects.com/webhook/ODOO4projects/crm", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload)
|
||||
}).then(function (r) {
|
||||
if (!r.ok) throw new Error("bad status " + r.status);
|
||||
submitBtn.style.display = "none";
|
||||
successDiv.classList.add("visible");
|
||||
}).catch(function () {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = "Submit";
|
||||
alert("Could not submit. Please try again.");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in new issue
Block a user