Author SHA1 Message Date
ODOO4projects Web Developer 20f8d02116 feat: add agent-skills JSON to homepage for free trial provisioning
- includes spin_up_free_trial skill with MCP server reference
- defines six server locations (Manchester, Sydney, Mumbai, São Paulo, Meppel, Boston)
- provides workflow steps and clear instructions for conversational agents
2026-10-06 22:45:34 +00:00
13 changed files with 75 additions and 549 deletions

No files matched your search

+1 -1
View File
@@ -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; contact form on support.html#contact.
- Support: AI support bot (agent.js from static.odoo4projects.com) plus human team; email support@odoo4projects.com; /contactus route.
- Blog with guides and news (10 posts); homepage renders it with search and pagination.
## Capabilities and Constraints
-16
View File
@@ -1,21 +1,5 @@
{
"posts": [
{
"id": "6-tips-to-leverage-the-latest-odoo-management-app-update",
"date": "2026-10-08",
"area": "news",
"headline": "6 Tips to Leverage the Latest Odoo Management App Update",
"teaser": "We've just rolled out a major update to the management app preinstalled on your ODOO4project service. Along with a fresh",
"link": "blog/posts/6-tips-to-leverage-the-latest-odoo-management-app-update.html"
},
{
"id": "odoo-20-is-live-on-our-servers-with-an-mcp-server-and-free-backups",
"date": "2026-10-06",
"area": "news",
"headline": "Odoo 20 Is Live on Our Servers — With an MCP Server and Free Backups",
"teaser": "Two weeks. That is how long it took us to bring up Odoo 20 on our servers, with all of the new features that come with i",
"link": "blog/posts/odoo-20-is-live-on-our-servers-with-an-mcp-server-and-free-backups.html"
},
{
"id": "odoo-community-is-going-online-on-odoo4projects",
"date": "2026-09-28",
@@ -1,72 +0,0 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>6 Tips to Leverage the Latest Odoo Management App Update | ODOO4projects</title>
<meta name="description" content="We've just rolled out a major update to the management app preinstalled on your ODOO4project service. Along with a fresh new look, we've added several powe" />
<link rel="canonical" href="https://odoo4projects.com/blog/posts/6-tips-to-leverage-the-latest-odoo-management-app-update.html" />
<meta property="og:title" content="6 Tips to Leverage the Latest Odoo Management App Update" />
<meta property="og:description" content="We've just rolled out a major update to the management app preinstalled on your ODOO4project service. Along with a fresh new look, we've added several powe" />
<meta property="og:type" content="article" />
<meta property="og:image" content="https://image.office.odoo4projects.com/img/20_4server.png" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" href="../../images/favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
<link rel="stylesheet" href="../../style.css" />
<style>
body { background: #0d1b2e; }
.blog-post { max-width: 720px; margin: 0 auto; padding: 3rem 1.5rem 6rem; color: #171c26; background: #faf7f1; min-height: 100vh; }
.blog-post h1 { font-family: 'Marcellus', Georgia, serif; font-size: 2.4rem; font-weight: 400; margin: 0 0 0.5rem; color: #0d1b2e; }
.blog-post .post-meta { font-family: Inter, sans-serif; font-size: 0.82rem; color: rgba(23,28,38,0.6); margin-bottom: 2rem; }
.blog-post .post-meta .badge { display: inline-block; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase; color: #c9a227; margin-right: 0.75rem; }
.blog-post .post-image { width: 100%; border-radius: 0.75rem; margin-bottom: 2rem; box-shadow: 0 2px 8px rgba(13,27,46,0.08); }
.blog-post p { font-family: Inter, sans-serif; font-size: 1rem; line-height: 1.7; margin-bottom: 1.2rem; }
.blog-post h2 { font-family: 'Marcellus', Georgia, serif; font-size: 1.6rem; font-weight: 400; margin: 2rem 0 0.75rem; color: #0d1b2e; }
.blog-post h3 { font-family: 'Marcellus', Georgia, serif; font-size: 1.25rem; font-weight: 400; margin: 1.5rem 0 0.5rem; color: #0d1b2e; }
.blog-post ul, .blog-post ol { font-family: Inter, sans-serif; font-size: 1rem; line-height: 1.7; margin-bottom: 1.2rem; padding-left: 1.5rem; }
.blog-post li { margin-bottom: 0.3rem; }
.blog-post a { color: #8a6f1f; text-decoration: underline; }
.blog-post strong { font-weight: 600; }
.blog-post blockquote { border-left: 3px solid #c9a227; padding-left: 1rem; margin-left: 0; color: rgba(23,28,38,0.7); font-style: italic; }
.back-link { display: inline-block; margin-top: 2rem; font-family: 'Marcellus', Georgia, serif; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.04em; color: #c9a227; text-decoration: none; }
.back-link:hover { text-decoration: underline; }
@media (max-width: 600px) { .blog-post h1 { font-size: 1.7rem; } .blog-post { padding: 2rem 1rem 4rem; } }
</style>
</head>
<body>
<main class="blog-post">
<span class="badge">news</span>
<h1>6 Tips to Leverage the Latest Odoo Management App Update</h1>
<div class="post-meta">Oct 08, 2026</div>
<img src="https://image.office.odoo4projects.com/img/20_4server.png" alt="6 Tips to Leverage the Latest Odoo Management App Update" class="post-image" loading="lazy" />
<div class="post-body">
<p>We've just rolled out a major update to the management app preinstalled on your ODOO4project service. Along with a fresh new look, we've added several powerful features to make managing your Odoo hosting easier. Here are six practical tips to help you get the most out of them.</p>
<h3>1. Automate hosting tasks with the new MCP server</h3>
<p>The new MCP server lets your agent control your Odoo hosting directly. You can restart the server, upload modules, add or check domains, manage backups, and read logfiles—all without manual intervention. <strong>Tip:</strong> Configure your agent to handle routine maintenance so you can focus on development.</p>
<h3>2. Download and archive logfiles for easier troubleshooting</h3>
<p>You can now download and archive logfiles directly from the app. <strong>Tip:</strong> When debugging an issue, download the relevant logfile to analyze it locally. Archive older logs regularly to keep your system organized and reduce clutter.</p>
<h3>3. Take advantage of the free backup schema</h3>
<p>We've added a free backup schema for everyone to improve data security. <strong>Tip:</strong> Make sure backups are scheduled and test restoring from a backup occasionally to ensure your data is safe.</p>
<h3>4. Explore the improved AI server management backend</h3>
<p>The AI server management backend has been upgraded. <strong>Tip:</strong> Spend a few minutes navigating the new interface—you'll find streamlined workflows that make server management more intuitive.</p>
<h3>5. Install modules faster with improved GIT support</h3>
<p>Module installation via GIT has been improved. <strong>Tip:</strong> Use GIT to install or update modules more efficiently, especially when you need to manage versions or deploy across multiple environments.</p>
<h3>6. Get instant help from the AI support bot</h3>
<p>Our AI support bot has also been improved. <strong>Tip:</strong> When you run into a question, ask the bot first—it's a quick way to get answers without leaving your workflow.</p>
<p>These updates are designed to save you time and give you more control over your Odoo hosting. Ready to try them out? <a href="https://ODOO4projects.com">Start your free trial on ODOO4projects.com</a>.</p>
</div>
<a href="../../index.html#blog" class="back-link">&larr; Back to the Blog</a>
</main>
</body>
</html>
@@ -1,52 +0,0 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Odoo 20 Is Live on Our Servers — With an MCP Server and Free Backups | ODOO4projects</title>
<meta name="description" content="Two weeks. That is how long it took us to bring up Odoo 20 on our servers, with all of the new features that come with it. It is live now.But the version u" />
<link rel="canonical" href="https://odoo4projects.com/blog/posts/odoo-20-is-live-on-our-servers-with-an-mcp-server-and-free-backups.html" />
<meta property="og:title" content="Odoo 20 Is Live on Our Servers — With an MCP Server and Free Backups" />
<meta property="og:description" content="Two weeks. That is how long it took us to bring up Odoo 20 on our servers, with all of the new features that come with it. It is live now.But the version u" />
<meta property="og:type" content="article" />
<meta property="og:image" content="https://image.office.odoo4projects.com/img/ODOO_20_chatter.png" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" href="../../images/favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
<link rel="stylesheet" href="../../style.css" />
<style>
body { background: #0d1b2e; }
.blog-post { max-width: 720px; margin: 0 auto; padding: 3rem 1.5rem 6rem; color: #171c26; background: #faf7f1; min-height: 100vh; }
.blog-post h1 { font-family: 'Marcellus', Georgia, serif; font-size: 2.4rem; font-weight: 400; margin: 0 0 0.5rem; color: #0d1b2e; }
.blog-post .post-meta { font-family: Inter, sans-serif; font-size: 0.82rem; color: rgba(23,28,38,0.6); margin-bottom: 2rem; }
.blog-post .post-meta .badge { display: inline-block; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase; color: #c9a227; margin-right: 0.75rem; }
.blog-post .post-image { width: 100%; border-radius: 0.75rem; margin-bottom: 2rem; box-shadow: 0 2px 8px rgba(13,27,46,0.08); }
.blog-post p { font-family: Inter, sans-serif; font-size: 1rem; line-height: 1.7; margin-bottom: 1.2rem; }
.blog-post h2 { font-family: 'Marcellus', Georgia, serif; font-size: 1.6rem; font-weight: 400; margin: 2rem 0 0.75rem; color: #0d1b2e; }
.blog-post h3 { font-family: 'Marcellus', Georgia, serif; font-size: 1.25rem; font-weight: 400; margin: 1.5rem 0 0.5rem; color: #0d1b2e; }
.blog-post ul, .blog-post ol { font-family: Inter, sans-serif; font-size: 1rem; line-height: 1.7; margin-bottom: 1.2rem; padding-left: 1.5rem; }
.blog-post li { margin-bottom: 0.3rem; }
.blog-post a { color: #8a6f1f; text-decoration: underline; }
.blog-post strong { font-weight: 600; }
.blog-post blockquote { border-left: 3px solid #c9a227; padding-left: 1rem; margin-left: 0; color: rgba(23,28,38,0.7); font-style: italic; }
.back-link { display: inline-block; margin-top: 2rem; font-family: 'Marcellus', Georgia, serif; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.04em; color: #c9a227; text-decoration: none; }
.back-link:hover { text-decoration: underline; }
@media (max-width: 600px) { .blog-post h1 { font-size: 1.7rem; } .blog-post { padding: 2rem 1rem 4rem; } }
</style>
</head>
<body>
<main class="blog-post">
<span class="badge">News</span>
<h1>Odoo 20 Is Live on Our Servers — With an MCP Server and Free Backups</h1>
<div class="post-meta">Oct 06, 2026</div>
<img src="https://image.office.odoo4projects.com/img/ODOO_20_chatter.png" alt="Odoo 20 Is Live on Our Servers — With an MCP Server and Free Backups" class="post-image" loading="lazy" />
<div class="post-body">
<p>Two weeks. That is how long it took us to bring up Odoo 20 on our servers, with all of the new features that come with it. It is live now.</p><p>But the version upgrade is not the whole story. Alongside it, we shipped a set of updates to our management console — the place where you manage your Odoo hosting from inside Odoo itself.</p><h2>An MCP Server for Your Agent</h2><p>The biggest addition is an MCP server that lets your agent control your Odoo hosting directly. That means an agent can:</p><ul><li>Restart the server</li><li>Upload modules</li><li>Add and check domains</li><li>Manage your backups</li><li>Read the logfiles</li></ul><p>Instead of clicking through menus to handle routine hosting tasks, you can hand them to an agent and stay focused on your actual work.</p><h2>Logfiles You Can Keep</h2><p>Logfiles can now be downloaded and archived. When something needs investigating, you can pull the logs and hold on to them, rather than scrolling through a live view and hoping the relevant lines are still there by the time you look.</p><h2>Free Backups for Everyone</h2><p>We also added a free backup scheme for every customer. Backups are the least glamorous part of hosting and the one you miss most when they are gone. Having a baseline in place for everyone meaningfully improves data security across the board.</p><h2>Better AI Server Management</h2><p>Finally, we improved our AI server management backend — the layer that connects the agent-facing tools to the underlying hosting infrastructure. It is now more capable and better suited to the way these tools are actually used.</p><h2>What It Adds Up To</h2><p>Odoo 20 running on our servers, a console that manages your Odoo from within Odoo, an MCP server that opens hosting tasks up to your agent, downloadable and archivable logfiles, a free backup scheme, and a stronger AI management backend. All of it is available now.</p><p>Take a look at our homepage and sign up for a trial to see how it works in practice.</p>
</div>
<a href="../../index.html#blog" class="back-link">&larr; Back to the Blog</a>
</main>
</body>
</html>
+1 -1
View File
@@ -190,7 +190,7 @@
<p>
<a href="https://odoo4projects.com/legal/privacy">Privacy</a> &bull;
<a href="https://odoo4projects.com/legal/terms">Terms</a> &bull;
<a href="https://ODOO4projects.com/support.html#contact">Contact</a>
<a href="https://odoo4projects.com/contactus">Contact</a>
</p>
<p class="unsubscribe">
<a href="https://odoo4projects.com/unsubscribe?token=USER_TOKEN">Unsubscribe</a> from these emails
Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

+15 -85
View File
@@ -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/support.html#contact" },
"contactPoint": { "@type": "ContactPoint", "contactType": "customer support", "url": "https://ODOO4projects.com/contactus" },
"sameAs": ["https://www.linkedin.com/company/odoo4projects/"],
"offers": [
{ "@type": "Offer", "name": "Side Hustle", "price": "214.00", "priceCurrency": "USD", "url": "https://ODOO4projects.com/#pricing" },
@@ -117,13 +117,6 @@
.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}
@@ -145,7 +138,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.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: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: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)}}
@@ -188,27 +181,7 @@
.oca-icon-link:hover{color:var(--brass-bright);transform:scale(1.2)}
.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: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}
.ow-panel textarea::placeholder{color:rgba(23,28,38,.3)}
.ow-panel input[type="email"]::placeholder{color:rgba(23,28,38,.3)}
.ow-close{background:var(--midnight);border:1px solid var(--line);color:#fff;font-size:2rem;cursor:pointer;line-height:1;position:absolute;right:1rem;top:1rem;transition:color .2s,background .2s;border-radius:var(--radius);width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center}
.ow-close:hover{color:var(--brass);background:var(--midnight-2)}
/* Custom Quote Modal overrides for biz-field inside ow-panel */
#customQuoteModal .biz-field label{color:#171c26}
#customQuoteModal .biz-field textarea{color:#171c26}
#customQuoteModal .biz-field textarea::placeholder{color:rgba(23,28,38,.3)}
#customQuoteModal .biz-field input[type="email"]{color:#171c26}
#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}}
@media(max-width:600px){.oca-table td,.oca-table th{padding:.5rem .65rem;font-size:.8rem}}
</style>
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'" />
<noscript><link rel="stylesheet" href="style.css" /></noscript>
@@ -218,19 +191,14 @@
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 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.
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.
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">&times;</button>
</div>
<div class="container">
<div class="hero-kicker">Fully Managed Odoo Community Hosting</div>
<div class="hero-kicker">Fully Managed Odoo 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">
@@ -376,7 +344,7 @@
<!-- Pricing -->
<section class="section-dark" id="pricing">
<div class="container">
<p class="section-kicker">Order & Pricing</p>
<p class="section-kicker">Rates & Suites</p>
<h2 class="section-title">Your Plan, Your Timing: Upgrade Anytime</h2>
<div class="pricing-server-row">
<label for="pricingServerLocation">Server Location</label>
@@ -384,7 +352,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" selected>20.0 — Latest Greatest</option>
<option value="20.0">20.0 — Latest Greatest</option>
</select>
</div>
<div class="pricing-grid">
@@ -398,7 +366,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="6">Buy Now</a>
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="54">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>
@@ -417,7 +385,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="4">Buy Now</a>
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="55">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>
@@ -437,7 +405,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="5">Buy Now</a>
<a href="javascript:void(0)" class="btn btn-brass btn-buy" data-id="56">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>
@@ -458,7 +426,7 @@
<div class="price-save"></div>
</div>
<p class="desc">"My house! My Horse! My Server!"</p>
<a href="javascript:void(0)" class="btn btn-brass btn-empire">Get Custom Quote</a>
<a href="javascript:void(0)" class="btn btn-brass btn-empire" data-plan="Empire" data-price="950.00" data-is-empire="true">Get Custom Quote</a>
<ul>
<li><i class="fas fa-check" style="color: var(--success)"></i> Our service on your server</li>
<li><i class="fas fa-check" style="color: var(--success)"></i> All modules & features</li>
@@ -501,43 +469,12 @@
</div>
<p class="ow-coupon-status" id="orderCouponStatus">&#10003; Coupon applied</p>
</div>
<a id="orderBuyBtn" href="/support.html#contact" class="btn btn-brass ow-buy">Continue to Stripe &rarr;</a>
<a id="orderBuyBtn" href="/contactus" class="btn btn-brass ow-buy">Continue to Stripe &rarr;</a>
<p class="ow-note">&#128274; Secure Stripe checkout &middot; Credit card required</p>
</div>
</div>
</div>
<!-- Custom Quote Modal -->
<div id="customQuoteModal" class="ow-overlay" onclick="if(event.target===this)closeCustomQuoteModal()">
<div id="customQuotePanel" class="ow-panel" style="display:none">
<button class="ow-close" onclick="closeCustomQuoteModal()">&times;</button>
<div class="ow-content">
<h2 class="ow-title">Get Custom Quote</h2>
<p class="ow-sub">Tell us about your needs and we'll prepare a tailored offer.</p>
<form id="customQuoteForm" class="biz-form" style="text-align:left">
<div class="biz-field">
<label for="cqName">Name</label>
<input type="text" id="cqName" placeholder="Your full name" required />
</div>
<div class="biz-field">
<label for="cqEmail">Email</label>
<input type="email" id="cqEmail" placeholder="your@email.com" required />
</div>
<div class="biz-field">
<label for="cqRequirements">Your Requirements</label>
<textarea id="cqRequirements" placeholder="Describe your requirements (how many users? onsite, cloud? how many workers?)" required></textarea>
</div>
<button type="submit" class="btn btn-brass btn-lg">Submit Request</button>
</form>
<div class="biz-success" id="customQuoteSuccess" style="display:none">
<i class="fas fa-check-circle"></i>
<h3>Request received</h3>
<p>We'll review your requirements and get back to you shortly.</p>
</div>
</div>
</div>
</div>
<!-- Blog -->
<section class="blog-section blog-section-light" id="blog">
<div class="container">
@@ -626,7 +563,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="/support.html#contact">Contact us</a></li>
<li><a href="/contactus">Contact us</a></li>
</ul>
</div>
<div>
@@ -639,8 +576,9 @@
</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 Agents and N8N automations.</p>
<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>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>
@@ -648,14 +586,6 @@
<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 &copy; ODOO4projects LLC</div>
+14 -10
View File
@@ -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:1146px;max-width:96vw;background:transparent;display:grid;grid-template-columns:320px 1fr;gap:20px;align-items:stretch}
.app{width:960px;max-width:96vw;background:transparent;display:grid;grid-template-columns:320px 1fr;gap:20px}
/* 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,16 +55,17 @@
.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:100%;min-height:0;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:70vh;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;min-height:0;padding:22px;overflow:auto;background:linear-gradient(180deg,#fbfcff, #f7f9fc)}
.messages{flex:1;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;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}
.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}
.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}
@@ -163,7 +164,7 @@ Please note: it does not cover general Odoo usage or functional questions.
<script>
// Configuration - use your webhook
const WEBHOOK = 'https://n8n.odoo4projects.com/webhook/960d7f0f-d0ef-42a5-a8f1-79db6a7d70bd/chat';
const WEBHOOK = 'https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/702862fd-dd17-4a34-8efb-e9056d2c50df/chat';
const messagesEl = document.getElementById('messagesInner');
const input = document.getElementById('messageInput');
@@ -203,13 +204,16 @@ 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);
wrap.appendChild(avatar);
wrap.appendChild(col);
if(who==='me'){
wrap.appendChild(col);
wrap.appendChild(avatar);
} else {
wrap.appendChild(avatar);
wrap.appendChild(col);
}
messagesEl.appendChild(wrap);
messagesEl.parentElement.scrollTop = messagesEl.parentElement.scrollHeight;
+9 -48
View File
@@ -297,7 +297,7 @@
<script>
// ── Webhooks ─────────────────────────────────────────────────────────────
const getContract_Webhook =
"https://n8n.odoo4projects.com/webhook/ODOO4projects/upsell";
"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/0c8536be-d175-4740-8e78-123159193b23";
// ── Plan hierarchy (index = tier, lower = cheaper) ────────────────────────
const PLAN_ORDER = [
@@ -337,46 +337,11 @@
// ── Product ID mapping ─────────────────────────────────────────
const PRODUCT_IDS = {
sidehustle: 6,
ontherise: 4,
powerhouse: 5,
sidehustle: 54,
ontherise: 55,
powerhouse: 56,
};
// ── 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) {
@@ -390,7 +355,7 @@
}
var form = document.createElement("form");
form.method = "POST";
form.action = "https://20.odoo4projects.com/shop/post_basket";
form.action = window.location.origin + "/shop/post_basket";
form.target = "_blank";
form.style.display = "none";
var basket = document.createElement("input");
@@ -404,7 +369,6 @@
clear.name = "clear";
clear.value = "1";
form.appendChild(clear);
appendUTM(form);
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
@@ -426,7 +390,7 @@
const currentIdx = PLAN_ORDER.indexOf(contractName);
if (currentIdx === -1) return; // unknown plan – leave defaults
const badgeLabel = expires ? "✅ Expires " + expires : "✅";
const badgeLabel = expires ? "✅ " + expires : "✅";
PLAN_ORDER.forEach(function (plan, idx) {
var meta = PLAN_META[plan];
@@ -468,15 +432,12 @@
if (!res.ok) throw new Error("HTTP " + res.status);
const payload = await res.json();
// Webhook returns: { "expires": "YYYY-MM-DD", "contractName": "Trial" }
// (tolerate an array wrapper and snake_case keys as well)
// Webhook returns: [{ "expires": "YYYY-MM-DD", "contractName": "Trial" }]
const record = Array.isArray(payload)
? payload[0]
: payload;
const contractName =
record && (record.contractName || record.contract_name);
if (contractName) {
applyPlanState(contractName, record.expires);
if (record && record.contract_name) {
applyPlanState(record.contract_name, record.expires);
}
} catch (err) {
console.error("Could not load contract data:", err);
+9 -178
View File
@@ -57,33 +57,7 @@ var si = 0,
return data;
}
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: parseUTM, getStored: getStoredUTM, inject: injectUTM };
window.UTM.parse(); // Parse on page load
})();
@@ -96,30 +70,6 @@ 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;
@@ -246,15 +196,13 @@ 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) +
(utmQuery ? "&" + utmQuery : "");
encodeURIComponent(loc);
widget.style.display = "flex";
orderPopupShown = true;
}
@@ -285,15 +233,13 @@ 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) +
(utmQuery ? "&" + utmQuery : "");
encodeURIComponent(loc);
});
function applyCoupon() {
var input = document.getElementById("orderCouponInput");
@@ -584,9 +530,8 @@ var si = 0,
if (bestServer) {
[trialLoc, pricingLoc].forEach(function(el) {
if (el) {
var cityVal = bestServer.host.replace('api.', '').replace('.odoo4projects.com', '');
for (var i = 0; i < el.options.length; i++) {
if (el.options[i].value === cityVal) {
if (el.options[i].value === bestServer.host) {
el.selectedIndex = i;
break;
}
@@ -755,7 +700,7 @@ var si = 0,
var version = verSelect ? verSelect.value : '';
var form = document.createElement('form');
form.method = 'POST';
form.action = 'https://20.odoo4projects.com/shop/post_basket';
form.action = 'https://odoo.odoo4projects.com/shop/post_basket';
form.target = '_blank';
form.style.display = 'none';
var basket = document.createElement('input');
@@ -773,7 +718,6 @@ 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);
@@ -851,123 +795,10 @@ var si = 0,
document.querySelectorAll('.btn-empire').forEach(function(btn) {
btn.addEventListener('click', function() {
openCustomQuoteModal();
});
});
/* ---- Custom Quote Modal ---- */
function openCustomQuoteModal() {
document.getElementById('customQuotePanel').style.display = 'block';
document.getElementById('customQuoteModal').style.display = 'flex';
}
function closeCustomQuoteModal() {
document.getElementById('customQuoteModal').style.display = 'none';
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');
if (modal && modal.style.display === 'flex') {
closeCustomQuoteModal();
}
}
});
/* Submit custom quote form */
var customQuoteForm = document.getElementById('customQuoteForm');
if (customQuoteForm) {
customQuoteForm.addEventListener('submit', function(e) {
e.preventDefault();
var name = document.getElementById('cqName').value.trim();
var email = document.getElementById('cqEmail').value.trim();
var requirements = document.getElementById('cqRequirements').value.trim();
if (!name || !email || !requirements) return;
var submitBtn = customQuoteForm.querySelector('.btn-lg');
submitBtn.textContent = 'Sending...';
submitBtn.disabled = true;
fetch('https://n8n.odoo4projects.com/webhook/ODOO4projects/crm', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(UTM.inject({
name: name,
email: email,
requirements: requirements,
area: 'quote'
}))
}).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';
submitBtn.disabled = false;
}).catch(function() {
submitBtn.textContent = 'Submit Request';
submitBtn.disabled = false;
var errorMsg = document.createElement('div');
errorMsg.style.marginTop = '1rem';
errorMsg.style.color = '#dc3545';
errorMsg.textContent = 'Something went wrong. Please try again.';
customQuoteForm.appendChild(errorMsg);
setTimeout(function() { if(errorMsg.parentNode) errorMsg.parentNode.removeChild(errorMsg); }, 3000);
});
});
}
/* Attach "Get Custom Quote" click handlers to Empire buttons */
document.querySelectorAll('.btn-empire').forEach(function(btn) {
btn.addEventListener('click', function() {
openCustomQuoteModal();
});
});
})();
/* ---- 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);
var plan = this.getAttribute('data-plan');
var price = parseFloat(this.getAttribute('data-price'));
var isEmpire = this.getAttribute('data-is-empire') === 'true';
if (plan) openOrderWidget(plan, price, isEmpire);
});
});
})();
+1 -1
View File
@@ -3,7 +3,7 @@
const baseUrl = '/static/agent-odoo4projects';
const config = {
cssUrl: `${baseUrl}/agent.css`, // CSS file
api: `https://n8n.odoo4projects.com/webhook/960d7f0f-d0ef-42a5-a8f1-79db6a7d70bd/chat`, // Backend webhook endpoint
api: `https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/702862fd-dd17-4a34-8efb-e9056d2c50df/chat`, // Backend webhook endpoint
buttonImage: `${baseUrl}/images/4.svg`, // Chat toggle button image
logoImage: `${baseUrl}/images/logo.svg`, // Logo image for chat widget
preamble: '🤔 This is the ODOO4Projects sales agent 🛠️. Besides Sales, he can help revert module installations or restart your server using your UUID and a confirmation email. 📬 For human follow-up, leave your email.' // Initial bot message
+13 -66
View File
@@ -663,7 +663,7 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
transition: all 0.2s;
}
.ow-close:hover { background: var(--cream); color: var(--ink); }
.ow-content { padding: 2rem; color: var(--ink); }
.ow-content { padding: 2rem; }
.ow-title { font-family: Marcellus, Georgia, serif; font-size: clamp(1rem, 2vw, 1.24rem); margin-bottom: 0.5rem; color: var(--midnight); }
.ow-price { font-size: 0.85rem; color: var(--ink-soft); margin-bottom: 1rem; }
.ow-price .ow-price-amount { font-size: 1rem; font-weight: 600; color: var(--midnight); }
@@ -920,76 +920,23 @@ 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-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;
.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);
border-radius: var(--radius);
border: 1px solid var(--line-brass);
background: rgba(255,255,255,0.06);
color: #fff;
color: var(--brass);
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;
font-size: 0.85rem;
transition: all 0.2s;
}
.footer-contact-form input[type="email"]:focus,
.footer-contact-form textarea:focus {
.footer-email:hover {
background: rgba(201,162,39,0.12);
border-color: var(--brass);
background: rgba(255,255,255,0.1);
color: #fff;
}
.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; }
+12 -19
View File
@@ -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.html" />
<link rel="canonical" href="https://ODOO4projects.com/support" />
<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.html" />
<meta property="og:url" content="https://ODOO4projects.com/support" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" href="images/favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
@@ -474,7 +474,8 @@
<section class="contact-section" id="contact">
<div class="container">
<h2>Still questions? Contact our support.</h2>
<form class="contact-form" id="supportForm">
<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="" />
<div class="form-group">
<label>Your Name <span class="required">*</span></label>
<input type="text" id="contactName" name="contact_name" required placeholder="Your Name" />
@@ -527,31 +528,23 @@
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...";
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.");
});
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."); });
});
</script>