Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e25e4c64fa | ||
|
|
0f7da0b68b | ||
|
|
db919fc8c2 | ||
|
|
a54dc22bd1 | ||
|
|
ca89d8e7b7 | ||
|
|
29127d4025 | ||
|
|
b4e0faa62e | ||
|
|
575e3efece | ||
|
|
62f92769a1 | ||
|
|
3637094896 | ||
|
|
609f9d64bf | ||
|
|
1ab6c47df6 | ||
|
|
354799b9ca | ||
|
|
04d39157b8 | ||
|
|
5cc0c06a11 | ||
|
|
b003c221ce | ||
|
|
79f2a71d49 | ||
|
|
729289ef71 | ||
|
|
06ed942f8b | ||
|
|
3d1473a2d5 | ||
|
|
e926f850f7 | ||
|
|
eb142d1aa6 | ||
|
|
4d9becd159 | ||
|
|
5f4c75e94f | ||
|
|
d83d960543 | ||
|
|
9751bda35c | ||
|
|
3e899391d7 | ||
|
|
4134ff5260 | ||
|
|
af866d87e8 | ||
|
|
5f52cd6059 | ||
|
|
3605545838 | ||
|
|
246beeb231 | ||
|
|
e5604381da | ||
|
|
aeb465e9dd | ||
|
|
1fb2bdf525 | ||
|
|
d26a3ee725 | ||
|
|
1642497c10 | ||
|
|
f7460c129d | ||
|
|
602329db27 | ||
|
|
a003054781 | ||
|
|
5ddb142c8f | ||
|
|
7245e47cac | ||
|
|
b34e001c46 | ||
|
|
109bcac7f7 | ||
|
|
0ac11bcce0 | ||
|
|
5a6380871d | ||
|
|
fcc972557b | ||
|
|
07de1249cf | ||
|
|
8e5d508b13 | ||
|
|
ba55327400 | ||
|
|
d37ceca9bd | ||
|
|
d58089d194 | ||
|
|
284f59f863 | ||
|
|
09f8b6100f | ||
|
|
ba0aa96d3b | ||
|
|
3b4b1faef7 | ||
|
|
47c187f661 | ||
|
|
5e7549651b | ||
|
|
03e49b2b2c | ||
|
|
413471aceb | ||
|
|
0020477cb1 | ||
|
|
4afa74bd16 | ||
|
|
840982dc2e | ||
|
|
d4e9acd4e3 | ||
|
|
60b41d7453 | ||
|
|
b2d2677a34 | ||
|
|
87874d0f34 | ||
|
|
a24570f187 | ||
|
|
a2cfa09558 | ||
|
|
3e9a6d5c4b | ||
|
|
9a9319e3a3 | ||
|
|
94b5e36d8e | ||
|
|
ad03edb0ee | ||
|
|
9a87d3a5fe | ||
|
|
b5c9361fc9 | ||
|
|
1c362f4683 | ||
|
|
a0ed2c7e9f | ||
|
|
b96c2870ef | ||
|
|
a9328bf383 | ||
|
|
5e315cee0e | ||
|
|
e2e37e18b4 | ||
|
|
d29dd1174f | ||
|
|
fb8c1b7dea | ||
|
|
0d4e39f582 | ||
|
|
2c6f033d43 | ||
|
|
26d113b486 | ||
|
|
b55c121257 | ||
|
|
85334fc4d2 | ||
|
|
cc5667bf7b | ||
|
|
358e480ea6 | ||
|
|
ea449d0769 | ||
|
|
8666714818 | ||
|
|
9891ba5d86 | ||
|
|
7adbcdcbdc | ||
|
|
9a6a435bea | ||
|
|
b2d2d1dbff | ||
|
|
adc41f6e08 | ||
|
|
a4b1c31bbd | ||
|
|
5acea62050 | ||
|
|
38e523f624 | ||
|
|
4f81a3a59b | ||
|
|
59413f5b36 | ||
|
|
60f31286d7 | ||
|
|
1b0ebe3b7e | ||
|
|
dc75fa6655 | ||
|
|
e1180c9268 | ||
|
|
d65913e63e | ||
|
|
e839ea396d | ||
|
|
acea41cdfc | ||
|
|
398ba7ba26 | ||
|
|
706b8e13a8 | ||
|
|
60f45ebfce | ||
|
|
88e9cbd9f5 | ||
|
|
b0cb28a79b | ||
|
|
3639669eb1 | ||
|
|
56cbe820a5 | ||
|
|
52a9817722 | ||
|
|
9dc16202d1 | ||
|
|
45bfc154d7 | ||
|
|
170d351783 | ||
|
|
d2ecfbad3f | ||
|
|
e97e682fdd | ||
|
|
8bb1e73352 | ||
|
|
b643dc914e | ||
|
|
2cc933d7a0 | ||
|
|
b84b0d4bf5 | ||
|
|
129a02ebb2 | ||
|
|
7180fd190d | ||
|
|
7871bacb8a | ||
|
|
ee8d071835 | ||
|
|
7e93e0f099 |
No files matched your search
@@ -0,0 +1,132 @@
|
|||||||
|
---
|
||||||
|
target: homepage index.html
|
||||||
|
total_score: 26
|
||||||
|
max_score: 36
|
||||||
|
na_heuristics: 10
|
||||||
|
p0_count: 3
|
||||||
|
p1_count: 3
|
||||||
|
timestamp: 2026-08-15T09-22-42Z
|
||||||
|
slug: index-html
|
||||||
|
---
|
||||||
|
# ODOO4projects.com Homepage — Design Critique
|
||||||
|
|
||||||
|
Method: dual-agent (A: design review · B: detector + browser evidence)
|
||||||
|
|
||||||
|
## Design Health Score
|
||||||
|
|
||||||
|
| # | Heuristic | Score | Key Issue |
|
||||||
|
|---|-----------|-------|-----------|
|
||||||
|
| 1 | Visibility of System Status | 3/4 | Billing toggle gives feedback; order widget never marks server location as required |
|
||||||
|
| 2 | Match System / Real World | 3/4 | "No FTP, no shenanigans" is borderline informal for B2B hosting voice |
|
||||||
|
| 3 | User Control and Freedom | 2/4 | Order widget: no Escape key, no backdrop-click close, small × target |
|
||||||
|
| 4 | Consistency and Standards | 3/4 | Blog post pages still dark/cyan (legacy); order widget uses ~15 inline styles bypassing tokens |
|
||||||
|
| 5 | Error Prevention | 2/4 | No validation before Stripe redirect — empty `?location=` possible; no pre-checkout confirm |
|
||||||
|
| 6 | Recognition Rather Than Recall | 4/4 | Features fully visible on cards; Most Popular badge kills comparison effort |
|
||||||
|
| 7 | Flexibility and Efficiency | 3/4 | Yearly toggle good; domain-count differences buried in feature text |
|
||||||
|
| 8 | Aesthetic and Minimalist Design | 3/4 | Blog cards after pricing add density to an already long Persuade page |
|
||||||
|
| 9 | Error Recovery | 3/4 | Coupon feedback clear; blog fetch failure shows only "Could not load blog posts." |
|
||||||
|
| 10 | Help and Documentation | n/a | Persuade surface; FAQ tab + support link cover it |
|
||||||
|
| **Total** | | **26/36** | **Good (72%)** |
|
||||||
|
|
||||||
|
## Design Specificity Verdict
|
||||||
|
|
||||||
|
**High specificity — composed for THIS product.** Hero headline ("Deploy Odoo in 5 Minutes"), Odoo-specific features (Quick Git, ODOO Settings Panel, 2 Workers), growth-themed plan names (Side Hustle → Empire), real partner instances in the trust bar, Odoo-specific blog topics, and a custom Stripe routing pattern. The skeleton (icon cards + pricing grid) is a familiar hosting-page pattern, but the content is authentically this product.
|
||||||
|
|
||||||
|
**Deterministic scan:** Detector exit code 2 (44 findings, regex-only mode — HTML parser modules unavailable, so this is an undercount). Real hits: 12 low-contrast green check icons (#28a745 at 2.9:1–3.1:1), 4 undersized functional labels (9.6–9.92px), 2 skipped heading levels, 5 line-length violations, 17 off-ramp font sizes, 19 off-palette colors. The detector caught the contrast and text-size failures that the human review missed — those are its best catches. False positives: `overused-font` (Inter IS the brand font per DESIGN.md), hero gradient midpoint #2a1a26 (within palette family), rgba(33,37,41,X) opacity tones (intentional accessibility variants), em-dash count (moderate for marketing copy).
|
||||||
|
|
||||||
|
**Visual overlays:** Browser injection succeeded; 17 anti-patterns reported in console. No reliable user-visible overlay persists (servers auto-exited after idle).
|
||||||
|
|
||||||
|
## Overall Impression
|
||||||
|
|
||||||
|
A warm, confident, genuinely specific landing page with a working pricing widget and honest social proof. The bones are good. The problems cluster at the edges: legibility (green checks, tiny labels), dismissal (order widget trap), and ending (blog after the conversion point). The single biggest opportunity: turn the post-pricing ending from content exploration back into a conversion moment.
|
||||||
|
|
||||||
|
## What's Working
|
||||||
|
|
||||||
|
1. **The pricing widget plays.** Billing toggle live-updates all four prices; location selector is Odoo-contextual; coupon defaults to "FREE TRIAL" — warm hand-holding most hosts don't do.
|
||||||
|
2. **The dark hero band with Warm Sand CTA** creates sharp hierarchy; the "5 Minutes" highlight in #f0cda8 draws the eye to the value prop; Holland.webp at 8% adds texture without noise.
|
||||||
|
3. **"Your Company" placeholder in the trust bar** is strategically honest — it invites the visitor to imagine themselves there and links to pricing.
|
||||||
|
|
||||||
|
## Priority Issues
|
||||||
|
|
||||||
|
**[P0] Low-contrast green check icons fail WCAG AA** (detector)
|
||||||
|
- **What**: 12 `fa-check` icons in #28a745 on pricing cards — 2.9:1 on Warm Paper, 3.1:1 on white.
|
||||||
|
- **Why**: Below 4.5:1; fails accessibility and reads washed-out on the featured card.
|
||||||
|
- **Fix**: Darken the success green (e.g. #1e7a34) or switch checks to Plum Velvet with green reserved for savings text.
|
||||||
|
- **Command**: /impeccable colorize
|
||||||
|
|
||||||
|
**[P0] Undersized functional text** (detector)
|
||||||
|
- **What**: "1 month free" and "up to -10%" at 9.92px; badge labels "guide"/"news" at 9.6px — below the 10–11px floor.
|
||||||
|
- **Why**: These are decision-relevant (savings, content type); unreadable on mobile.
|
||||||
|
- **Fix**: Raise to ≥0.72rem with 11px minimum; give the toggle sub-labels room.
|
||||||
|
- **Command**: /impeccable typeset
|
||||||
|
|
||||||
|
**[P0] Order widget traps users** (design review)
|
||||||
|
- **What**: `#orderWidgetOverlay` closes only via a 2.4rem × button — no Escape, no backdrop click, undersized touch target.
|
||||||
|
- **Why**: Accidentally opened widget = forced path; mobile users have no convenient exit.
|
||||||
|
- **Fix**: Backdrop click + Escape listener in script.js; enlarge close hit area to ≥2.8rem.
|
||||||
|
- **Command**: /impeccable harden
|
||||||
|
|
||||||
|
**[P1] Hero stats waste prime real estate on redundancy** (design review)
|
||||||
|
- **What**: "Deploy in 5 min" and "Instant setup" say the same thing; two of four stat slots.
|
||||||
|
- **Why**: The hero is the only place for credibility metrics; redundancy forfeits it.
|
||||||
|
- **Fix**: Replace "Instant setup" with a real metric (uptime, instances deployed, avg deploy time).
|
||||||
|
- **Command**: /impeccable layout
|
||||||
|
|
||||||
|
**[P1] Empire plan: blank feature row + weakest CTA on the highest-margin plan** (design review)
|
||||||
|
- **What**: `<li><br/></li>` blank entry in the feature list; "Contact Us" as outline button vs "Buy Now" primaries below it.
|
||||||
|
- **Why**: Blank row reads as "ran out of things to say"; the custom plan should be the most confident ask.
|
||||||
|
- **Fix**: Replace blank row with a concrete feature; make CTA "Get Custom Quote" in primary style.
|
||||||
|
- **Command**: /impeccable clarify
|
||||||
|
|
||||||
|
**[P1] Skipped heading levels hurt structure** (detector)
|
||||||
|
- **What**: h1→h3 (missing h2) at hero→features; h3→h5 (missing h4) at blog→footer; footer uses h5s.
|
||||||
|
- **Why**: Screen-reader navigation and outline integrity for assistive tech.
|
||||||
|
- **Fix**: Promote features-strip headings to h2; footer headings to h3/p.
|
||||||
|
- **Command**: /impeccable audit
|
||||||
|
|
||||||
|
**[P2] Blog after pricing weakens the conversion ending** (design review + synthesis)
|
||||||
|
- **What**: Page ends on content exploration ("Read more →") right after the pricing decision.
|
||||||
|
- **Why**: Peak-end rule — the emotional close should reinforce the decision, not invite second-guessing.
|
||||||
|
- **Fix**: Replace trailing blog grid with a final CTA band ("Ready to deploy?" + pricing link), or move blog above pricing.
|
||||||
|
- **Command**: /impeccable layout
|
||||||
|
|
||||||
|
**[P2] "Satisfied or reimbursed" is undefined** (design review)
|
||||||
|
- **What**: Strong claim with no qualifier anywhere.
|
||||||
|
- **Why**: "Reimbursed for what, when?" introduces a tiny trust question at the exact conversion moment.
|
||||||
|
- **Fix**: Add a time qualifier ("within 7 days") or link to legal.html.
|
||||||
|
- **Command**: /impeccable clarify
|
||||||
|
|
||||||
|
**[P2] Weak features-strip hierarchy** (design review)
|
||||||
|
- **What**: Feature h3s at 0.9rem compete with their own descriptions; line-height 1.
|
||||||
|
- **Why**: The first value-prop section after social proof should lead the eye, not whisper.
|
||||||
|
- **Fix**: h3 to 1rem+, line-height 1.3, tighter tracking.
|
||||||
|
- **Command**: /impeccable typeset
|
||||||
|
|
||||||
|
## Persona Red Flags
|
||||||
|
|
||||||
|
**Jordan (first-timer)**:
|
||||||
|
- Tab 1 contains nested `<strong>` tags ("Full management through your <strong>ODOO Settings Panel</strong>") — invalid HTML, visually noisy, and "ODOO Settings Panel" is unexplained jargon.
|
||||||
|
- FAQ tab has only 4 questions — no "What is Odoo?" or "Do I need to know code?"; feels like a teaser, not help.
|
||||||
|
|
||||||
|
**Riley (stress tester / comparison shopper)**:
|
||||||
|
- On the Rise (featured, $36.25) is 87% more than Side Hustle ($19.40) with the only listed difference being Git module installs — the price jump needs a clearer justification or feature gap.
|
||||||
|
- Empire: "Our service on your server" doesn't answer who provides infrastructure or whether it's BYO cloud.
|
||||||
|
|
||||||
|
**Casey (mobile, on-the-go)**:
|
||||||
|
- Trust bar partner row (7 items, 2rem gaps) forces horizontal scrolling on 390px viewports; logos read as tiny unlabeled icons.
|
||||||
|
- Billing toggle sub-labels at 0.62rem are barely legible; 48×26px switch is a tight thumb target.
|
||||||
|
|
||||||
|
## Minor Observations
|
||||||
|
|
||||||
|
- Order widget ~15 inline styles bypass the CSS custom properties — theming drift.
|
||||||
|
- Footer uses h5 headings ("Useful Links," "About us," "Follow us on") — odd semantics.
|
||||||
|
- "AccellerSales" spelling (double l) in the trust bar — verify.
|
||||||
|
- Chat widget (agent.js) overlaps the footer on narrow viewports.
|
||||||
|
- Holland.webp hero texture's purpose is unclear — if it signals the NL data region, label it.
|
||||||
|
- script.js `isEmpire` param naming is unclear (controls CTA style, not price).
|
||||||
|
|
||||||
|
## Questions to Consider
|
||||||
|
|
||||||
|
- Why does "On the Rise" carry "Most Popular" when Side Hustle is 47% cheaper — is that badge conversion data or a guess? Would "Recommended — best value for growing teams" be more honest?
|
||||||
|
- The page says "No DevOps required" then features "Git-based module deployment" — who is actually reading this page, the owner or their technical contact?
|
||||||
|
- What if the highest-priced plan made the strongest ask instead of the weakest?
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 2,
|
||||||
|
"generatedAt": "2026-08-15T09:01:14Z",
|
||||||
|
"title": "Design System: ODOO4projects",
|
||||||
|
"extensions": {
|
||||||
|
"colorMeta": {
|
||||||
|
"plum-velvet": {
|
||||||
|
"role": "primary",
|
||||||
|
"displayName": "Plum Velvet",
|
||||||
|
"canonical": "#714b67",
|
||||||
|
"tonalRamp": ["#3b2b37","#402639","#46203c","#4c1a3f","#521442","#580e44","#5e0847","#63034a"]
|
||||||
|
},
|
||||||
|
"deep-plum": {
|
||||||
|
"role": "primary",
|
||||||
|
"displayName": "Deep Plum",
|
||||||
|
"canonical": "#65435c",
|
||||||
|
"tonalRamp": ["#3b2b37","#402639","#46203c","#4c1a3f","#521442","#580e44","#5e0847","#63034a"]
|
||||||
|
},
|
||||||
|
"warm-sand": {
|
||||||
|
"role": "secondary",
|
||||||
|
"displayName": "Warm Sand",
|
||||||
|
"canonical": "#f0cda8",
|
||||||
|
"tonalRamp": ["#c0b5aa","#c8b6a2","#d1b699","#d9b691","#e2b788","#eab780","#f3b777","#fbb76f"]
|
||||||
|
},
|
||||||
|
"ink-cocoa": {
|
||||||
|
"role": "neutral",
|
||||||
|
"displayName": "Ink Cocoa",
|
||||||
|
"canonical": "#1b1319",
|
||||||
|
"tonalRamp": ["#32252f","#372031","#3c1b34","#411636","#461139","#4b0c3b","#50073e","#550240"]
|
||||||
|
},
|
||||||
|
"warm-paper": {
|
||||||
|
"role": "neutral",
|
||||||
|
"displayName": "Warm Paper",
|
||||||
|
"canonical": "#f6f5f4",
|
||||||
|
"tonalRamp": ["#acaaa9","#bab7b5","#c8c4c1","#d5d1ce","#e3dfdb","#f1ece7","#f8f3ef","#fefaf5"]
|
||||||
|
},
|
||||||
|
"parchment": {
|
||||||
|
"role": "neutral",
|
||||||
|
"displayName": "Parchment",
|
||||||
|
"canonical": "#e5e3e0",
|
||||||
|
"tonalRamp": ["#9e9c9a","#acaaa7","#bab8b5","#c9c6c2","#d7d4d0","#e5e2de","#f4f0eb","#fefaf6"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typographyMeta": {
|
||||||
|
"display": {
|
||||||
|
"displayName": "Display",
|
||||||
|
"purpose": "Hero H1 only. Inter Tight 800, clamp(2rem, 4.5vw, 3.2rem), 1.15 line-height."
|
||||||
|
},
|
||||||
|
"headline": {
|
||||||
|
"displayName": "Headline",
|
||||||
|
"purpose": "Section H2s. Inter Tight 600, clamp(1.8rem, 3.2vw, 2.8rem), 1.25 line-height."
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"displayName": "Title",
|
||||||
|
"purpose": "Card H3s, plan names, tab headers. Inter Tight 600, clamp(1.1rem, 2vw, 1.4rem), 1.25."
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"displayName": "Body",
|
||||||
|
"purpose": "Paragraph text. Inter 400, 1rem, 1.6 line-height. Max ~580-680ch in prose."
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"displayName": "Label",
|
||||||
|
"purpose": "Meta text, plan features, small-print, tab subtitles. Inter Tight 500, 0.82rem, 0.04em letter-spacing."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shadows": [
|
||||||
|
{
|
||||||
|
"name": "card-rest",
|
||||||
|
"value": "0 1px 3px rgba(0,0,0,0.06)",
|
||||||
|
"purpose": "Baseline pricing card shadow at rest."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "card-hover",
|
||||||
|
"value": "0 4px 16px rgba(0,0,0,0.08)",
|
||||||
|
"purpose": "Interactive card hover, paired with translateY(-2px/-3px)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "toggle-thumb",
|
||||||
|
"value": "0 1px 3px rgba(0,0,0,0.15)",
|
||||||
|
"purpose": "Billing toggle thumb shadow."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blog-hover",
|
||||||
|
"value": "0 4px 20px rgba(113,75,103,0.08)",
|
||||||
|
"purpose": "Blog card hover on the light theme variant (homepage)."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"motion": [
|
||||||
|
{
|
||||||
|
"name": "state-transition",
|
||||||
|
"value": "all 0.2s",
|
||||||
|
"purpose": "Default easing for state transitions (hover, focus, active)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "partner-scroll",
|
||||||
|
"value": "40s linear infinite",
|
||||||
|
"purpose": "Seamless partner logo carousel animation."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "spinner",
|
||||||
|
"value": "0.8s linear infinite",
|
||||||
|
"purpose": "Loading spinner rotation."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "toggle",
|
||||||
|
"value": "left 0.25s, background 0.25s",
|
||||||
|
"purpose": "Billing toggle switch animation."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"breakpoints": [
|
||||||
|
{ "name": "lg", "value": "992px" },
|
||||||
|
{ "name": "md", "value": "768px" },
|
||||||
|
{ "name": "sm", "value": "576px" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"name": "Primary Button",
|
||||||
|
"kind": "button",
|
||||||
|
"refersTo": "button-primary",
|
||||||
|
"description": "Primary call-to-action on light surfaces. Use once per section.",
|
||||||
|
"html": "<button class=\"ds-btn-primary\">See Plans & Pricing</button>",
|
||||||
|
"css": ".ds-btn-primary{display:inline-block;padding:0.6rem 1.5rem;font-family:'Inter Tight','Inter',sans-serif;font-size:0.9rem;font-weight:500;background:#714b67;color:#fff;border:1px solid #714b67;border-radius:0.5rem;cursor:pointer;text-decoration:none;transition:all 0.2s}.ds-btn-primary:hover{background:#65435c;border-color:#65435c;transform:translateY(-1px)}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Hero Button",
|
||||||
|
"kind": "button",
|
||||||
|
"refersTo": "button-hero",
|
||||||
|
"description": "Primary call-to-action inside the dark hero band. Warm Sand on Ink Cocoa.",
|
||||||
|
"html": "<a class=\"ds-btn-hero\">Deploy in 5 Minutes</a>",
|
||||||
|
"css": ".ds-btn-hero{display:inline-block;padding:0.85rem 2.5rem;background:#f0cda8;color:#1b1319;border-radius:0.5rem;font-family:'Inter Tight','Inter',sans-serif;font-size:1rem;font-weight:700;text-decoration:none;transition:opacity 0.2s,transform 0.2s}.ds-btn-hero:hover{opacity:0.9;transform:translateY(-2px)}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Outline Button",
|
||||||
|
"kind": "button",
|
||||||
|
"refersTo": "button-outline",
|
||||||
|
"description": "Secondary/ghost action. Deep Plum border.",
|
||||||
|
"html": "<button class=\"ds-btn-outline\">How It Works</button>",
|
||||||
|
"css": ".ds-btn-outline{display:inline-block;padding:0.85rem 1.5rem;background:transparent;color:#65435c;border:1px solid #65435c;border-radius:0.5rem;font-family:'Inter Tight','Inter',sans-serif;font-size:0.9rem;text-decoration:none;transition:all 0.2s;cursor:pointer}.ds-btn-outline:hover{background:#65435c;color:#fff}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pricing Card",
|
||||||
|
"kind": "card",
|
||||||
|
"refersTo": "card-pricing",
|
||||||
|
"description": "Pricing plan card. Featured variant adds Plum Velvet border + Most Popular pill.",
|
||||||
|
"html": "<div class=\"ds-card-pricing featured\"><div class=\"ds-card-badge\">Most Popular</div><h3>On the Rise</h3><div class=\"ds-card-price\"><strong>$36.25</strong> <small>/month</small></div><p class=\"ds-card-desc\">I need some modules and professional reports</p><ul><li><svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#28a745\" stroke-width=\"3\"><polyline points=\"20 6 9 17 4 12\"/></svg> ODOO CE Hosting</li><li><svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#28a745\" stroke-width=\"3\"><polyline points=\"20 6 9 17 4 12\"/></svg> Automatic Backups</li><li><svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#28a745\" stroke-width=\"3\"><polyline points=\"20 6 9 17 4 12\"/></svg> Module installation via GIT</li></ul><button class=\"ds-btn-primary\" style=\"width:100%;box-sizing:border-box\">Buy Now</button></div>",
|
||||||
|
"css": ".ds-card-pricing{background:#fff;border:1px solid #e5e3e0;border-radius:1rem;overflow:hidden;display:flex;flex-direction:column;transition:all 0.3s;box-shadow:0 1px 3px rgba(0,0,0,0.06)}.ds-card-pricing.featured{border:2px solid #714b67;position:relative}.ds-card-pricing:hover{box-shadow:0 4px 16px rgba(0,0,0,0.08);transform:translateY(-3px)}.ds-card-badge{position:absolute;top:0.75rem;right:0.75rem;background:#714b67;color:#fff;padding:0.2rem 0.6rem;border-radius:2rem;font-size:0.6rem;font-weight:600}.ds-card-pricing h3{font-family:'Inter Tight',sans-serif;font-size:1.1rem;font-weight:700;margin:0 0 0.5rem}.ds-card-price{margin:0.5rem 0}.ds-card-price strong{font-size:clamp(1.28rem,2vw,1.92rem);color:#1b1319}.ds-card-price small{color:rgba(33,37,41,0.55);font-size:0.82rem}.ds-card-desc{font-size:0.82rem;color:rgba(33,37,41,0.6);font-style:italic;min-height:3rem}.ds-card-pricing ul{list-style:none;padding:0;margin:0;flex-grow:1}.ds-card-pricing li{padding:0.4rem 0;font-size:0.82rem;border-bottom:1px solid rgba(0,0,0,0.05);display:flex;align-items:center;gap:0.4rem}.ds-card-pricing .ds-btn-primary{margin-top:0.75rem}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Search Input",
|
||||||
|
"kind": "input",
|
||||||
|
"refersTo": "input",
|
||||||
|
"description": "Blog search / general text input on light surfaces.",
|
||||||
|
"html": "<div style=\"position:relative\"><svg style=\"position:absolute;left:0.75rem;top:50%;transform:translateY(-50%);color:rgba(33,37,41,0.35)\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.35-4.35\"/></svg><input class=\"ds-input\" type=\"text\" placeholder=\"Search posts...\"></div>",
|
||||||
|
"css": ".ds-input{width:100%;padding:0.75rem 1rem 0.75rem 2.5rem;font-size:0.85rem;font-family:Inter,sans-serif;background:#fff;border:1px solid #e5e3e0;border-radius:0.5rem;color:#212529;outline:none;transition:border-color 0.2s;box-sizing:border-box}.ds-input:focus{border-color:#714b67;box-shadow:0 0 0 2px rgba(113,75,103,0.15)}.ds-input::placeholder{color:rgba(33,37,41,0.35)}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Navigation Tab (Active)",
|
||||||
|
"kind": "nav",
|
||||||
|
"refersTo": "tab-active",
|
||||||
|
"description": "Mission tab navigation — vertical rail on desktop, horizontal scroll on mobile.",
|
||||||
|
"html": "<nav style=\"display:flex;flex-direction:column;gap:0.25rem;width:220px\"><button class=\"ds-tab active\">Our Mission<small>What makes us different</small></button><button class=\"ds-tab\">Competitive Edge<small>We practice what we preach</small></button><button class=\"ds-tab\">Infrastructure<small>How we scale with you</small></button></nav>",
|
||||||
|
"css": ".ds-tab{display:block;padding:0.6rem 1rem;color:#212529;border-radius:0.6rem;border:none;background:none;width:100%;text-align:left;font-family:'Inter Tight','Inter',sans-serif;font-size:0.9rem;font-weight:500;cursor:pointer;transition:all 0.2s}.ds-tab:hover{background:#f6f5f4}.ds-tab.active{background:linear-gradient(135deg,rgba(113,75,103,0.08),rgba(113,75,103,0.03));color:#714b67;font-weight:600;border-left:3px solid #714b67}.ds-tab small{display:block;color:rgba(33,37,41,0.55);font-size:0.72rem;margin-top:0.1rem}.ds-tab.active small{color:rgba(113,75,103,0.6)}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Billing Toggle",
|
||||||
|
"kind": "custom",
|
||||||
|
"refersTo": "toggle-switch",
|
||||||
|
"description": "Monthly / Yearly billing toggle with sliding thumb.",
|
||||||
|
"html": "<div style=\"display:flex;align-items:center;justify-content:center;gap:0.75rem\"><span class=\"ds-toggle-label active\">Monthly<small>1 month free</small></span><div class=\"ds-toggle-switch\"><div class=\"ds-toggle-thumb\"></div></div><span class=\"ds-toggle-label\">Yearly<small>up to -10%</small></span></div>",
|
||||||
|
"css": ".ds-toggle-label{font-size:0.82rem;font-weight:500;color:rgba(33,37,41,0.6);cursor:pointer;transition:color 0.2s;user-select:none}.ds-toggle-label.active{color:#1b1319;font-weight:600}.ds-toggle-label small{display:block;font-size:0.62rem;font-weight:400;color:#28a745;margin-top:0.1rem}.ds-toggle-switch{width:48px;height:26px;background:#e5e3e0;border-radius:13px;cursor:pointer;position:relative;transition:background 0.25s;flex-shrink:0}.ds-toggle-thumb{position:absolute;top:3px;left:3px;width:20px;height:20px;background:#fff;border-radius:50%;transition:left 0.25s;box-shadow:0 1px 3px rgba(0,0,0,0.15)}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Blog Card",
|
||||||
|
"kind": "card",
|
||||||
|
"refersTo": "card-blog",
|
||||||
|
"description": "Blog post card on the homepage (light theme variant).",
|
||||||
|
"html": "<div class=\"ds-card-blog\"><div class=\"ds-card-blog-top\"><span class=\"ds-badge-guide\">guide</span><span class=\"ds-badge-agent\">AI</span></div><div class=\"ds-card-blog-date\">June 27, 2026</div><h3><a href=\"#\">Odoo Community vs. Enterprise: The Real Cost Breakdown (2026)</a></h3><p class=\"ds-card-blog-teaser\">A transparent cost comparison including hosting, licensing, and hidden costs for 5, 10, and 25-user teams.</p><a href=\"#\" class=\"ds-card-blog-link\">Read more →</a></div>",
|
||||||
|
"css": ".ds-card-blog{background:#fff;border:1px solid #e5e3e0;border-radius:0.6rem;padding:1.25rem;display:flex;flex-direction:column;transition:transform 0.2s,border-color 0.2s,box-shadow 0.2s}.ds-card-blog:hover{transform:translateY(-2px);border-color:#714b67;box-shadow:0 4px 20px rgba(113,75,103,0.08)}.ds-card-blog-top{display:flex;align-items:center;gap:0.5rem;margin-bottom:0.75rem;flex-wrap:wrap}.ds-badge-guide{display:inline-block;padding:0.15rem 0.5rem;border-radius:3rem;font-size:0.6rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;color:#08080c;background:#a78bfa}.ds-badge-agent{display:inline-block;padding:0.15rem 0.45rem;border-radius:3rem;font-size:0.56rem;font-weight:600;background:rgba(113,75,103,0.1);color:#714b67;border:1px solid rgba(113,75,103,0.2)}.ds-card-blog-date{font-size:0.82rem;color:rgba(33,37,41,0.45);margin-bottom:0.4rem}.ds-card-blog h3{margin:0 0 0.5rem}.ds-card-blog h3 a{font-family:'Inter Tight',sans-serif;font-size:1.1rem;font-weight:600;line-height:1.35;color:#1b1319;text-decoration:none;transition:color 0.2s}.ds-card-blog h3 a:hover{color:#714b67}.ds-card-blog-teaser{font-size:0.9rem;color:rgba(33,37,41,0.6);line-height:1.55;margin:0 0 1rem;flex:1}.ds-card-blog-link{font-size:0.85rem;color:#714b67;text-decoration:none;font-weight:500;transition:opacity 0.2s;margin-top:auto}.ds-card-blog-link:hover{opacity:0.75}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"narrative": {
|
||||||
|
"northStar": "The Global Workbench",
|
||||||
|
"overview": "ODOO4projects is a managed Odoo hosting brand built on a warm, quietly premium plum-and-sand palette. The system's personality is warm, trustworthy, quietly premium — infrastructure that feels approachable and dependable for business owners who are not sysadmins. The North Star — The Global Workbench — names the promise: tools are pre-configured, the bench is set up, and the work is ready to start anywhere in the world. The interface is light by default: Warm Paper surfaces on white, Ink Cocoa text, with Plum Velvet as the single strong accent and Warm Sand as its warm counterpoint. Components are tactile and confident: rounded corners, solid buttons, immediate hover feedback, small upward lifts. Depth is currently subtle (flat at rest, gentle lift on interaction) and is slated to deepen.",
|
||||||
|
"keyCharacteristics": [
|
||||||
|
"Light, warm surfaces with one strong plum accent and a peach counterpoint",
|
||||||
|
"Generous, centered layout with clear vertical rhythm",
|
||||||
|
"Tactile, confident components with rounded corners (0.5–1rem)",
|
||||||
|
"Subtle interaction-driven elevation — flat at rest, lift on hover",
|
||||||
|
"Inter Tight for display/headings, Inter for body",
|
||||||
|
"No emojis, no gradients-as-decoration, no dark surfaces in the brand system (legacy dark blog theme is being phased out)"
|
||||||
|
],
|
||||||
|
"rules": [
|
||||||
|
{ "name": "The One-Accent Rule", "body": "Plum Velvet is the only full-strength accent. Green is reserved exclusively for functional success states.", "section": "colors" },
|
||||||
|
{ "name": "The Warmth Rule", "body": "Every neutral must land warm — plum-tinted grays, never cold blue-grays.", "section": "colors" },
|
||||||
|
{ "name": "The Small-Print Silence Rule", "body": "Label text is always one or two steps quieter in color so it never raises its voice over headline content.", "section": "typography" },
|
||||||
|
{ "name": "The Flat-By-Default Rule", "body": "Surfaces are flat at rest. Shadow and lift appear only as a response to hover, focus, or active state.", "section": "elevation" }
|
||||||
|
],
|
||||||
|
"dos": [
|
||||||
|
"Do lead with Plum Velvet for any single accent moment — the button, the active tab, the featured border.",
|
||||||
|
"Do keep all neutrals warm; any gray on the page should read as plum-tinted or sand-tinted, not blue.",
|
||||||
|
"Do use warm, client-focused copy with short sentences and bullets; no tech jargon, no emojis.",
|
||||||
|
"Do keep section containers centered at 80% / max 1300px and let sections breathe at 2–3rem padding.",
|
||||||
|
"Do give interactive elements an immediate hover response — a lift, a fill change, or a border shift within 0.2s.",
|
||||||
|
"Do use the pill for badges and the lg radius for cards; consistency of the radius ladder is what makes the system feel composed."
|
||||||
|
],
|
||||||
|
"donts": [
|
||||||
|
"Don't use the legacy dark/cyan blog theme (#08080c background, #00f5ff cyan accents) — it is an older style being phased out; the brand is the plum/peach light system only.",
|
||||||
|
"Don't paint large areas Plum Velvet; it is an accent, not a surface.",
|
||||||
|
"Don't introduce additional accent colors; green belongs to success states only.",
|
||||||
|
"Don't use sharp rectangular corners (0 radius) on interactive elements.",
|
||||||
|
"Don't decorate with gradients other than the established hero band and the primary-to-secondary 'hr' divider.",
|
||||||
|
"Don't add permanent shadows to resting surfaces; depth responds to interaction."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"files": ["index.html", "support.html", "legal.html"],
|
||||||
|
"insertBefore": "</body>",
|
||||||
|
"commentSyntax": "html",
|
||||||
|
"cspChecked": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
---
|
||||||
|
name: ODOO4projects
|
||||||
|
description: Managed Odoo hosting — the Global Workbench. Warm plum and sand, enterprise-grade but approachable.
|
||||||
|
colors:
|
||||||
|
plum-velvet: "#714b67"
|
||||||
|
deep-plum: "#65435c"
|
||||||
|
warm-sand: "#f0cda8"
|
||||||
|
ink-cocoa: "#1b1319"
|
||||||
|
warm-paper: "#f6f5f4"
|
||||||
|
parchment: "#e5e3e0"
|
||||||
|
white: "#ffffff"
|
||||||
|
typography:
|
||||||
|
display:
|
||||||
|
fontFamily: "'Inter Tight', 'Inter', sans-serif"
|
||||||
|
fontSize: "clamp(2rem, 4.5vw, 3.2rem)"
|
||||||
|
fontWeight: 800
|
||||||
|
lineHeight: 1.15
|
||||||
|
headline:
|
||||||
|
fontFamily: "'Inter Tight', 'Inter', sans-serif"
|
||||||
|
fontSize: "clamp(1.8rem, 3.2vw, 2.8rem)"
|
||||||
|
fontWeight: 600
|
||||||
|
lineHeight: 1.25
|
||||||
|
title:
|
||||||
|
fontFamily: "'Inter Tight', 'Inter', sans-serif"
|
||||||
|
fontSize: "clamp(1.1rem, 2vw, 1.4rem)"
|
||||||
|
fontWeight: 600
|
||||||
|
lineHeight: 1.25
|
||||||
|
body:
|
||||||
|
fontFamily: "Inter, 'Segoe UI', sans-serif"
|
||||||
|
fontSize: "1rem"
|
||||||
|
fontWeight: 400
|
||||||
|
lineHeight: 1.6
|
||||||
|
label:
|
||||||
|
fontFamily: "'Inter Tight', 'Inter', sans-serif"
|
||||||
|
fontSize: "0.82rem"
|
||||||
|
fontWeight: 500
|
||||||
|
letterSpacing: "0.04em"
|
||||||
|
rounded:
|
||||||
|
sm: "0.5rem"
|
||||||
|
md: "0.6rem"
|
||||||
|
lg: "1rem"
|
||||||
|
pill: "2rem"
|
||||||
|
spacing:
|
||||||
|
xs: "0.25rem"
|
||||||
|
sm: "0.5rem"
|
||||||
|
md: "1rem"
|
||||||
|
lg: "1.5rem"
|
||||||
|
xl: "2rem"
|
||||||
|
components:
|
||||||
|
button-primary:
|
||||||
|
backgroundColor: "{colors.plum-velvet}"
|
||||||
|
textColor: "{colors.white}"
|
||||||
|
rounded: "{rounded.sm}"
|
||||||
|
padding: "0.6rem 1.5rem"
|
||||||
|
button-primary-hover:
|
||||||
|
backgroundColor: "{colors.deep-plum}"
|
||||||
|
textColor: "{colors.white}"
|
||||||
|
rounded: "{rounded.sm}"
|
||||||
|
padding: "0.6rem 1.5rem"
|
||||||
|
button-hero:
|
||||||
|
backgroundColor: "{colors.warm-sand}"
|
||||||
|
textColor: "{colors.ink-cocoa}"
|
||||||
|
rounded: "{rounded.sm}"
|
||||||
|
padding: "0.85rem 2.5rem"
|
||||||
|
button-outline:
|
||||||
|
textColor: "{colors.deep-plum}"
|
||||||
|
rounded: "{rounded.sm}"
|
||||||
|
padding: "0.6rem 1.5rem"
|
||||||
|
card-pricing:
|
||||||
|
backgroundColor: "{colors.white}"
|
||||||
|
rounded: "{rounded.lg}"
|
||||||
|
padding: "1.25rem"
|
||||||
|
tab-active:
|
||||||
|
textColor: "{colors.plum-velvet}"
|
||||||
|
rounded: "{rounded.md}"
|
||||||
|
padding: "0.6rem 1rem"
|
||||||
|
input:
|
||||||
|
backgroundColor: "{colors.white}"
|
||||||
|
rounded: "{rounded.sm}"
|
||||||
|
padding: "0.75rem 1rem"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Design System: ODOO4projects
|
||||||
|
|
||||||
|
**Creative North Star: "The Global Workbench"**
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
ODOO4projects is a managed Odoo hosting brand built on a warm, quietly premium plum-and-sand palette. The system's personality is "warm, trustworthy, quietly premium — infrastructure that feels approachable and dependable" for business owners who are not sysadmins. The North Star — *The Global Workbench* — names the promise: tools are pre-configured, the bench is set up, and the work is ready to start anywhere in the world. Six global data regions are a literal fact of the product and the visual system leans into that reach.
|
||||||
|
|
||||||
|
The interface is light by default: Warm Paper surfaces on white, Ink Cocoa text, with Plum Velvet as the single strong accent and Warm Sand as its warm counterpoint. Density is relaxed — generous section padding, centered constrained containers (80% width, max 1300px) — and the tone is conversational, not technical. Components are tactile and confident: rounded corners, solid buttons, immediate hover feedback, small upward lifts. Depth is currently subtle (flat at rest, gentle lift on interaction) and is slated to deepen.
|
||||||
|
|
||||||
|
The homepage is a single long persuasion surface: hero → trust bar → features → mission tabs → how-it-works → pricing → blog → footer. Tabs and pricing cards carry the interactive weight; everything else is rhythm.
|
||||||
|
|
||||||
|
**Key Characteristics:**
|
||||||
|
- Light, warm surfaces with one strong plum accent and a peach counterpoint
|
||||||
|
- Generous, centered layout with clear vertical rhythm
|
||||||
|
- Tactile, confident components with rounded corners (0.5–1rem)
|
||||||
|
- Subtle interaction-driven elevation — flat at rest, lift on hover
|
||||||
|
- Inter Tight for display/headings, Inter for body
|
||||||
|
- No emojis, no gradients-as-decoration, no dark surfaces in the brand system (legacy dark blog theme is being phased out)
|
||||||
|
|
||||||
|
## Colors
|
||||||
|
|
||||||
|
The palette is warm through and through — every neutral carries a whisper of plum or sand. Plum Velvet does the brand's talking; Warm Sand does the welcoming; Warm Paper and Parchment do the quiet work.
|
||||||
|
|
||||||
|
### Primary
|
||||||
|
- **Plum Velvet** (#714b67): The brand accent. Primary buttons, active tabs, featured plan border, footer social hover, link color context. Used sparingly — as fills on buttons and edges on active states, never as a wash across large areas.
|
||||||
|
- **Deep Plum** (#65435c): Hover/darker variant of the accent. Primary button hover, outline button text and border.
|
||||||
|
|
||||||
|
### Secondary
|
||||||
|
- **Warm Sand** (#f0cda8): The welcoming counterpoint. Hero primary CTA background with Ink Cocoa text, the "hr" divider gradient, hero headline accent span. Reads as warm light, not cautionary yellow.
|
||||||
|
|
||||||
|
### Neutral
|
||||||
|
- **Warm Paper** (#f6f5f4): Section backgrounds (trust bar, how-it-works, pricing, light blog override). One step off pure white.
|
||||||
|
- **Parchment** (#e5e3e0): Borders, dividers, card edges, toggle-switch off state.
|
||||||
|
- **Ink Cocoa** (#1b1319): Text on light surfaces, footer background, hero gradient base, headline color, price figures.
|
||||||
|
- **White** (#ffffff): Main page background, card backgrounds, text on Plum Velvet buttons.
|
||||||
|
|
||||||
|
### Named Rules
|
||||||
|
**The Warmth Rule.** Every neutral must land warm — plum-tinted grays, never cold blue-grays. When choosing a gray, err toward the sand side.
|
||||||
|
|
||||||
|
**The One-Accent Rule.** Plum Velvet is the only full-strength accent. Green (#28a745) is reserved exclusively for functional success states (checkmarks, savings labels); it never competes as a brand color.
|
||||||
|
|
||||||
|
## Typography
|
||||||
|
|
||||||
|
**Display Font:** Inter Tight (fallback Inter, sans-serif)
|
||||||
|
**Body Font:** Inter (fallback Segoe UI, sans-serif)
|
||||||
|
|
||||||
|
**Character:** A quiet Swiss pairing — Inter Tight carries headings with slightly condensed confidence; Inter carries body copy with neutral legibility. The hierarchy leans on weight and size contrast rather than color.
|
||||||
|
|
||||||
|
### Hierarchy
|
||||||
|
- **Display** (800, clamp(2rem, 4.5vw, 3.2rem), 1.15): Hero H1 only (e.g. "Deploy Odoo in 5 Minutes — Fully Managed Hosting"). Accent span in Warm Sand.
|
||||||
|
- **Headline** (600, clamp(1.8rem, 3.2vw, 2.8rem), 1.25): Section H2s ("Your Plan, Your Timing: Upgrade Anytime", "Latest from the Blog").
|
||||||
|
- **Title** (600, clamp(1.1rem, 2vw, 1.4rem), 1.25): Card H3s, tab names, plan names.
|
||||||
|
- **Body** (400, 1rem, 1.6): Paragraph text; line lengths held to ~580–680px in hero and section intro blocks.
|
||||||
|
- **Label** (500, 0.82rem, 0.04em): Meta text — plan features, small-print, tab subtitles, footer links. The trust-bar kicker ("Trusted by businesses worldwide") is uppercase at 0.75rem with 0.08em tracking.
|
||||||
|
|
||||||
|
### Named Rules
|
||||||
|
**The Small-Print Silence Rule.** Label text is always one or two steps quieter in color (55–70% opacity of its surface's text color) so it never raises its voice over headline content.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
A single centered column system: `.container` at 80% width, max 1300px, with 20px side padding. Sections stack in full-bleed bands that alternate Warm Paper and White to create rhythm without borders.
|
||||||
|
|
||||||
|
- **Hero:** full-bleed dark band (Ink Cocoa gradient 135deg #1b1319 → #2a1a26 → #3d2235) with a faint country-map image at 8% opacity, content left-aligned, max 720px headline width.
|
||||||
|
- **Trust bar:** Warm Paper strip, centered kicker, seamless looping partner logo carousel (40s linear, pause on hover).
|
||||||
|
- **Feature strip:** auto-fit grid, min 220px columns.
|
||||||
|
- **Mission tabs:** 220px fixed left rail + fluid content; below 992px the rail becomes a horizontal scrollable tab row with a bottom border indicator.
|
||||||
|
- **How-it-works:** 3-step centered grid (max 800px), numbered circles.
|
||||||
|
- **Pricing:** 4-column grid → 2 → 1 at 992px / 576px; featured card gets a Plum Velvet border and a "Most Popular" pill.
|
||||||
|
- **Blog:** 3-column card grid → 2 → 1 at 992px / 576px.
|
||||||
|
- **Footer:** Ink Cocoa band; 3 columns (1.5fr 3fr 3.5fr) collapsing to 1 column at 992px.
|
||||||
|
|
||||||
|
**Spacing rhythm:** sections breathe at 2–3rem vertical padding; cards use 1.25rem internal padding; grids gap at 1–1.5rem (features 1.5rem, pricing 1rem, blog 1.25rem).
|
||||||
|
|
||||||
|
## Elevation & Depth
|
||||||
|
|
||||||
|
The system is **flat at rest with interaction-driven lift**. Cards at rest carry only a whisper of shadow (0 1px 3px rgba(0,0,0,0.06)) or none; on hover they rise — translateY(-2px to -3px) with a soft shadow (0 4px 16px rgba(0,0,0,0.08)). Buttons lift 1–2px on hover. The hero band is the exception: it is the one physically "deep" surface, built from color gradient and imagery rather than shadow.
|
||||||
|
|
||||||
|
**Forward direction (user-confirmed):** depth is currently conservative and is intended to *increase*. Future work should add more pronounced elevation, layered surfaces, or subtle depth cues without abandoning the flat-at-rest principle.
|
||||||
|
|
||||||
|
### Shadow Vocabulary
|
||||||
|
- **Card rest** (`0 1px 3px rgba(0,0,0,0.06)`): baseline pricing cards.
|
||||||
|
- **Card hover** (`0 4px 16px rgba(0,0,0,0.08)`): interactive cards on hover, paired with translateY(-2px/-3px).
|
||||||
|
- **Toggle thumb** (`0 1px 3px rgba(0,0,0,0.15)`): the billing toggle's sliding thumb.
|
||||||
|
|
||||||
|
### Named Rules
|
||||||
|
**The Flat-By-Default Rule.** Surfaces are flat at rest. Shadow and lift appear only as a response to hover, focus, or active state — never as permanent decoration.
|
||||||
|
|
||||||
|
## Shapes
|
||||||
|
|
||||||
|
The form language is soft and approachable: everything rounds off, nothing is sharp enough to feel technical. Radius scales in three steps plus pill: **sm** 0.5rem (8px) for buttons and inputs, **md** 0.6rem (~10px) for tabs and badges, **lg** 1rem (16px) for pricing cards and feature items, and **pill** 2rem for "Most Popular" badges, promo tags, the hero "How It Works" ghost button, and large buttons (.btn-lg). Circles handle the small geometry: numbered how-to steps (2.5rem), social icons (2.5rem), carousel dots (8px), toggle thumbs (20px).
|
||||||
|
|
||||||
|
Borders are 1px Parchment for cards and inputs; the featured pricing card doubles to 2px Plum Velvet. Active tabs mark themselves with a 3px Plum Velvet bar — left edge on desktop, bottom edge below 992px.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
### Buttons
|
||||||
|
- **Shape:** rounded sm (0.5rem), full-width within pricing cards and on mobile hero, inline otherwise.
|
||||||
|
- **Primary:** Plum Velvet fill, white text, 0.6rem 1.5rem padding. Hover: Deep Plum fill, translateY(-1px). Transition: all 0.2s.
|
||||||
|
- **Hero:** Warm Sand fill, Ink Cocoa text, 0.85rem 2.5rem, weight 700 Inter Tight. Hover: opacity 0.9, translateY(-2px).
|
||||||
|
- **Outline:** Deep Plum border and text on transparent. Hover: Deep Plum fill, white text. Used for "Contact Us" (Empire plan) and hero secondary.
|
||||||
|
- **Large:** .btn-lg — pill radius (2rem), 0.75rem 2rem padding.
|
||||||
|
|
||||||
|
### Cards / Containers
|
||||||
|
- **Corner Style:** rounded lg (1rem); feature items 1rem; blog cards 0.6rem.
|
||||||
|
- **Background:** white on light sections; #fff overrides in the home blog section; blog post pages use the legacy dark card (#12121c) pending the brand-wide phase-out of the dark theme.
|
||||||
|
- **Shadow Strategy:** flat at rest, hover lift per Elevation & Depth.
|
||||||
|
- **Border:** 1px Parchment.
|
||||||
|
- **Internal Padding:** 1.25rem (pricing, blog); feature items 1.5rem 1rem.
|
||||||
|
|
||||||
|
### Inputs / Fields
|
||||||
|
- **Style:** white fill, 1px Parchment border, rounded sm (0.5rem), 0.75rem 1rem padding, Inter.
|
||||||
|
- **Focus:** Plum Velvet border + a soft 2px ring rgba(113,75,103,0.15).
|
||||||
|
- **Footer variant:** translucent fill rgba(255,255,255,0.08) with a lighter border — form inputs on the Ink Cocoa footer.
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
- **Tabs (desktop):** 220px left rail; tab = label + small subtitle, left-aligned, rounded md; active = Plum Velvet 3px left bar + soft plum-tinted gradient fill (rgba 0.08→0.03) + Plum Velvet text at 600.
|
||||||
|
- **Tabs (mobile, <992px):** horizontal scroll row; active bar moves to the bottom edge; subtitles hidden.
|
||||||
|
- **Footer navigation:** Ink Cocoa band, white headings, links at 65% white, hover to full white.
|
||||||
|
|
||||||
|
### Billing Toggle
|
||||||
|
- 48 × 26px pill track; off = Parchment, on = Plum Velvet; 20px white thumb with soft shadow slides left 3px → right 25px over 0.25s.
|
||||||
|
|
||||||
|
### Blog Card
|
||||||
|
- rounded md (0.6rem), white fill, 1.25rem padding, area badge pill (violet/sky/amber/cyan legacy palette — being replaced by plum-family in the brand system), date at 45% opacity, headline in Ink Cocoa, teaser at 60% opacity, "Read more →" in Plum Velvet. Hover: translateY(-2px), border to Plum Velvet, soft plum glow.
|
||||||
|
|
||||||
|
## Do's and Don'ts
|
||||||
|
|
||||||
|
### Do:
|
||||||
|
- **Do** lead with Plum Velvet for any single accent moment — the button, the active tab, the featured border.
|
||||||
|
- **Do** keep all neutrals warm; any gray on the page should read as plum-tinted or sand-tinted, not blue.
|
||||||
|
- **Do** use warm, client-focused copy with short sentences and bullets; no tech jargon, no emojis.
|
||||||
|
- **Do** keep section containers centered at 80% / max 1300px and let sections breathe at 2–3rem padding.
|
||||||
|
- **Do** give interactive elements an immediate hover response — a lift, a fill change, or a border shift within 0.2s.
|
||||||
|
- **Do** use the pill for badges and the lg radius for cards; consistency of the radius ladder is what makes the system feel composed.
|
||||||
|
|
||||||
|
### Don't:
|
||||||
|
- **Don't** use the legacy dark/cyan blog theme (#08080c background, #00f5ff cyan accents) — it is an older style being phased out; the brand is the plum/peach light system only.
|
||||||
|
- **Don't** paint large areas Plum Velvet; it is an accent, not a surface.
|
||||||
|
- **Don't** introduce additional accent colors; green belongs to success states only.
|
||||||
|
- **Don't** use sharp rectangular corners (0 radius) on interactive elements.
|
||||||
|
- **Don't** decorate with gradients other than the established hero band and the primary→secondary "hr" divider.
|
||||||
|
- **Don't** add permanent shadows to resting surfaces; depth responds to interaction.
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Product
|
||||||
|
|
||||||
|
<!-- impeccable:product-schema 1 -->
|
||||||
|
|
||||||
|
## Platform
|
||||||
|
|
||||||
|
web
|
||||||
|
|
||||||
|
## Users
|
||||||
|
|
||||||
|
Primary: business owners and small-to-mid teams worldwide who need Odoo (Community) running for their business but do not want to hire DevOps or manage servers. They are evaluating or already using Odoo and need a production-ready instance fast — deploy in about 5 minutes — with backups, SSL, custom modules, and support handled for them.
|
||||||
|
|
||||||
|
The site copy speaks to non-technical decision makers ("built for business owners, not sysadmins") and to growing businesses that will outgrow entry plans. Trust bar names real customer businesses across regions (Paraguay, Kenya, Germany, sales/automation consultancies).
|
||||||
|
|
||||||
|
## Product Purpose
|
||||||
|
|
||||||
|
Fully managed Odoo Community hosting: deploy a production-ready instance in about 5 minutes without DevOps. Automatic daily backups, free SSL on every domain, Git-based module deployment, management through an ODOO Settings Panel, an AI support bot plus human support, and a choice of 6 global data regions. Success = the customer has a running, maintained Odoo instance and never touches a command line.
|
||||||
|
|
||||||
|
## Positioning
|
||||||
|
|
||||||
|
Enterprise-grade Odoo Community hosting without the enterprise price tag. Community is treated as a powerful ERP that deserves first-class infrastructure — not a budget option. AI-first and global from day one: instances are ready to connect with AI tools and automation, deployed across 6 world regions; going global is a setting, not a project.
|
||||||
|
|
||||||
|
## Operating Context
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
- Blog with guides and news (10 posts); homepage renders it with search and pagination.
|
||||||
|
|
||||||
|
## Capabilities and Constraints
|
||||||
|
|
||||||
|
- Plans: Side Hustle $19.40/mo, On the Rise $36.25/mo (Git modules), Powerhouse $49.60/mo (2 workers, 2GB HDD, 3 domains), Empire $80+/mo (service on the customer's own server, contact to order).
|
||||||
|
- Features: automatic daily backups (FIFO rotation, redundant slots), free SSL on every domain, Git-based module deployment (Quick Git one-click), full management via ODOO Settings Panel, worker scaling, daily security audits with automated patching, continuous performance monitoring, 6 regions.
|
||||||
|
- Enterprise-ready on Powerhouse and above; customer brings their own license.
|
||||||
|
- ODOO4projects LLC; founding date 2020; partner: OD8N.
|
||||||
|
- Constraint: this site remains a pure Odoo hosting seller. The PM Suite (Odoo-based project management + accounting tool for independent project managers, sold without Odoo branding) is a separate product on its own landing page and is not marketed on this site.
|
||||||
|
- Technology: plain static HTML/CSS/JS, no framework, no build step; Inter and Inter Tight fonts; Font Awesome icons.
|
||||||
|
|
||||||
|
## Brand Commitments
|
||||||
|
|
||||||
|
- Name: ODOO4projects (ODOO4projects LLC).
|
||||||
|
- Voice: client-focused, no tech jargon, short sentences, bullet points where appropriate, no emojis in content; lead with the Odoo Community focus and the benefit to the customer; use user-provided copy verbatim.
|
||||||
|
- Identity assets: logo.png, favicon.ico; LinkedIn company page; YouTube channel.
|
||||||
|
- Real named customers in the trust bar are commitments (Paraguay Service, Estancia Agape, KATE Group, agilnova, Ramani Kenya, Start Paraguay, AccellerSales); "Your Company" is an explicit placeholder for prospects.
|
||||||
|
|
||||||
|
## Evidence on Hand
|
||||||
|
|
||||||
|
- 7 named customer/partner sites with logos in the trust bar (see Brand Commitments).
|
||||||
|
- 10 blog posts: Community vs Enterprise cost breakdown, AI agents with Community, enterprise migration guide, custom module how-to, deploy and backup speed runs, platform update, official partner news.
|
||||||
|
- Plan names, prices, coupons, guarantees as listed above (from homepage code).
|
||||||
|
- No invented testimonials beyond plan quotes; no case studies on site.
|
||||||
|
|
||||||
|
## Product Principles
|
||||||
|
|
||||||
|
1. Hosting must be zero-DevOps for the customer; everything manageable from a panel.
|
||||||
|
2. Community edition gets enterprise-grade treatment — the infrastructure is the product's dignity.
|
||||||
|
3. AI and automation are first-class capabilities, not add-ons.
|
||||||
|
4. Trust is explicit: backups, SSL, guarantees, real named customers.
|
||||||
|
5. Copy stays client-focused and jargon-free; facts over hype.
|
||||||
|
|
||||||
|
## Accessibility & Inclusion
|
||||||
|
|
||||||
|
No product-specific accessibility requirement has been established; standard web best practices apply.
|
||||||
@@ -1,68 +1,44 @@
|
|||||||
{
|
{
|
||||||
"posts": [
|
"posts": [
|
||||||
{
|
{
|
||||||
"id": "news-platform-update",
|
"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",
|
||||||
|
"area": "news",
|
||||||
|
"headline": "ODOO Community Is Going Online on ODOO4projects",
|
||||||
|
"teaser": "ODOO Community is scheduled to go online on the 06.10.2026. Alongside that step, the team behind ODOO4projects is workin",
|
||||||
|
"link": "blog/posts/odoo-community-is-going-online-on-odoo4projects.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "community-vs-enterprise-cost",
|
||||||
|
"date": "2026-06-27",
|
||||||
|
"area": "guide",
|
||||||
|
"headline": "Odoo Community vs. Enterprise: The Real Cost Breakdown (2026)",
|
||||||
|
"teaser": "A transparent cost comparison \u2014 including hosting, licensing, and hidden costs for 5, 10, and 25-user teams.",
|
||||||
|
"link": "blog/posts/community-vs-enterprise-cost.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "odoocommunity-agents",
|
||||||
"date": "2026-06-24",
|
"date": "2026-06-24",
|
||||||
"area": "news",
|
"area": "news",
|
||||||
"headline": "Platform Update: New Dashboard, Faster Backups & Smarter Monitoring",
|
"headline": "Why ODOO Community is Perfect for Working with AI Agents",
|
||||||
"teaser": "We've rolled out a major platform update with a redesigned dashboard, incremental backups, and AI-powered uptime monitoring.",
|
"teaser": "ODOO Community's per-seat licensing model allows each AI agent to have its own access rights without additional costs - a game changer for automation.",
|
||||||
"link": "blog/posts/news-platform-update.html"
|
"link": "blog/posts/odoocommunity-agents.html"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "guide-migrate-enterprise",
|
|
||||||
"date": "2026-06-20",
|
|
||||||
"area": "guide",
|
|
||||||
"headline": "How to Migrate from Odoo Community to Enterprise Without Downtime",
|
|
||||||
"teaser": "A step-by-step guide to migrating your Odoo CE instance to Enterprise edition with zero downtime and full data integrity.",
|
|
||||||
"link": "blog/posts/guide-migrate-enterprise.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "howto-custom-module",
|
|
||||||
"date": "2026-06-17",
|
|
||||||
"area": "howto",
|
|
||||||
"headline": "Install Custom Odoo Modules via Git – A Practical How-To",
|
|
||||||
"teaser": "Learn how to install and manage custom Odoo modules directly from Git repositories on your ODOO4projects instance.",
|
|
||||||
"link": "blog/posts/howto-custom-module.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "news-official-partner",
|
|
||||||
"date": "2026-06-14",
|
|
||||||
"area": "news",
|
|
||||||
"headline": "ODOO4projects Becomes an Official Odoo Ready Partner",
|
|
||||||
"teaser": "We're thrilled to announce our official partnership with Odoo SA, bringing enterprise-grade hosting to even more businesses.",
|
|
||||||
"link": "blog/posts/news-official-partner.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "speed-run-backup",
|
|
||||||
"date": "2026-06-10",
|
|
||||||
"area": "speed-run",
|
|
||||||
"headline": "Set Up Automated Backups in Under 2 Minutes",
|
|
||||||
"teaser": "Protect your Odoo data in moments. This speed-run walks you through enabling automated daily backups with one click.",
|
|
||||||
"link": "blog/posts/speed-run-backup.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "howto-ai-automation",
|
|
||||||
"date": "2026-06-06",
|
|
||||||
"area": "howto",
|
|
||||||
"headline": "Build AI-Powered Workflows with Odoo & n8n",
|
|
||||||
"teaser": "Connect Odoo to AI services and automate repetitive tasks using n8n workflows. A hands-on guide for busy operators.",
|
|
||||||
"link": "blog/posts/howto-ai-automation.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "speed-run-deploy",
|
|
||||||
"date": "2026-06-02",
|
|
||||||
"area": "speed-run",
|
|
||||||
"headline": "Deploy Your First Odoo Instance in 5 Minutes",
|
|
||||||
"teaser": "From zero to live Odoo instance in under five minutes. Follow this speed-run and see your business apps running instantly.",
|
|
||||||
"link": "blog/posts/speed-run-deploy.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "my-first-post",
|
|
||||||
"date": "2026-05-28",
|
|
||||||
"area": "guide",
|
|
||||||
"headline": "Getting Started with Odoo Hosting – What You Need to Know",
|
|
||||||
"teaser": "New to Odoo hosting? This guide covers everything from choosing a plan to configuring your first domain and SSL.",
|
|
||||||
"link": "blog/posts/my-first-post.html"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<!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">← Back to the Blog</a>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,296 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Odoo Community vs. Enterprise: The Real Cost Breakdown (2026) | ODOO4projects</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="A transparent cost comparison of Odoo Community vs Enterprise — including hosting, licensing, and hidden costs for 5, 10, and 25-user teams."
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="canonical"
|
||||||
|
href="https://odooprojects.com/blog/posts/community-vs-enterprise-cost.html"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:title"
|
||||||
|
content="Odoo Community vs. Enterprise: The Real Cost Breakdown (2026)"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="A transparent cost comparison of Odoo Community vs Enterprise — including hosting, licensing, and hidden costs for 5, 10, and 25-user teams."
|
||||||
|
/>
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
<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>
|
||||||
|
:root {
|
||||||
|
--primary: #714b67;
|
||||||
|
--dark: #212529;
|
||||||
|
--border: #e5e3e0;
|
||||||
|
--radius: 0.6rem;
|
||||||
|
}
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
background: #fff;
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
.container { width: 80%; max-width: 800px; margin: 0 auto; padding: 0 20px; }
|
||||||
|
@media (max-width: 768px) { .container { width: 100%; } }
|
||||||
|
.blog-header { padding: 2rem 0; border-bottom: 1px solid var(--border); }
|
||||||
|
.blog-header a { color: var(--primary); text-decoration: none; font-size: 0.85rem; }
|
||||||
|
.blog-header a:hover { text-decoration: underline; }
|
||||||
|
.post-title {
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
|
font-weight: 700; margin: 1.5rem 0 0.5rem; color: var(--dark);
|
||||||
|
}
|
||||||
|
.post-meta { color: rgba(33,37,41,0.5); font-size: 0.85rem; margin-bottom: 2rem; }
|
||||||
|
.post-content h2 {
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: 1.3rem; margin-top: 2rem; color: var(--dark);
|
||||||
|
}
|
||||||
|
.post-content p { margin: 1rem 0; color: rgba(33,37,41,0.7); line-height: 1.7; }
|
||||||
|
.post-content ul, .post-content ol { padding-left: 1.5rem; }
|
||||||
|
.post-content li { margin: 0.5rem 0; color: rgba(33,37,41,0.7); }
|
||||||
|
.post-content a { color: var(--primary); }
|
||||||
|
.post-content table {
|
||||||
|
width: 100%; border-collapse: collapse; margin: 1.5rem 0;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.post-content th, .post-content td {
|
||||||
|
border: 1px solid var(--border); padding: 0.6rem 0.8rem; text-align: left;
|
||||||
|
}
|
||||||
|
.post-content th { background: var(--light); font-weight: 600; color: var(--dark); }
|
||||||
|
.post-content td { color: rgba(33,37,41,0.75); }
|
||||||
|
.post-content .highlight-row { background: rgba(113,75,103,0.04); }
|
||||||
|
.pro-tip {
|
||||||
|
border-left: 3px solid var(--primary);
|
||||||
|
background: rgba(113,75,103,0.04);
|
||||||
|
padding: 1rem 1.25rem; margin: 1.5rem 0;
|
||||||
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
|
}
|
||||||
|
.pro-tip strong { color: var(--primary); }
|
||||||
|
.cta-box {
|
||||||
|
border: 1px solid var(--border); background: #fff;
|
||||||
|
padding: 1.5rem; margin: 2rem 0; border-radius: 0.6rem; text-align: center;
|
||||||
|
}
|
||||||
|
.cta-box h3 { margin: 0 0 0.5rem; color: var(--dark); }
|
||||||
|
.cta-box p { margin: 0 0 1rem; color: rgba(33,37,41,0.7); font-size: 0.9rem; }
|
||||||
|
.cta-box .btn {
|
||||||
|
display: inline-block; padding: 0.6rem 1.5rem;
|
||||||
|
background: var(--primary); color: #fff; text-decoration: none;
|
||||||
|
border-radius: 0.5rem; font-weight: 600; font-size: 0.85rem;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
.cta-box .btn:hover { opacity: 0.85; }
|
||||||
|
.post-footer { padding: 2rem 0; border-top: 1px solid var(--border); margin-top: 2rem; }
|
||||||
|
.post-footer a { color: var(--primary); text-decoration: none; }
|
||||||
|
.post-footer a:hover { text-decoration: underline; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="blog-header">
|
||||||
|
<a href="../../index.html#blog">← Back to Blog</a>
|
||||||
|
</div>
|
||||||
|
<article>
|
||||||
|
<h1 class="post-title">Odoo Community vs. Enterprise: The Real Cost Breakdown (2026)</h1>
|
||||||
|
<div class="post-meta">June 27, 2026 · Guide</div>
|
||||||
|
<div class="post-content">
|
||||||
|
<p>
|
||||||
|
Choosing between Odoo Community and Enterprise often comes down to one question:
|
||||||
|
<strong>what do you actually need to pay for?</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Enterprise pricing starts at $31.10/user/month — that's $3,732/year for 10 users
|
||||||
|
before you've paid for hosting. Community is free. But "free" doesn't mean
|
||||||
|
"no cost." You still need hosting, maintenance, and the occasional custom module.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This guide breaks down the real numbers for 5, 10, and 25-user teams so you
|
||||||
|
can make an informed decision.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>The Price of Enterprise</h2>
|
||||||
|
<p>
|
||||||
|
Odoo Enterprise licensing varies by country. The prices below reflect
|
||||||
|
<strong>US pricing</strong> — rates in Europe, Asia, and other regions may differ.
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Plan</th>
|
||||||
|
<th>Per User / Month</th>
|
||||||
|
<th>5 Users / Year</th>
|
||||||
|
<th>10 Users / Year</th>
|
||||||
|
<th>25 Users / Year</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Standard (yearly)</td>
|
||||||
|
<td>$31.10</td>
|
||||||
|
<td>$1,866</td>
|
||||||
|
<td>$3,732</td>
|
||||||
|
<td>$9,330</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Custom (yearly)</td>
|
||||||
|
<td>$61.00</td>
|
||||||
|
<td>$3,660</td>
|
||||||
|
<td>$7,320</td>
|
||||||
|
<td>$18,300</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
Odoo Online hosting is included in these prices, but it's shared infrastructure
|
||||||
|
with limited performance. For dedicated resources, you'd add Odoo.sh or a
|
||||||
|
third-party host — adding another $2,000-$6,000/year.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>What Community Actually Costs</h2>
|
||||||
|
<p>
|
||||||
|
Odoo Community has no license fee. Your costs are:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Hosting</strong> — $19–$50/month depending on plan ($228–$600/year)</li>
|
||||||
|
<li><strong>SSL certificates</strong> — included with most hosts (free with ODOO4projects)</li>
|
||||||
|
<li><strong>Backup storage</strong> — included in your plan</li>
|
||||||
|
<li><strong>Custom modules</strong> — if you need them, but you can start with standard apps</li>
|
||||||
|
</ul>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Team Size</th>
|
||||||
|
<th>Community / Year</th>
|
||||||
|
<th>Enterprise + Hosting / Year</th>
|
||||||
|
<th>You Save</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="highlight-row">
|
||||||
|
<td>5 users</td>
|
||||||
|
<td>$228–$600</td>
|
||||||
|
<td>$3,866–$5,660</td>
|
||||||
|
<td><strong>$3,266–$5,060</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="highlight-row">
|
||||||
|
<td>10 users</td>
|
||||||
|
<td>$228–$600</td>
|
||||||
|
<td>$5,732–$9,320</td>
|
||||||
|
<td><strong>$5,132–$8,720</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="highlight-row">
|
||||||
|
<td>25 users</td>
|
||||||
|
<td>$228–$600</td>
|
||||||
|
<td>$11,330–$20,300</td>
|
||||||
|
<td><strong>$10,730–$19,700</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
A 10-user team on Community saves <strong>$5,000–$8,700 per year</strong>
|
||||||
|
compared to Enterprise Standard — enough to fund development, marketing,
|
||||||
|
or additional tools.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>What You Give Up with Community</h2>
|
||||||
|
<p>
|
||||||
|
Community is powerful, but there are real gaps vs Enterprise:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Built-in AI</strong> — Enterprise has AI text generation, lead scoring,
|
||||||
|
OCR, and chatbots. Community needs external tools like N8N + OpenAI to
|
||||||
|
replicate these (which is straightforward, but requires setup).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Multi-company accounting</strong> — Enterprise handles consolidation
|
||||||
|
across entities. Community handles single-entity only.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Studio & advanced automation</strong> — Enterprise's no-code
|
||||||
|
Studio tools simplify customization. Community requires code or Git-based
|
||||||
|
modules.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Official support</strong> — Enterprise includes Odoo SA support.
|
||||||
|
Community relies on community forums and your hosting provider.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="pro-tip">
|
||||||
|
<strong>Where Community shines:</strong> Single-entity businesses under $2M revenue,
|
||||||
|
startups validating their workflow, companies that want full control over their
|
||||||
|
codebase, and teams that prefer integrating their own AI stack rather than paying
|
||||||
|
per-user for features they may not fully use.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>The Hidden Advantage: No Lock-In</h2>
|
||||||
|
<p>
|
||||||
|
Enterprise runs on Odoo's proprietary license. If you stop paying, you lose
|
||||||
|
access to your modules and can't run the software. Community is LGPLv3-licensed —
|
||||||
|
you own the code forever. Switch hosting providers, take it in-house, or modify
|
||||||
|
it however you need.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For businesses that value long-term IT independence, that alone is worth
|
||||||
|
thousands.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>When Should You Upgrade?</h2>
|
||||||
|
<p>
|
||||||
|
Most businesses hit the Enterprise ceiling at one of three milestones:
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<strong>$2M+ in revenue</strong> — multi-entity accounting and audit-grade
|
||||||
|
controls become necessary.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Adding a second legal entity</strong> — Community can't consolidate
|
||||||
|
across companies.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Preparing for an audit or financing</strong> — Enterprise's audit
|
||||||
|
trail and SOX-grade controls are table stakes.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p>
|
||||||
|
Until then, Community + quality hosting is the financially smarter choice.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="cta-box">
|
||||||
|
<h3>Start with Community, Upgrade When Ready</h3>
|
||||||
|
<p>
|
||||||
|
ODOO4projects plans start at $19.40/month — enterprise-grade hosting
|
||||||
|
for your Odoo Community instance. No lock-in, no per-user fees.
|
||||||
|
</p>
|
||||||
|
<a href="../../index.html#pricing" class="btn btn-primary">See Plans</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<div class="post-footer">
|
||||||
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -32,17 +32,23 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
* {
|
.blog-header {
|
||||||
box-sizing: border-box;
|
padding: 2rem 0;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
body {
|
.blog-header a {
|
||||||
margin: 0;
|
color: var(--primary);
|
||||||
font-family: Inter, sans-serif;
|
text-decoration: none;
|
||||||
font-size: 1rem;
|
font-size: 0.85rem;
|
||||||
line-height: 1.7;
|
}
|
||||||
background: #08080c;
|
.blog-header a:hover {
|
||||||
color: #e8e8f0;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@@ -55,27 +61,15 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.blog-header {
|
|
||||||
padding: 2rem 0;
|
|
||||||
border-bottom: 1px solid #1a1a2e;
|
|
||||||
}
|
|
||||||
.blog-header a {
|
|
||||||
color: #00f5ff;
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
.blog-header a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.post-title {
|
.post-title {
|
||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -83,10 +77,15 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -94,36 +93,37 @@
|
|||||||
}
|
}
|
||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
}
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.post-content pre {
|
.post-content pre {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border: 1px solid #1a1a2e;
|
border: 1px solid var(--border);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: #fff;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: 0.6rem;
|
||||||
@@ -131,34 +131,41 @@
|
|||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
font-size: 0.9rem;
|
||||||
color: #08080c;
|
font-weight: 500;
|
||||||
text-decoration: none;
|
border: 1px solid transparent;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
cursor: pointer;
|
||||||
font-size: 0.85rem;
|
text-decoration: none;
|
||||||
transition: opacity 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
.cta-box .btn:hover {
|
.cta-box .btn-primary {
|
||||||
opacity: 0.85;
|
color: #fff;
|
||||||
|
background: var(--primary);
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
|
.cta-box .btn-primary:hover {
|
||||||
|
background: #5e3f55;
|
||||||
|
border-color: #5e3f55;
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -227,7 +234,7 @@
|
|||||||
Upgrade to Powerhouse and unlock Enterprise features
|
Upgrade to Powerhouse and unlock Enterprise features
|
||||||
today.
|
today.
|
||||||
</p>
|
</p>
|
||||||
<a href="../../index.html#pricing" class="btn"
|
<a href="../../index.html#pricing" class="btn btn-primary"
|
||||||
>View Powerhouse Plan</a
|
>View Powerhouse Plan</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -237,5 +244,6 @@
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -31,35 +31,30 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
|
<link rel="stylesheet" href="../../style.css" />
|
||||||
<style>
|
<style>
|
||||||
* {
|
/* Blog post specific overrides — matching homepage light theme */
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
background: #fff;
|
||||||
font-family: Inter, sans-serif;
|
color: #212529;
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.7;
|
|
||||||
background: #08080c;
|
|
||||||
color: #e8e8f0;
|
|
||||||
}
|
}
|
||||||
.container {
|
.blog-post-container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.container {
|
.blog-post-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid #e5e3e0;
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: #65435c;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -71,10 +66,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: #1b1319;
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -82,7 +77,7 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: #1b1319;
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
@@ -95,34 +90,34 @@
|
|||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background: #12121c;
|
background: #f6f5f4;
|
||||||
color: #00f5ff;
|
color: #714b67;
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.post-content pre {
|
.post-content pre {
|
||||||
background: #12121c;
|
background: #f6f5f4;
|
||||||
color: #00f5ff;
|
color: #1b1319;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 0.6rem;
|
border-radius: 0.6rem;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border: 1px solid #1a1a2e;
|
border: 1px solid #e5e3e0;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid #714b67;
|
||||||
background: #010f20;
|
background: #f6f5f4;
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: #714b67;
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid rgba(113, 75, 103, 0.2);
|
||||||
background: #12121c;
|
background: #f6f5f4;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: 0.6rem;
|
||||||
@@ -130,18 +125,18 @@
|
|||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: #1b1319;
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.55);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
background: #714b67;
|
||||||
color: #08080c;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -153,11 +148,11 @@
|
|||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid #e5e3e0;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: #65435c;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -166,7 +161,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="blog-post-container">
|
||||||
<div class="blog-header">
|
<div class="blog-header">
|
||||||
<a href="../../index.html#blog">← Back to Blog</a>
|
<a href="../../index.html#blog">← Back to Blog</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -32,7 +32,20 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary: #714b67;
|
||||||
|
--border: #e5e3e0;
|
||||||
|
--radius: 0.6rem;
|
||||||
|
--dark: #212529;
|
||||||
|
--light: #f8f9fa;
|
||||||
|
--bg: #ffffff;
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -41,8 +54,8 @@
|
|||||||
font-family: Inter, sans-serif;
|
font-family: Inter, sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
background: #08080c;
|
background: var(--bg);
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@@ -57,10 +70,10 @@
|
|||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -72,10 +85,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -83,10 +96,12 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -95,54 +110,57 @@
|
|||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.post-content pre {
|
.post-content pre {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border: 1px solid #1a1a2e;
|
border: 1px solid var(--border);
|
||||||
font-size: 0.9rem;
|
font-size: 0.82rem;
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: var(--bg);
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
background: var(--primary);
|
||||||
color: #08080c;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -154,11 +172,11 @@
|
|||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -228,5 +246,6 @@
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -32,7 +32,20 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary: #714b67;
|
||||||
|
--border: #e5e3e0;
|
||||||
|
--radius: 0.6rem;
|
||||||
|
--dark: #212529;
|
||||||
|
--light: #f8f9fa;
|
||||||
|
--bg: #ffffff;
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -41,8 +54,8 @@
|
|||||||
font-family: Inter, sans-serif;
|
font-family: Inter, sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
background: #08080c;
|
background: var(--bg);
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@@ -57,10 +70,10 @@
|
|||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -72,10 +85,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -83,10 +96,12 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -95,54 +110,57 @@
|
|||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.post-content pre {
|
.post-content pre {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border: 1px solid #1a1a2e;
|
border: 1px solid var(--border);
|
||||||
font-size: 0.9rem;
|
font-size: 0.82rem;
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: var(--bg);
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
background: var(--primary);
|
||||||
color: #08080c;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -154,11 +172,11 @@
|
|||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -232,7 +250,7 @@ Admin credentials: sent via email</code></pre>
|
|||||||
Pick a plan and launch your Odoo instance in
|
Pick a plan and launch your Odoo instance in
|
||||||
minutes.
|
minutes.
|
||||||
</p>
|
</p>
|
||||||
<a href="../../index.html#pricing" class="btn"
|
<a href="../../index.html#pricing" class="btn btn-primary"
|
||||||
>View Plans</a
|
>View Plans</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,5 +260,6 @@ Admin credentials: sent via email</code></pre>
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -31,7 +31,18 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary: #714b67;
|
||||||
|
--dark: #212529;
|
||||||
|
--border: #e5e3e0;
|
||||||
|
--radius: 0.6rem;
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -40,8 +51,8 @@
|
|||||||
font-family: Inter, sans-serif;
|
font-family: Inter, sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
background: #08080c;
|
background: #fff;
|
||||||
color: #e8e8f0;
|
color: #212529;
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@@ -56,10 +67,10 @@
|
|||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -71,10 +82,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -82,10 +93,12 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -93,20 +106,24 @@
|
|||||||
}
|
}
|
||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: #fff;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: 0.6rem;
|
||||||
@@ -114,18 +131,18 @@
|
|||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
background: var(--primary);
|
||||||
color: #08080c;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -137,11 +154,11 @@
|
|||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -203,7 +220,7 @@
|
|||||||
Join thousands of businesses running on
|
Join thousands of businesses running on
|
||||||
ODOO4projects.
|
ODOO4projects.
|
||||||
</p>
|
</p>
|
||||||
<a href="../../index.html#pricing" class="btn"
|
<a href="../../index.html#pricing" class="btn btn-primary"
|
||||||
>Get Started</a
|
>Get Started</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -213,5 +230,9 @@
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script
|
||||||
|
defer
|
||||||
|
src="/static/agent-odoo4projects/agent.js"
|
||||||
|
></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -32,17 +32,28 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
:root {
|
||||||
|
--primary: #714b67;
|
||||||
|
--border: #e5e3e0;
|
||||||
|
--dark: #1b1319;
|
||||||
|
--radius: 0.6rem;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Inter, sans-serif;
|
font-family: Inter, sans-serif;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
background: #08080c;
|
background: #fff;
|
||||||
color: #e8e8f0;
|
color: #212529;
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@@ -57,10 +68,10 @@
|
|||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -72,10 +83,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -83,10 +94,12 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -95,19 +108,22 @@
|
|||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: #fff;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: 0.6rem;
|
||||||
@@ -115,18 +131,19 @@
|
|||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
background: var(--primary);
|
||||||
color: #08080c;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -138,11 +155,11 @@
|
|||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -213,5 +230,9 @@
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script
|
||||||
|
defer
|
||||||
|
src="/static/agent-odoo4projects/agent.js"
|
||||||
|
></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<!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">← Back to the Blog</a>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>ODOO Community Is Going Online on ODOO4projects | ODOO4projects</title>
|
||||||
|
<meta name="description" content="ODOO Community is scheduled to go online on the 06.10.2026. Alongside that step, the team behind ODOO4projects is working hard on upgrading its server modu" />
|
||||||
|
<link rel="canonical" href="https://odoo4projects.com/blog/posts/odoo-community-is-going-online-on-odoo4projects.html" />
|
||||||
|
<meta property="og:title" content="ODOO Community Is Going Online on ODOO4projects" />
|
||||||
|
<meta property="og:description" content="ODOO Community is scheduled to go online on the 06.10.2026. Alongside that step, the team behind ODOO4projects is working hard on upgrading its server modu" />
|
||||||
|
<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 Community Is Going Online on ODOO4projects</h1>
|
||||||
|
<div class="post-meta">Sep 28, 2026</div>
|
||||||
|
<img src="https://image.office.odoo4projects.com/img/ODOO_20_chatter.png" alt="ODOO Community Is Going Online on ODOO4projects" class="post-image" loading="lazy" />
|
||||||
|
<div class="post-body">
|
||||||
|
<p>ODOO Community is scheduled to go online on the 06.10.2026. Alongside that step, the team behind ODOO4projects is working hard on upgrading its server modules, with the goal of delivering the best possible ODOO4projects service on Odoo 20.</p>
|
||||||
|
|
||||||
|
<p>It is an upgrade cycle with more than one headline. Here is what is planned.</p>
|
||||||
|
|
||||||
|
<h2>An MCP server that lets your coding agent run your instance</h2>
|
||||||
|
|
||||||
|
<p>The most interesting piece of this update is an MCP server designed to hand everyday instance management to your coding agent. Instead of switching between tools and dashboards, the agent would be able to handle the routine work directly.</p>
|
||||||
|
|
||||||
|
<p>The planned capabilities include:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong>Reading logfiles</strong> — so problems can be spotted and investigated without digging through them manually.</li>
|
||||||
|
<li><strong>Restarting your ODOO</strong> — a frequent, mundane task that no longer needs to interrupt your flow.</li>
|
||||||
|
<li><strong>Pushing new modules</strong> — deploying new functionality as part of the same workflow.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>In short: less clicking around, more letting your agent do the operational heavy lifting while you focus on the work that actually moves your project forward.</p>
|
||||||
|
|
||||||
|
<h2>Analytics with AI on the backend</h2>
|
||||||
|
|
||||||
|
<p>The second major improvement is on the analytics side. AI is being added to the backend to make the numbers more useful — not just more numerous.</p>
|
||||||
|
|
||||||
|
<p>The aim is to surface better, more actionable tips for running your ODOO, so the data you already have starts pointing at concrete improvements instead of leaving you to interpret dashboards on your own.</p>
|
||||||
|
|
||||||
|
<h2>What this means for you</h2>
|
||||||
|
|
||||||
|
<p>Three things are being prepared at once: a community that is online, server modules upgraded for Odoo 20, and a service layer that leans on AI — both for hands-on instance management through the MCP server and for the insights you get from your analytics.</p>
|
||||||
|
|
||||||
|
<p>Details, timing, and the exact shape of each feature will follow as the work progresses. Until then, the direction is clear: a more capable ODOO4projects, built on Odoo 20, and far more automated for the people running it day to day.</p>
|
||||||
|
|
||||||
|
<p>Stay tuned so you do not miss the go live — and follow <strong>#ODOO4projects</strong> to keep up with every update as it lands.</p>
|
||||||
|
</div>
|
||||||
|
<a href="../../index.html#blog" class="back-link">← Back to the Blog</a>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>
|
||||||
|
Why ODOO Community is Perfect for Working with AI Agents | ODOO4projects
|
||||||
|
</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="ODOO Community's per-seat licensing model allows each AI agent to have its own access rights without additional costs - a game changer for automation."
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="canonical"
|
||||||
|
href="https://odooprojects.com/blog/posts/odoocommunity-agents.html"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:title"
|
||||||
|
content="Why ODOO Community is Perfect for Working with AI Agents"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="ODOO Community's per-seat licensing model allows each AI agent to have its own access rights without additional costs - a game changer for automation."
|
||||||
|
/>
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
<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>
|
||||||
|
/* Blog post specific styles — leverages CSS vars from style.css */
|
||||||
|
:root {
|
||||||
|
--primary: #714b67;
|
||||||
|
--border: #e5e3e0;
|
||||||
|
--dark: #1b1319;
|
||||||
|
--radius: 0.6rem;
|
||||||
|
}
|
||||||
|
.blog-header {
|
||||||
|
padding: 2rem 0;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.blog-header a {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.blog-header a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.post-title {
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 1.5rem 0 0.5rem;
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
.post-meta {
|
||||||
|
color: rgba(33, 37, 41, 0.5);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.post-content p {
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
.post-content h2 {
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
color: var(--dark);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.post-content ul,
|
||||||
|
.post-content ol {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
.post-content li {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.post-content a:hover {
|
||||||
|
color: #5e3f55;
|
||||||
|
}
|
||||||
|
.pro-tip {
|
||||||
|
border-left: 3px solid var(--primary);
|
||||||
|
background: rgba(113, 75, 103, 0.04);
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
|
}
|
||||||
|
.pro-tip strong {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
.pro-tip p {
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
}
|
||||||
|
.cta-box {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
background: #fff;
|
||||||
|
padding: 1.5rem;
|
||||||
|
margin: 2rem 0;
|
||||||
|
border-radius: 0.6rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.cta-box h3 {
|
||||||
|
margin: 0 0 0.5rem;
|
||||||
|
color: var(--dark);
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: clamp(1.1rem, 2vw, 1.4rem);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.cta-box p {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.post-footer {
|
||||||
|
padding: 2rem 0;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
.post-footer a {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.post-footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container" style="width:80%; max-width:800px; margin:0 auto; padding:0 20px;">
|
||||||
|
<div class="blog-header">
|
||||||
|
<a href="../../index.html#blog">← Back to Blog</a>
|
||||||
|
</div>
|
||||||
|
<article>
|
||||||
|
<h1 class="post-title">
|
||||||
|
Why ODOO Community is Perfect for Working with AI Agents
|
||||||
|
</h1>
|
||||||
|
<div class="post-meta">June 24, 2026 · News</div>
|
||||||
|
<div class="post-content">
|
||||||
|
<p>
|
||||||
|
AI agents are transforming how businesses operate, and
|
||||||
|
ODOO Community Edition is uniquely positioned to harness
|
||||||
|
this revolution. Unlike Enterprise, which requires per-user
|
||||||
|
licenses that scale costs linearly, Community Edition's
|
||||||
|
per-seat licensing model allows each AI agent to have its
|
||||||
|
own access rights <strong>without additional costs</strong>
|
||||||
|
— a genuine game changer for automation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>The Licensing Advantage</h2>
|
||||||
|
<p>
|
||||||
|
ODOO Enterprise charges per user per month. While this
|
||||||
|
works well for human employees, it becomes prohibitively
|
||||||
|
expensive when you want to deploy dozens or hundreds of
|
||||||
|
specialized AI agents — each performing distinct
|
||||||
|
roles like inventory reconciliation, invoice processing,
|
||||||
|
customer follow-up, or report generation.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
ODOO Community, on the other hand, has no per-user
|
||||||
|
licensing fees. You can create as many user accounts as
|
||||||
|
your infrastructure can support, assign granular access
|
||||||
|
rights to each agent, and scale your automation
|
||||||
|
horizontally without watching your monthly bill climb.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="pro-tip">
|
||||||
|
<strong>Pro Tip:</strong> With ODOO Community, you can
|
||||||
|
create dedicated user accounts for each AI agent —
|
||||||
|
one for invoice processing, one for inventory management,
|
||||||
|
one for customer support triage — all without
|
||||||
|
incurring additional licensing costs.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Granular Access Control</h2>
|
||||||
|
<p>
|
||||||
|
Each AI agent needs precisely scoped permissions. Your
|
||||||
|
invoice processing agent should read vendor bills and
|
||||||
|
create payments, but never touch HR records. Your customer
|
||||||
|
support agent needs access to the CRM and sales orders,
|
||||||
|
but not accounting.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
ODOO Community's robust access control lists (ACLs),
|
||||||
|
record rules, and security groups let you define
|
||||||
|
exactly what each agent can see and do. Combined with
|
||||||
|
the per-seat model, you can have:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Agents with full admin</strong> — for
|
||||||
|
system orchestration
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Specialized agents</strong> — scoped to
|
||||||
|
specific apps (Inventory, Accounting, CRM, etc.)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Read-only agents</strong> — for
|
||||||
|
monitoring, reporting, and data extraction
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>External API agents</strong> — using
|
||||||
|
API keys with limited endpoints
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>API-First Architecture</h2>
|
||||||
|
<p>
|
||||||
|
ODOO Community exposes a comprehensive JSON-RPC and XML-RPC
|
||||||
|
API that AI agents can consume directly. Modern agent
|
||||||
|
frameworks like LangChain, CrewAI, and AutoGen can connect
|
||||||
|
to ODOO instances natively, making it straightforward to
|
||||||
|
build agentic workflows.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Combined with N8N automation workflows and custom
|
||||||
|
modules hosted on ODOO4projects, you can create
|
||||||
|
sophisticated pipelines where AI agents coordinate
|
||||||
|
across multiple ODOO apps, external services, and
|
||||||
|
communication channels.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Why Host with ODOO4projects?</h2>
|
||||||
|
<p>
|
||||||
|
Running AI agents alongside ODOO requires reliable,
|
||||||
|
scalable infrastructure. Our hosting platform offers:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Dedicated resources</strong> — no noisy
|
||||||
|
neighbors affecting agent response times
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Automated backups</strong> — your agent
|
||||||
|
configurations and data are always protected
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>One-click upgrades</strong> — stay
|
||||||
|
current with ODOO Community releases without manual
|
||||||
|
intervention
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>N8N integration</strong> — pre-configured
|
||||||
|
automation server for agent orchestration
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="cta-box">
|
||||||
|
<h3>Ready to Build Your AI-Powered ODOO?</h3>
|
||||||
|
<p>
|
||||||
|
Start with any ODOO4projects plan and deploy your
|
||||||
|
first AI agent today.
|
||||||
|
</p>
|
||||||
|
<a href="../../index.html#pricing" class="btn btn-primary"
|
||||||
|
>Choose Your Plan</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<div class="post-footer">
|
||||||
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -31,18 +31,12 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: Inter, sans-serif;
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.7;
|
|
||||||
background: #08080c;
|
|
||||||
color: #e8e8f0;
|
|
||||||
}
|
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
@@ -56,10 +50,10 @@
|
|||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -71,10 +65,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -82,10 +76,12 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -94,70 +90,60 @@
|
|||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 4px;
|
border-radius: var(--radius);
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
border: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.post-content pre {
|
.post-content pre {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border: 1px solid #1a1a2e;
|
border: 1px solid var(--border);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 var(--radius) var(--radius) 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: #fff;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.6rem 1.5rem;
|
|
||||||
background: #00f5ff;
|
|
||||||
color: #08080c;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
}
|
|
||||||
.cta-box .btn:hover {
|
|
||||||
opacity: 0.85;
|
|
||||||
}
|
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -210,7 +196,7 @@ Recommended: Daily at 02:00 UTC, 14-day retention</code></pre>
|
|||||||
<p>
|
<p>
|
||||||
All ODOO4projects plans include automated backups.
|
All ODOO4projects plans include automated backups.
|
||||||
</p>
|
</p>
|
||||||
<a href="../../index.html#pricing" class="btn"
|
<a href="../../index.html#pricing" class="btn btn-primary"
|
||||||
>Choose a Plan</a
|
>Choose a Plan</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -220,5 +206,6 @@ Recommended: Daily at 02:00 UTC, 14-day retention</code></pre>
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -31,17 +31,19 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
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"
|
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>
|
<style>
|
||||||
* {
|
:root {
|
||||||
box-sizing: border-box;
|
--primary: #714b67;
|
||||||
}
|
--secondary: #f0cda8;
|
||||||
body {
|
--dark: #1b1319;
|
||||||
margin: 0;
|
--light: #f6f5f4;
|
||||||
font-family: Inter, sans-serif;
|
--border: #e5e3e0;
|
||||||
font-size: 1rem;
|
--radius: 0.6rem;
|
||||||
line-height: 1.7;
|
|
||||||
background: #08080c;
|
|
||||||
color: #e8e8f0;
|
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@@ -56,10 +58,10 @@
|
|||||||
}
|
}
|
||||||
.blog-header {
|
.blog-header {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-bottom: 1px solid #1a1a2e;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.blog-header a {
|
.blog-header a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@@ -71,10 +73,10 @@
|
|||||||
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 1.5rem 0 0.5rem;
|
margin: 1.5rem 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-meta {
|
.post-meta {
|
||||||
color: rgba(232, 232, 240, 0.5);
|
color: rgba(33, 37, 41, 0.5);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
@@ -82,10 +84,12 @@
|
|||||||
font-family: "Inter Tight", sans-serif;
|
font-family: "Inter Tight", sans-serif;
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.post-content p {
|
.post-content p {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
.post-content ul,
|
.post-content ul,
|
||||||
.post-content ol {
|
.post-content ol {
|
||||||
@@ -94,54 +98,57 @@
|
|||||||
.post-content li {
|
.post-content li {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
.post-content a {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
.post-content code {
|
.post-content code {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.post-content pre {
|
.post-content pre {
|
||||||
background: #12121c;
|
background: var(--light);
|
||||||
color: #00f5ff;
|
color: var(--dark);
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
border: 1px solid #1a1a2e;
|
border: 1px solid var(--border);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.pro-tip {
|
.pro-tip {
|
||||||
border-left: 3px solid #00f5ff;
|
border-left: 3px solid var(--primary);
|
||||||
background: #010f20;
|
background: rgba(113, 75, 103, 0.04);
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
margin: 1.5rem 0;
|
margin: 1.5rem 0;
|
||||||
border-radius: 0 0.6rem 0.6rem 0;
|
border-radius: 0 0.6rem 0.6rem 0;
|
||||||
}
|
}
|
||||||
.pro-tip strong {
|
.pro-tip strong {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
.cta-box {
|
.cta-box {
|
||||||
border: 1px solid rgba(0, 245, 255, 0.2);
|
border: 1px solid var(--border);
|
||||||
background: #12121c;
|
background: #fff;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
border-radius: 0.6rem;
|
border-radius: var(--radius);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.cta-box h3 {
|
.cta-box h3 {
|
||||||
margin: 0 0 0.5rem;
|
margin: 0 0 0.5rem;
|
||||||
color: #e8e8f0;
|
color: var(--dark);
|
||||||
}
|
}
|
||||||
.cta-box p {
|
.cta-box p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
color: rgba(232, 232, 240, 0.7);
|
color: rgba(33, 37, 41, 0.7);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.cta-box .btn {
|
.cta-box .btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.6rem 1.5rem;
|
padding: 0.6rem 1.5rem;
|
||||||
background: #00f5ff;
|
background: var(--primary);
|
||||||
color: #08080c;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -153,11 +160,11 @@
|
|||||||
}
|
}
|
||||||
.post-footer {
|
.post-footer {
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
border-top: 1px solid #1a1a2e;
|
border-top: 1px solid var(--border);
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
.post-footer a {
|
.post-footer a {
|
||||||
color: #00f5ff;
|
color: var(--primary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.post-footer a:hover {
|
.post-footer a:hover {
|
||||||
@@ -184,11 +191,7 @@
|
|||||||
<h2>Step 1: Choose a Plan</h2>
|
<h2>Step 1: Choose a Plan</h2>
|
||||||
<p>
|
<p>
|
||||||
Visit our
|
Visit our
|
||||||
<a
|
<a href="../../index.html#pricing">pricing page</a>
|
||||||
href="../../index.html#pricing"
|
|
||||||
style="color: #00f5ff"
|
|
||||||
>pricing page</a
|
|
||||||
>
|
|
||||||
and select the plan that fits your needs. For testing,
|
and select the plan that fits your needs. For testing,
|
||||||
Side Hustle is perfect. For production, go with On the
|
Side Hustle is perfect. For production, go with On the
|
||||||
Rise or Powerhouse.
|
Rise or Powerhouse.
|
||||||
@@ -223,7 +226,7 @@ Password: (check your email)</code></pre>
|
|||||||
From zero to live in under 5 minutes — no
|
From zero to live in under 5 minutes — no
|
||||||
credit card required to start.
|
credit card required to start.
|
||||||
</p>
|
</p>
|
||||||
<a href="../../index.html#pricing" class="btn"
|
<a href="../../index.html#pricing" class="btn btn-primary"
|
||||||
>Choose Your Plan</a
|
>Choose Your Plan</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -233,5 +236,6 @@ Password: (check your email)</code></pre>
|
|||||||
<a href="../../index.html#blog">← Back to all posts</a>
|
<a href="../../index.html#blog">← Back to all posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Confirm your email to get your Odoo instance</title>
|
||||||
|
<style>
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: #f4f0e8;
|
||||||
|
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #0d1b2e;
|
||||||
|
}
|
||||||
|
table { width: 100%; border-collapse: collapse; }
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background: #0d1b2e;
|
||||||
|
color: #fff;
|
||||||
|
padding: 32px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.brand {
|
||||||
|
font-family: Marcellus, serif;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.content { padding: 32px 24px; }
|
||||||
|
h1 {
|
||||||
|
font-family: Marcellus, serif;
|
||||||
|
font-size: 26px;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
color: #0d1b2e;
|
||||||
|
}
|
||||||
|
p { margin: 0 0 16px 0; color: #162a45; }
|
||||||
|
.highlight {
|
||||||
|
background: rgba(201,162,39,0.08);
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-left: 3px solid #c9a227;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
.cta {
|
||||||
|
display: inline-block;
|
||||||
|
background: #c9a227;
|
||||||
|
color: #fff;
|
||||||
|
padding: 14px 28px;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 24px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.cta:hover { background: #b38f22; }
|
||||||
|
.steps { margin: 24px 0; }
|
||||||
|
.step {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.step-number {
|
||||||
|
background: #0d1b2e;
|
||||||
|
color: #fff;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-right: 12px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.step-content { flex: 1; }
|
||||||
|
.step h3 { margin: 0 0 4px 0; font-size: 16px; color: #0d1b2e; }
|
||||||
|
.step p { margin: 0; font-size: 14px; color: #162a45; }
|
||||||
|
.footer {
|
||||||
|
background: #f4f0e8;
|
||||||
|
padding: 24px;
|
||||||
|
border-top: 1px solid #e8e2d4;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #162a45;
|
||||||
|
}
|
||||||
|
.footer p { margin: 0 0 8px 0; }
|
||||||
|
.footer a { color: #c9a227; text-decoration: underline; }
|
||||||
|
.support {
|
||||||
|
margin-top: 24px;
|
||||||
|
padding: 16px;
|
||||||
|
background: rgba(13,27,46,0.05);
|
||||||
|
border-radius: 6px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.support a { color: #0d1b2e; font-weight: 600; text-decoration: none; }
|
||||||
|
.support a:hover { text-decoration: underline; }
|
||||||
|
.unsubscribe { margin-top: 8px; color: #6b7b8c; }
|
||||||
|
.unsubscribe a { color: #6b7b8c; text-decoration: underline; }
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container { border-radius: 0; }
|
||||||
|
.header { padding: 24px 16px; }
|
||||||
|
.content { padding: 24px 16px; }
|
||||||
|
h1 { font-size: 22px; }
|
||||||
|
.cta { padding: 12px 20px; font-size: 15px; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<table class="container" cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<!-- Header -->
|
||||||
|
<tr>
|
||||||
|
<td class="header">
|
||||||
|
<h1 class="brand">ODOO4projects</h1>
|
||||||
|
<p style="font-size: 14px; margin-top: 8px; opacity: 0.85;">Odoo Community Managed Hosting</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<tr>
|
||||||
|
<td class="content">
|
||||||
|
<h1>Confirm your email to get your Odoo instance</h1>
|
||||||
|
<p>Thanks for signing up for the 30-day free trial of Odoo Community V20 hosting.</p>
|
||||||
|
<p>Your Odoo instance is waiting to be launched. Confirm your email address and we'll spin it up immediately.</p>
|
||||||
|
|
||||||
|
<!-- Confirmation CTA -->
|
||||||
|
<center>
|
||||||
|
<a class="cta" href="https://odoo4projects.com/trial/confirm?token=USER_TOKEN">Confirm Email</a>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<div class="highlight">
|
||||||
|
<strong>What happens next:</strong> We'll email your login credentials once your instance is ready.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Steps -->
|
||||||
|
<div class="steps">
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-number">1</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h3>Confirm email</h3>
|
||||||
|
<p>Click the button above to verify your address and start your Odoo V20 instance.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-number">2</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h3>Instance spins up</h3>
|
||||||
|
<p>We provision your Odoo Community V20 server automatically. Usually takes 2-5 minutes.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<div class="step-number">3</div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h3>Login credentials</h3>
|
||||||
|
<p>We email your URL, username, and temporary password. You can change them right away.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><strong>What you get in this trial:</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Odoo Community V20 — fully featured, open-source ERP</li>
|
||||||
|
<li>Automatic backups and SSL certificate</li>
|
||||||
|
<li>Domain mapping (use your own domain or our free subdomain)</li>
|
||||||
|
<li>No credit card required</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="support">
|
||||||
|
<p>Questions? Reply to this email or contact us directly:</p>
|
||||||
|
<p><a href="mailto:support@odoo4projects.com">support@odoo4projects.com</a></p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<tr>
|
||||||
|
<td class="footer">
|
||||||
|
<p><strong>ODOO4projects</strong> — Smart, scalable business solutions</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://odoo4projects.com/legal/privacy">Privacy</a> •
|
||||||
|
<a href="https://odoo4projects.com/legal/terms">Terms</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
|
||||||
|
</p>
|
||||||
|
<p style="margin-top: 8px; opacity: 0.7;">© 2024 ODOO4projects LLC. All rights reserved.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 11 MiB |
|
After Width: | Height: | Size: 338 KiB |
|
After Width: | Height: | Size: 381 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 9.4 MiB |
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 27.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 671.21002 172.39999"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="logo-01.svg"
|
||||||
|
width="671.21002"
|
||||||
|
height="172.39999"
|
||||||
|
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs47" /><sodipodi:namedview
|
||||||
|
id="namedview45"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.86041667"
|
||||||
|
inkscape:cx="335.30266"
|
||||||
|
inkscape:cy="86.004843"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="37"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" />
|
||||||
|
<style
|
||||||
|
type="text/css"
|
||||||
|
id="style2">
|
||||||
|
.st0{fill:#68696D;}
|
||||||
|
.st1{fill:#ED703E;}
|
||||||
|
</style>
|
||||||
|
<g
|
||||||
|
id="g42"
|
||||||
|
transform="translate(-144.4,-393.8)">
|
||||||
|
<g
|
||||||
|
id="g8">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 427.65,509.26 c -9.27,-5.19 -16.61,-12.39 -22.02,-21.6 -5.42,-9.21 -8.12,-19.62 -8.12,-31.23 0,-11.61 2.71,-22.02 8.12,-31.23 5.41,-9.21 12.75,-16.38 22.02,-21.52 9.26,-5.13 19.42,-7.7 30.47,-7.7 11.16,0 21.35,2.57 30.56,7.7 9.21,5.14 16.49,12.31 21.85,21.52 5.36,9.21 8.04,19.62 8.04,31.23 0,11.61 -2.68,22.02 -8.04,31.23 -5.36,9.21 -12.67,16.41 -21.93,21.6 -9.27,5.19 -19.42,7.79 -30.47,7.79 -11.06,-0.01 -21.22,-2.6 -30.48,-7.79 z m 50.31,-30.9 c 4.86,-5.47 7.28,-12.78 7.28,-21.93 0,-9.38 -2.43,-16.77 -7.28,-22.19 -4.86,-5.41 -11.47,-8.12 -19.84,-8.12 -8.48,0 -15.13,2.71 -19.93,8.12 -4.8,5.42 -7.2,12.81 -7.2,22.19 0,9.27 2.4,16.61 7.2,22.02 4.8,5.42 11.44,8.12 19.93,8.12 8.37,0 14.99,-2.74 19.84,-8.21 z"
|
||||||
|
id="path4" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 528.4,509.26 c -9.27,-5.19 -16.61,-12.39 -22.02,-21.6 -5.42,-9.21 -8.12,-19.62 -8.12,-31.23 0,-11.61 2.71,-22.02 8.12,-31.23 5.41,-9.21 12.75,-16.38 22.02,-21.52 9.26,-5.13 19.42,-7.7 30.47,-7.7 11.16,0 21.35,2.57 30.56,7.7 9.21,5.14 16.49,12.31 21.85,21.52 5.36,9.21 8.04,19.62 8.04,31.23 0,11.61 -2.68,22.02 -8.04,31.23 -5.36,9.21 -12.67,16.41 -21.93,21.6 -9.27,5.19 -19.42,7.79 -30.47,7.79 -11.05,-0.01 -21.21,-2.6 -30.48,-7.79 z m 50.32,-30.9 c 4.86,-5.47 7.28,-12.78 7.28,-21.93 0,-9.38 -2.43,-16.77 -7.28,-22.19 -4.86,-5.41 -11.47,-8.12 -19.84,-8.12 -8.48,0 -15.13,2.71 -19.93,8.12 -4.8,5.42 -7.2,12.81 -7.2,22.19 0,9.27 2.4,16.61 7.2,22.02 4.8,5.42 11.44,8.12 19.93,8.12 8.37,0 14.98,-2.74 19.84,-8.21 z"
|
||||||
|
id="path6" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="M 260.51,423.82 C 255,414.35 247.52,407 238.07,401.72 c -9.47,-5.28 -19.93,-7.92 -31.39,-7.92 -11.35,0 -21.79,2.64 -31.32,7.92 -9.52,5.28 -17.05,12.64 -22.62,22.1 -5.57,9.47 -8.34,20.16 -8.34,32.08 0,11.94 2.77,22.63 8.34,32.08 5.56,9.47 13.09,16.86 22.62,22.19 9.52,5.33 19.96,8 31.32,8 11.35,0 21.78,-2.67 31.3,-8 9.52,-5.33 17.03,-12.73 22.54,-22.19 5.51,-9.45 8.26,-20.14 8.26,-32.08 -0.01,-11.92 -2.77,-22.61 -8.27,-32.08 z m -33.46,54.62 c -4.99,5.62 -11.79,8.44 -20.38,8.44 -8.72,0 -15.54,-2.78 -20.48,-8.34 -4.93,-5.56 -7.39,-13.11 -7.39,-22.63 0,-9.63 2.46,-17.23 7.39,-22.79 4.93,-5.56 11.75,-8.34 20.48,-8.34 8.6,0 15.39,2.78 20.38,8.34 4.99,5.56 7.47,13.16 7.47,22.79 0.01,9.4 -2.48,16.91 -7.47,22.53 z"
|
||||||
|
id="path10" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 381.04,424.95 c -5.15,-9.18 -12.52,-16.32 -22.1,-21.41 -9.58,-5.1 -20.73,-7.66 -33.46,-7.66 h -48 v 121.28 h 48 c 12.61,0 23.7,-2.61 33.28,-7.83 9.58,-5.22 16.97,-12.41 22.19,-21.59 5.22,-9.18 7.83,-19.62 7.83,-31.31 0.01,-11.82 -2.58,-22.31 -7.74,-31.48 z m -34.92,54.35 c -5.62,5.39 -13.36,8.09 -23.22,8.09 h -11.7 v -62.27 h 11.7 c 9.87,0 17.6,2.72 23.22,8.17 5.62,5.45 8.44,13.16 8.44,23.13 -0.01,9.87 -2.82,17.49 -8.44,22.88 z"
|
||||||
|
id="path12" />
|
||||||
|
<g
|
||||||
|
id="g22">
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="742.83,486.53 713.07,486.53 750.82,441.47 "
|
||||||
|
id="polygon14" />
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="669.3,488.25 663.26,523.19 733.12,523.19 725.6,566.2 643.2,566.2 643.2,393.8 752.1,393.8 "
|
||||||
|
id="polygon16" />
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="782.29,486.53 798.47,393.8 815.61,393.8 815.61,486.53 "
|
||||||
|
id="polygon18" />
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="815.61,566.2 767.94,566.2 775.83,523.19 815.61,523.19 "
|
||||||
|
id="polygon20" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g40">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 162.99,549.74 c -1.81,1.75 -4.58,2.63 -8.3,2.63 h -6.13 v 13.31 H 144.4 V 533.8 h 10.29 c 3.6,0 6.34,0.87 8.21,2.61 1.87,1.74 2.81,3.98 2.81,6.72 0,2.65 -0.91,4.85 -2.72,6.61 z m -3.18,-2.31 c 1.1,-1.01 1.65,-2.44 1.65,-4.3 0,-3.93 -2.26,-5.9 -6.77,-5.9 h -6.13 v 11.71 h 6.13 c 2.31,0 4.02,-0.51 5.12,-1.51 z"
|
||||||
|
id="path24" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 224.26,565.68 -7.59,-13.04 h -5.03 v 13.04 h -4.16 V 533.8 h 10.29 c 2.41,0 4.44,0.41 6.11,1.23 1.66,0.82 2.9,1.94 3.73,3.34 0.82,1.4 1.23,3 1.23,4.8 0,2.2 -0.63,4.13 -1.9,5.81 -1.27,1.68 -3.16,2.79 -5.7,3.34 l 8.01,13.36 z M 211.64,549.3 h 6.13 c 2.26,0 3.95,-0.56 5.08,-1.67 1.13,-1.11 1.69,-2.6 1.69,-4.46 0,-1.89 -0.56,-3.35 -1.67,-4.39 -1.11,-1.04 -2.81,-1.56 -5.1,-1.56 h -6.13 z"
|
||||||
|
id="path26" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 278.24,563.92 c -2.44,-1.39 -4.37,-3.32 -5.79,-5.81 -1.42,-2.49 -2.13,-5.28 -2.13,-8.39 0,-3.11 0.71,-5.91 2.13,-8.39 1.42,-2.49 3.35,-4.42 5.79,-5.81 2.44,-1.39 5.14,-2.08 8.1,-2.08 2.99,0 5.7,0.69 8.14,2.08 2.44,1.39 4.36,3.32 5.76,5.79 1.4,2.47 2.1,5.28 2.1,8.42 0,3.14 -0.7,5.95 -2.1,8.42 -1.4,2.47 -3.32,4.4 -5.76,5.79 -2.44,1.39 -5.15,2.08 -8.14,2.08 -2.96,-0.02 -5.66,-0.71 -8.1,-2.1 z m 14.12,-3.09 c 1.78,-1.04 3.19,-2.52 4.21,-4.44 1.02,-1.92 1.53,-4.15 1.53,-6.68 0,-2.56 -0.51,-4.8 -1.53,-6.7 -1.02,-1.91 -2.42,-3.38 -4.19,-4.41 -1.77,-1.04 -3.78,-1.56 -6.04,-1.56 -2.26,0 -4.27,0.52 -6.04,1.56 -1.77,1.04 -3.16,2.51 -4.19,4.41 -1.02,1.91 -1.53,4.14 -1.53,6.7 0,2.53 0.51,4.76 1.53,6.68 1.02,1.92 2.42,3.4 4.21,4.44 1.78,1.04 3.79,1.56 6.02,1.56 2.23,-0.01 4.23,-0.52 6.02,-1.56 z"
|
||||||
|
id="path28" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 360.5,533.79 v 23.56 c 0,2.62 -0.81,4.72 -2.42,6.29 -1.62,1.57 -3.75,2.36 -6.4,2.36 -2.68,0 -4.83,-0.8 -6.45,-2.4 -1.62,-1.6 -2.42,-3.79 -2.42,-6.56 h 4.16 c 0.03,1.56 0.43,2.82 1.21,3.8 0.78,0.98 1.94,1.46 3.5,1.46 1.56,0 2.71,-0.46 3.48,-1.39 0.76,-0.93 1.14,-2.11 1.14,-3.55 V 533.8 h 4.2 z"
|
||||||
|
id="path30" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 409.44,537.18 v 10.66 h 11.62 v 3.43 h -11.62 v 10.98 h 12.99 v 3.43 h -17.15 v -31.93 h 17.15 v 3.43 z"
|
||||||
|
id="path32" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 465.89,541.32 c 1.4,-2.49 3.32,-4.43 5.74,-5.83 2.42,-1.4 5.12,-2.1 8.07,-2.1 3.48,0 6.51,0.84 9.1,2.52 2.59,1.68 4.48,4.06 5.67,7.14 h -4.99 c -0.89,-1.92 -2.16,-3.4 -3.82,-4.44 -1.66,-1.04 -3.65,-1.56 -5.97,-1.56 -2.23,0 -4.22,0.52 -5.99,1.56 -1.77,1.04 -3.16,2.51 -4.16,4.41 -1.01,1.91 -1.51,4.14 -1.51,6.7 0,2.53 0.5,4.75 1.51,6.66 1.01,1.91 2.39,3.38 4.16,4.41 1.77,1.04 3.77,1.56 5.99,1.56 2.32,0 4.31,-0.51 5.97,-1.53 1.66,-1.02 2.93,-2.49 3.82,-4.41 h 4.99 c -1.19,3.05 -3.08,5.41 -5.67,7.07 -2.59,1.66 -5.63,2.49 -9.1,2.49 -2.96,0 -5.65,-0.69 -8.07,-2.08 -2.42,-1.39 -4.34,-3.32 -5.74,-5.79 -1.4,-2.47 -2.1,-5.26 -2.1,-8.37 0,-3.11 0.7,-5.92 2.1,-8.41 z"
|
||||||
|
id="path34" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 556.88,533.79 v 3.38 h -8.69 v 28.5 h -4.16 v -28.5 h -8.74 v -3.38 z"
|
||||||
|
id="path36" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 603.06,564.88 c -1.66,-0.75 -2.97,-1.78 -3.91,-3.11 -0.95,-1.33 -1.43,-2.86 -1.46,-4.6 h 4.44 c 0.15,1.49 0.77,2.75 1.85,3.77 1.08,1.02 2.66,1.53 4.73,1.53 1.98,0 3.55,-0.49 4.69,-1.49 1.14,-0.99 1.72,-2.26 1.72,-3.82 0,-1.22 -0.34,-2.21 -1.01,-2.97 -0.67,-0.76 -1.51,-1.34 -2.52,-1.74 -1.01,-0.4 -2.36,-0.82 -4.07,-1.28 -2.1,-0.55 -3.79,-1.1 -5.06,-1.65 -1.27,-0.55 -2.35,-1.41 -3.25,-2.59 -0.9,-1.17 -1.35,-2.75 -1.35,-4.73 0,-1.74 0.44,-3.28 1.33,-4.62 0.88,-1.34 2.13,-2.38 3.73,-3.11 1.6,-0.73 3.44,-1.1 5.51,-1.1 2.99,0 5.44,0.75 7.34,2.24 1.91,1.5 2.98,3.48 3.22,5.95 h -4.57 c -0.15,-1.22 -0.79,-2.29 -1.92,-3.23 -1.13,-0.93 -2.62,-1.39 -4.48,-1.39 -1.74,0 -3.16,0.45 -4.25,1.35 -1.1,0.9 -1.65,2.16 -1.65,3.77 0,1.16 0.33,2.11 0.98,2.84 0.66,0.73 1.46,1.29 2.42,1.67 0.96,0.38 2.31,0.82 4.05,1.3 2.1,0.58 3.8,1.15 5.08,1.72 1.28,0.57 2.38,1.43 3.29,2.61 0.91,1.17 1.37,2.77 1.37,4.78 0,1.56 -0.41,3.02 -1.24,4.39 -0.83,1.37 -2.04,2.49 -3.66,3.34 -1.62,0.85 -3.52,1.28 -5.72,1.28 -2.08,0.01 -3.97,-0.36 -5.63,-1.11 z"
|
||||||
|
id="path38" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 486 KiB |
|
After Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 393 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 4.8 MiB |
|
After Width: | Height: | Size: 11 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 575 KiB |
|
After Width: | Height: | Size: 694 KiB |
|
After Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
|
||||||
|
<rect width="200" height="200" rx="32" fill="#f0cda8" />
|
||||||
|
<circle cx="100" cy="70" r="28" fill="#714b67" opacity="0.3" />
|
||||||
|
<path d="M65 130 Q65 100 100 100 Q135 100 135 130" fill="#714b67" opacity="0.3" />
|
||||||
|
<text x="100" y="155" text-anchor="middle" font-family="Inter Tight, sans-serif" font-size="18" font-weight="700" fill="#1b1319">Your</text>
|
||||||
|
<text x="100" y="177" text-anchor="middle" font-family="Inter Tight, sans-serif" font-size="18" font-weight="700" fill="#1b1319">Company</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 593 B |
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
|
||||||
|
<rect width="200" height="200" rx="28" fill="#f6f5f4"/>
|
||||||
|
<rect x="10" y="10" width="180" height="180" rx="24" fill="none" stroke="#e5e3e0" stroke-width="2" stroke-dasharray="6,4"/>
|
||||||
|
<circle cx="100" cy="65" r="24" fill="#714b67" opacity="0.15"/>
|
||||||
|
<path d="M68 115 Q68 90 100 90 Q132 90 132 115" fill="#714b67" opacity="0.15"/>
|
||||||
|
<text x="100" y="148" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="700" fill="#714b67">Your</text>
|
||||||
|
<text x="100" y="170" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="700" fill="#714b67">Company</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 703 B |
@@ -0,0 +1,158 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Legal information for ODOO4projects LLC — company details, contact, image credits, and trademark notices."
|
||||||
|
/>
|
||||||
|
<title>Legal | ODOO4projects</title>
|
||||||
|
<link rel="canonical" href="https://ODOO4projects.com/legal" />
|
||||||
|
<meta property="og:title" content="Legal | ODOO4projects" />
|
||||||
|
<meta property="og:description" content="Legal information for ODOO4projects LLC." />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://ODOO4projects.com/legal" />
|
||||||
|
<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
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
||||||
|
/>
|
||||||
|
<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>
|
||||||
|
.legal-hero {
|
||||||
|
padding: 4rem 0 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
background: var(--light);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.legal-hero h1 {
|
||||||
|
font-size: clamp(1.8rem, 3.2vw, 2.8rem);
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
.legal-section {
|
||||||
|
padding: 3rem 0 4rem;
|
||||||
|
}
|
||||||
|
.legal-section .container {
|
||||||
|
max-width: 700px;
|
||||||
|
}
|
||||||
|
.legal-card {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 1.75rem;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.legal-card:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.legal-card h2 {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.legal-card p,
|
||||||
|
.legal-card .address {
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
font-size: 0.88rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
.legal-card strong {
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
.legal-card .contact-email {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.image-credits {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.3rem;
|
||||||
|
}
|
||||||
|
.image-credits .credit-row {
|
||||||
|
color: rgba(33, 37, 41, 0.6);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
}
|
||||||
|
.image-credits .credit-row a {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
.trademark-notice {
|
||||||
|
background: rgba(113, 75, 103, 0.04);
|
||||||
|
border: 1px solid rgba(113, 75, 103, 0.15);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
}
|
||||||
|
.trademark-notice p {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
margin: 0;
|
||||||
|
color: rgba(33, 37, 41, 0.6);
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.legal-hero { padding: 2.5rem 0 1.5rem; }
|
||||||
|
.legal-card { padding: 1.25rem; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="blog-header">
|
||||||
|
<a href="index.html">← Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="legal-hero">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Legal</h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<div class="container">
|
||||||
|
<div class="legal-card">
|
||||||
|
<h2>Company Information</h2>
|
||||||
|
<p><strong>ODOO4projects LLC</strong></p>
|
||||||
|
<p class="address">
|
||||||
|
30 N Gould St, STE R, Sheridan<br />
|
||||||
|
WY 82801, USA
|
||||||
|
</p>
|
||||||
|
<p style="margin-top: 0.75rem;">
|
||||||
|
Contact: <span class="contact-email">support@ODOO4projects.com</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legal-card">
|
||||||
|
<h2>Image Credits</h2>
|
||||||
|
<div class="image-credits">
|
||||||
|
<span class="credit-row"><a href="https://pixabay.com/de/users/rafael_neddermeyer-5342045/" target="_blank" rel="noopener">Rafael_Neddermeyer</a> auf <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
<span class="credit-row"><a href="https://pixabay.com/de/users/nuno_lopes-27925/" target="_blank" rel="noopener">Nuno Lopes</a> auf <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
<span class="credit-row"><a href="https://pixabay.com/de/users/liushuquan-600749/" target="_blank" rel="noopener">liushuquan</a> auf <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
<span class="credit-row">von <a href="https://pixabay.com/de/users/iulian_ursache-17029687/" target="_blank" rel="noopener">Iulian Ursache</a> auf <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
<span class="credit-row"><a href="https://pixabay.com/de/users/pattyjansen-154933/" target="_blank" rel="noopener">Patty Jansen</a> auf <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
<span class="credit-row"><a href="https://pixabay.com/de/users/ananddhumal-5250062/" target="_blank" rel="noopener">Anand Dhumal</a> auf <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
<span class="credit-row"><a href="https://pixabay.com/users/giulivec-7339391/" target="_blank" rel="noopener">Giuliana Vecchi</a> from <a href="https://pixabay.com/" target="_blank" rel="noopener">Pixabay</a></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legal-card">
|
||||||
|
<h2>Trademark Notice</h2>
|
||||||
|
<div class="trademark-notice">
|
||||||
|
<p>Odoo<sup>®</sup> is a trademark of Odoo S.A. This site is totally independent of Odoo S.A.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# ODOO4projects
|
||||||
|
|
||||||
|
> ODOO4projects is a managed Odoo Community hosting service. We run the server, the backups, the
|
||||||
|
> SSL certificate and the version upgrades for a monthly-or-yearly price, so the customer does not
|
||||||
|
> have to administer a server. One login: everything happens inside the customer's own Odoo
|
||||||
|
> instance. We do not sell Odoo itself; we sell a business system that runs.
|
||||||
|
|
||||||
|
## Products and pricing (verified 2026-10-21, list prices, USD, VAT excluded)
|
||||||
|
|
||||||
|
- Side Hustle — $214 per year. Managed Odoo Community hosting: server, backups, SSL. No per-user
|
||||||
|
licence. No module installation on this plan.
|
||||||
|
- On the Rise — $395 per year. The same, plus Git and one-click module installs.
|
||||||
|
- Powerhouse and Empire — quoted on the plans page (no fixed price published).
|
||||||
|
- Odoo Community has no per-user licence. Odoo Enterprise, if the customer brings their own
|
||||||
|
licence, is licensed per user by Odoo S.A.
|
||||||
|
|
||||||
|
## What we support
|
||||||
|
|
||||||
|
- Odoo Community, hosted and managed.
|
||||||
|
- odoo.sh (Odoo S.A.'s own platform) — supported and coexists with our service.
|
||||||
|
- Growth into Odoo Enterprise — bring your own licence, keep the same instance, no migration.
|
||||||
|
- Own hardware — the Empire plan runs our service on the customer's own server.
|
||||||
|
|
||||||
|
## What we do not support
|
||||||
|
|
||||||
|
- Odoo Online (Odoo's SaaS). It runs Odoo's standard apps only and is incompatible with custom
|
||||||
|
modules, so it is not a fit for our managed Community model.
|
||||||
|
|
||||||
|
## Key pages
|
||||||
|
|
||||||
|
- [Odoo hosting 2027 — comparison landing page](https://odoo4projects.com/odoo-hosting-2027.html): every route to Odoo (managed, VPS, odoo.sh, Odoo Online, own hardware) side by side, with annual and five-year cost comparisons.
|
||||||
|
- [Home](https://odoo4projects.com/): plans and pricing, FAQ, server locations.
|
||||||
|
- [Support](https://odoo4projects.com/support.html): support and frequently asked questions.
|
||||||
|
- [Legal](https://odoo4projects.com/legal): company details.
|
||||||
|
- [Blog](https://odoo4projects.com/blog/): guides, how-tos and platform news.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Prices are list prices captured on 21 October 2026 and are re-checked before each publishing year.
|
||||||
|
- Findability: [sitemap.xml](https://odoo4projects.com/sitemap.xml).
|
||||||
@@ -0,0 +1,986 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Odoo Hosting 2027: Managed Odoo Community, Live in About Five Minutes</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Odoo hosting in 2027, compared: managed Odoo Community from ODOO4projects against a self-managed VPS, odoo.sh, Odoo Online and your own hardware. One login, one yearly price, no per-user licence."
|
||||||
|
/>
|
||||||
|
<link rel="canonical" href="https://odoo4projects.com/odoo-hosting-2027.html" />
|
||||||
|
<meta property="og:title" content="Odoo Hosting 2027: Managed Odoo Community, Live in About Five Minutes" />
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="Every route to Odoo side by side, and what it really costs over three to five years. One login, one yearly price, no per-user licence."
|
||||||
|
/>
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://odoo4projects.com/odoo-hosting-2027.html" />
|
||||||
|
<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
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Marcellus&display=swap"
|
||||||
|
media="print"
|
||||||
|
onload="this.media='all'"
|
||||||
|
/>
|
||||||
|
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Marcellus&display=swap" /></noscript>
|
||||||
|
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'" />
|
||||||
|
<noscript><link rel="stylesheet" href="style.css" /></noscript>
|
||||||
|
<style>
|
||||||
|
/* ---- Odoo Hosting 2027 landing page (page-scoped; additive) ---- */
|
||||||
|
.cmp-sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top bar (page-scoped: the site has no global header) */
|
||||||
|
.cmp-topbar {
|
||||||
|
background: var(--midnight-2);
|
||||||
|
border-bottom: 1px solid var(--line-brass);
|
||||||
|
padding: 0.85rem 0;
|
||||||
|
}
|
||||||
|
.cmp-topbar .container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.cmp-brand {
|
||||||
|
font-family: Marcellus, Georgia, serif;
|
||||||
|
font-size: 1.15rem;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.cmp-brand span {
|
||||||
|
color: var(--brass);
|
||||||
|
}
|
||||||
|
.cmp-topbar-links {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.25rem;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
}
|
||||||
|
.cmp-topbar-links a {
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
|
.cmp-topbar-links a:hover {
|
||||||
|
color: var(--brass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero */
|
||||||
|
.cmp-hero {
|
||||||
|
min-height: 0;
|
||||||
|
padding: 3.5rem 0 3rem;
|
||||||
|
}
|
||||||
|
.cmp-hero h1 span {
|
||||||
|
color: var(--brass);
|
||||||
|
}
|
||||||
|
.cmp-hero .hero-sub {
|
||||||
|
max-width: 620px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cmp-lead {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: var(--ink-soft);
|
||||||
|
max-width: 720px;
|
||||||
|
line-height: 1.75;
|
||||||
|
margin: 0 auto 1.5rem;
|
||||||
|
}
|
||||||
|
.section-light .section-title,
|
||||||
|
.section-light .section-kicker {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comparison tables (reuse .oca-table on dark sections) */
|
||||||
|
.cmp-table-wrap {
|
||||||
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
border: 1px solid var(--line-brass);
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
}
|
||||||
|
.cmp-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
min-width: 860px;
|
||||||
|
}
|
||||||
|
.cmp-table th,
|
||||||
|
.cmp-table td {
|
||||||
|
padding: 0.7rem 0.9rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
border-bottom: 1px solid rgba(201, 162, 39, 0.1);
|
||||||
|
}
|
||||||
|
.cmp-table thead th {
|
||||||
|
font-family: Marcellus, Georgia, serif;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--brass);
|
||||||
|
background: rgba(13, 27, 46, 0.55);
|
||||||
|
border-bottom: 1px solid var(--line-brass);
|
||||||
|
white-space: normal;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
.cmp-table tbody th {
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
|
}
|
||||||
|
.cmp-table td {
|
||||||
|
color: rgba(255, 255, 255, 0.78);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.cmp-table tbody tr:hover td,
|
||||||
|
.cmp-table tbody tr:hover th {
|
||||||
|
background: rgba(201, 162, 39, 0.06);
|
||||||
|
}
|
||||||
|
.cmp-table tbody tr:last-child th,
|
||||||
|
.cmp-table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.cmp-table .is-us {
|
||||||
|
background: rgba(201, 162, 39, 0.09);
|
||||||
|
}
|
||||||
|
.cmp-table thead th.is-us {
|
||||||
|
color: var(--brass-bright);
|
||||||
|
background: rgba(201, 162, 39, 0.14);
|
||||||
|
}
|
||||||
|
.cmp-table .is-us strong {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.cmp-flag {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-size: 0.69rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--midnight);
|
||||||
|
background: var(--brass);
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
padding: 0.1rem 0.5rem;
|
||||||
|
margin-left: 0.35rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.cmp-not-us {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-size: 0.69rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #ffd9d9;
|
||||||
|
background: rgba(190, 40, 40, 0.35);
|
||||||
|
border: 1px solid rgba(255, 120, 120, 0.45);
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
padding: 0.1rem 0.5rem;
|
||||||
|
margin-left: 0.35rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notes under the tables */
|
||||||
|
.cmp-notes {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1.75rem;
|
||||||
|
}
|
||||||
|
.cmp-note {
|
||||||
|
background: rgba(255, 255, 255, 0.04);
|
||||||
|
border: 1px solid var(--line-brass);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 1.15rem 1.25rem;
|
||||||
|
}
|
||||||
|
.cmp-note h3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.cmp-note p {
|
||||||
|
font-size: 0.84rem;
|
||||||
|
color: rgba(255, 255, 255, 0.72);
|
||||||
|
line-height: 1.65;
|
||||||
|
margin-bottom: 0.7rem;
|
||||||
|
}
|
||||||
|
.cmp-note p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.cmp-note a {
|
||||||
|
color: var(--brass-bright);
|
||||||
|
}
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
.cmp-notes {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cost infographic */
|
||||||
|
.cmp-figure {
|
||||||
|
margin: 2rem auto 0;
|
||||||
|
max-width: 780px;
|
||||||
|
}
|
||||||
|
.cmp-figure svg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.cmp-figure figcaption {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: var(--ink-faint);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.cmp-bar-label {
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
fill: var(--ink);
|
||||||
|
}
|
||||||
|
.cmp-bar-label.is-us {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.cmp-bar-value {
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
fill: var(--midnight);
|
||||||
|
}
|
||||||
|
.cmp-bar {
|
||||||
|
transform-box: fill-box;
|
||||||
|
transform-origin: left center;
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
.cmp-bar {
|
||||||
|
animation: cmpGrow 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||||
|
}
|
||||||
|
.cmp-bar:nth-of-type(2) {
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
}
|
||||||
|
.cmp-bar:nth-of-type(3) {
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes cmpGrow {
|
||||||
|
from {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cost table extras */
|
||||||
|
.cmp-cost-note {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 1.5rem auto 0;
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
.cmp-cost-note li {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 1.4rem;
|
||||||
|
margin-bottom: 0.6rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: rgba(255, 255, 255, 0.75);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.cmp-cost-note li::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0.25rem;
|
||||||
|
top: 0.5rem;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--brass);
|
||||||
|
}
|
||||||
|
.cmp-cost-note strong {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FAQ (native details/summary — no JS) */
|
||||||
|
.cmp-faq-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.cmp-faq {
|
||||||
|
background: var(--ivory);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 0.4rem 1.25rem;
|
||||||
|
box-shadow: var(--shadow-rest);
|
||||||
|
transition: box-shadow 0.25s;
|
||||||
|
}
|
||||||
|
.cmp-faq[open] {
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
}
|
||||||
|
.cmp-faq:hover {
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
}
|
||||||
|
.cmp-faq summary {
|
||||||
|
cursor: pointer;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0.85rem 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
font-family: Marcellus, Georgia, serif;
|
||||||
|
font-size: 0.98rem;
|
||||||
|
color: var(--midnight);
|
||||||
|
}
|
||||||
|
.cmp-faq summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.cmp-faq summary::after {
|
||||||
|
content: "+";
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
color: var(--brass);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
line-height: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: transform 0.25s;
|
||||||
|
}
|
||||||
|
.cmp-faq[open] summary::after {
|
||||||
|
content: "\2212";
|
||||||
|
}
|
||||||
|
.cmp-faq summary:focus-visible {
|
||||||
|
outline: 2px solid var(--brass);
|
||||||
|
outline-offset: 3px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
.cmp-faq .cmp-a {
|
||||||
|
font-size: 0.87rem;
|
||||||
|
color: var(--ink-soft);
|
||||||
|
line-height: 1.7;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.cmp-faq .cmp-a p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.cmp-faq-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Final CTA band */
|
||||||
|
.cmp-cta {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.cmp-cta .cmp-lead {
|
||||||
|
color: rgba(255, 255, 255, 0.72);
|
||||||
|
}
|
||||||
|
.cmp-cta-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
.cmp-cta p.cmp-cta-answers {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus states on every CTA */
|
||||||
|
.btn:focus-visible,
|
||||||
|
.cmp-topbar-links a:focus-visible,
|
||||||
|
.cmp-note a:focus-visible {
|
||||||
|
outline: 3px solid var(--brass-bright);
|
||||||
|
outline-offset: 2px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
.btn-brass:focus-visible {
|
||||||
|
outline-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@graph": [
|
||||||
|
{
|
||||||
|
"@type": "Organization",
|
||||||
|
"@id": "https://odoo4projects.com/#organization",
|
||||||
|
"name": "ODOO4projects",
|
||||||
|
"url": "https://odoo4projects.com/",
|
||||||
|
"foundingDate": "2020",
|
||||||
|
"sameAs": ["https://www.linkedin.com/company/odoo4projects/"],
|
||||||
|
"contactPoint": {
|
||||||
|
"@type": "ContactPoint",
|
||||||
|
"contactType": "customer support",
|
||||||
|
"url": "https://odoo4projects.com/support.html#contact"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "WebPage",
|
||||||
|
"@id": "https://odoo4projects.com/odoo-hosting-2027.html",
|
||||||
|
"url": "https://odoo4projects.com/odoo-hosting-2027.html",
|
||||||
|
"name": "Odoo Hosting 2027: Managed Odoo Community, Live in About Five Minutes",
|
||||||
|
"description": "A comparison of every route to Odoo in 2027: managed Odoo Community, a self-managed VPS, odoo.sh, Odoo Online and your own hardware.",
|
||||||
|
"isPartOf": { "@id": "https://odoo4projects.com/#organization" },
|
||||||
|
"about": [
|
||||||
|
{ "@type": "Thing", "name": "Odoo hosting" },
|
||||||
|
{ "@type": "Thing", "name": "managed Odoo Community hosting" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "BreadcrumbList",
|
||||||
|
"itemListElement": [
|
||||||
|
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://odoo4projects.com/" },
|
||||||
|
{ "@type": "ListItem", "position": 2, "name": "Odoo Hosting 2027", "item": "https://odoo4projects.com/odoo-hosting-2027.html" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Product",
|
||||||
|
"name": "Managed Odoo Community hosting",
|
||||||
|
"description": "Managed Odoo Community hosting: the server, backups, SSL certificate and version upgrades are run for you on one yearly price, with no per-user licence on Odoo Community.",
|
||||||
|
"brand": { "@id": "https://odoo4projects.com/#organization" },
|
||||||
|
"offers": [
|
||||||
|
{
|
||||||
|
"@type": "Offer",
|
||||||
|
"name": "Side Hustle",
|
||||||
|
"price": "214.00",
|
||||||
|
"priceCurrency": "USD",
|
||||||
|
"url": "https://odoo4projects.com/#pricing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Offer",
|
||||||
|
"name": "On the Rise",
|
||||||
|
"price": "395.00",
|
||||||
|
"priceCurrency": "USD",
|
||||||
|
"url": "https://odoo4projects.com/#pricing"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "FAQPage",
|
||||||
|
"mainEntity": [
|
||||||
|
{
|
||||||
|
"@type": "Question",
|
||||||
|
"name": "What does \"five minutes\" actually mean?",
|
||||||
|
"acceptedAnswer": {
|
||||||
|
"@type": "Answer",
|
||||||
|
"text": "Five minutes is the time to a running instance, not to a finished system. Putting your own customers, products and stock in is the first week's work, and it is the same week on any of the routes above."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Question",
|
||||||
|
"name": "Do you support Odoo Online?",
|
||||||
|
"acceptedAnswer": {
|
||||||
|
"@type": "Answer",
|
||||||
|
"text": "No. Odoo Online runs Odoo's standard apps only and is incompatible with custom modules or modules from the Odoo Apps Store, so you cannot add an app that is not on Odoo's list. Upgrades are automatic and mandatory on Odoo's schedule. If Odoo's standard apps cover everything you will ever need, Odoo Online is the cheaper and simpler answer and we are not the right choice."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Question",
|
||||||
|
"name": "Can I add my own apps or OCA modules?",
|
||||||
|
"acceptedAnswer": {
|
||||||
|
"@type": "Answer",
|
||||||
|
"text": "Odoo's own apps are all there on every plan. Custom and OCA modules install from On the Rise up, by Git or one click. Side Hustle has no module installation."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Question",
|
||||||
|
"name": "Do I need an AI assistant to use ODOO4projects?",
|
||||||
|
"acceptedAnswer": {
|
||||||
|
"@type": "Answer",
|
||||||
|
"text": "No. We ship our MCP server directly in the apps, so an AI assistant such as Claude Code or Hermes can restart the server, upload a module, add a domain or read the log for you, and you never open a hosting panel. It is optional: the business works exactly the same without it."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Question",
|
||||||
|
"name": "Can we move to Odoo Enterprise later?",
|
||||||
|
"acceptedAnswer": {
|
||||||
|
"@type": "Answer",
|
||||||
|
"text": "Yes. Bring your own Odoo Enterprise licence and keep the same instance. No migration."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Question",
|
||||||
|
"name": "Is there a per-user licence?",
|
||||||
|
"acceptedAnswer": {
|
||||||
|
"@type": "Answer",
|
||||||
|
"text": "No. Odoo Community has no per-user licence; our plans are one flat yearly price. Odoo Enterprise, if you bring it, is licensed per user by Odoo S.A."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Page-scoped top bar: the site has no global header, so the page carries its own way home. -->
|
||||||
|
<div class="cmp-topbar">
|
||||||
|
<div class="container">
|
||||||
|
<a class="cmp-brand" href="index.html">ODOO4<span>projects</span></a>
|
||||||
|
<nav class="cmp-topbar-links" aria-label="Page links">
|
||||||
|
<a href="index.html#pricing">Plans & pricing</a>
|
||||||
|
<a href="support.html">Support</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="hero cmp-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="hero-kicker">Managed Odoo Community Hosting</p>
|
||||||
|
<h1>Odoo Hosting 2027: Managed Odoo Community, <span>Live in About Five Minutes</span></h1>
|
||||||
|
<p class="hero-sub">
|
||||||
|
A managed Odoo Community instance: your stock, orders, invoices and customers in one system. We
|
||||||
|
run the server, the backups, the certificate and the upgrades. You put your own data in and get on
|
||||||
|
with the business.
|
||||||
|
</p>
|
||||||
|
<div class="hero-stats">
|
||||||
|
<span class="hero-stat"><i aria-hidden="true">✓</i> About 5 minutes to a live instance</span>
|
||||||
|
<span class="hero-stat"><i aria-hidden="true">✓</i> One login, one place to work</span>
|
||||||
|
<span class="hero-stat"><i aria-hidden="true">✓</i> No per-user licence</span>
|
||||||
|
<span class="hero-stat"><i aria-hidden="true">✓</i> One yearly price</span>
|
||||||
|
</div>
|
||||||
|
<div class="hero-actions">
|
||||||
|
<a href="index.html#trialCard" class="btn btn-brass btn-lg">Start the free trial</a>
|
||||||
|
<a href="index.html#pricing" class="btn btn-outline btn-lg">See plans and pricing</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Mission -->
|
||||||
|
<section class="section-light">
|
||||||
|
<div class="container">
|
||||||
|
<p class="section-kicker">Why we exist</p>
|
||||||
|
<h2 class="section-title">We don't sell Odoo. We sell a business that runs.</h2>
|
||||||
|
<p class="cmp-lead">
|
||||||
|
You should not have to become the IT department to find out what is in your stock. A business
|
||||||
|
system is something you subscribe to, not a project you build. The server, the patches, the
|
||||||
|
backups, the certificate, the version upgrade: those are our job, permanently, and not an evening
|
||||||
|
you hand back to the company.
|
||||||
|
</p>
|
||||||
|
<p class="cmp-lead">
|
||||||
|
So we put your stock, your orders, your invoices and who owes you money in one place, and we keep
|
||||||
|
the machine underneath it alive. That is the whole offer.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Feature comparison -->
|
||||||
|
<section class="section-dark" id="comparison">
|
||||||
|
<div class="container">
|
||||||
|
<p class="section-kicker">Every route to Odoo</p>
|
||||||
|
<h2 class="section-title">Side by side, and what each one asks of you</h2>
|
||||||
|
<div class="cmp-table-wrap">
|
||||||
|
<table class="cmp-table">
|
||||||
|
<caption class="cmp-sr-only">
|
||||||
|
Feature comparison of ODOO4projects managed hosting against a self-managed VPS, odoo.sh, Odoo
|
||||||
|
Online and your own hardware.
|
||||||
|
</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Comparison</th>
|
||||||
|
<th scope="col" class="is-us">ODOO4projects</th>
|
||||||
|
<th scope="col">Self-managed VPS</th>
|
||||||
|
<th scope="col">odoo.sh</th>
|
||||||
|
<th scope="col">Odoo Online</th>
|
||||||
|
<th scope="col">Own hardware</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">What you get</th>
|
||||||
|
<td class="is-us"><strong>Odoo Community, hosted and managed.</strong> Stock, orders, invoices, customers and accounting in one system.</td>
|
||||||
|
<td>Odoo Community on a server you rent, install and run yourself.</td>
|
||||||
|
<td>Odoo Enterprise on Odoo S.A.'s platform, built for a Git and developer workflow.</td>
|
||||||
|
<td>Odoo's standard apps only, hosted by Odoo. <span class="cmp-not-us">Not supported by us</span></td>
|
||||||
|
<td>Odoo on a machine you own, in your building.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Who runs the server and patches it</th>
|
||||||
|
<td class="is-us">We do.</td>
|
||||||
|
<td>You. You install it, patch it and fix it.</td>
|
||||||
|
<td>Odoo S.A. runs the servers; you still need a developer for the code side.</td>
|
||||||
|
<td>Odoo S.A.</td>
|
||||||
|
<td>You. Or our Empire plan runs our service on your server.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Time to a live instance</th>
|
||||||
|
<td class="is-us">About five minutes: pick a plan and a region and the instance is live.</td>
|
||||||
|
<td>You install it first, before it is a system.</td>
|
||||||
|
<td>You connect GitHub, then deploy by pushing a branch.</td>
|
||||||
|
<td>Sign up and use it. Nothing to install.</td>
|
||||||
|
<td>You install it on your own machine.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Backups, SSL certificate, domain</th>
|
||||||
|
<td class="is-us">Run for you on every plan. No schedule for you to set.</td>
|
||||||
|
<td>Yours: database dump, certificate, DNS record.</td>
|
||||||
|
<td>Odoo runs the backups and handles DNS on the platform.</td>
|
||||||
|
<td>Odoo runs the backups and handles the domain.</td>
|
||||||
|
<td>Yours: dump, certificate, DNS and the machine itself.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Where you manage it</th>
|
||||||
|
<td class="is-us">Inside your Odoo instance. One login, one place to work.</td>
|
||||||
|
<td>A hosting panel, a terminal and Odoo.</td>
|
||||||
|
<td>The odoo.sh dashboard, GitHub and Odoo.</td>
|
||||||
|
<td>Odoo and Odoo's control centre.</td>
|
||||||
|
<td>Wherever you install it.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">AI assistant control (Claude Code, Hermes)</th>
|
||||||
|
<td class="is-us">Included. Our MCP server ships in the apps.</td>
|
||||||
|
<td>You build it yourself.</td>
|
||||||
|
<td>Not provided by us.</td>
|
||||||
|
<td>Not supported by us.</td>
|
||||||
|
<td>Through our service on your server.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Adding your own apps</th>
|
||||||
|
<td class="is-us">Odoo's own apps are all there on every plan. Custom and OCA modules install from On the Rise up, by Git or one click. Side Hustle has no module installation.</td>
|
||||||
|
<td>Yes, if you can run the install.</td>
|
||||||
|
<td>Yes, through Git, with a developer.</td>
|
||||||
|
<td>No. You cannot add any app that is not on Odoo's list, not even the free ones.</td>
|
||||||
|
<td>Yes, if you can run the install.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Price model</th>
|
||||||
|
<td class="is-us">One flat yearly price. No per-user licence on Community.</td>
|
||||||
|
<td>Server rental only, plus your hours.</td>
|
||||||
|
<td>Per-user Odoo licence plus hosting, billed separately.</td>
|
||||||
|
<td>Per user, per month, all in.</td>
|
||||||
|
<td>You buy the machine and pay for everything it needs.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Version upgrades</th>
|
||||||
|
<td class="is-us">A support ticket. We migrate versions 17, 18 and 19.</td>
|
||||||
|
<td>You do it, after taking a full backup.</td>
|
||||||
|
<td>Push to the branch; if a module update fails, Odoo reverts the server and rolls the database back.</td>
|
||||||
|
<td>Automatic and mandatory on Odoo's schedule.</td>
|
||||||
|
<td>You do it.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Growth to Enterprise</th>
|
||||||
|
<td class="is-us">Bring your own Odoo Enterprise licence and keep the same instance. No migration.</td>
|
||||||
|
<td>Supported: Community to Enterprise on the same server.</td>
|
||||||
|
<td>An Odoo Enterprise licence is required to be on odoo.sh at all.</td>
|
||||||
|
<td>It is Enterprise software already.</td>
|
||||||
|
<td>Supported on the same server.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cmp-notes">
|
||||||
|
<div class="cmp-note">
|
||||||
|
<h3>Five minutes, honestly</h3>
|
||||||
|
<p>
|
||||||
|
Five minutes is the time to a running instance, not to a finished system. Putting your own
|
||||||
|
customers, products and stock in is the first week's work, and it is the same week on any of
|
||||||
|
the routes above.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="cmp-note">
|
||||||
|
<h3>About Odoo Online, and why we don't support it</h3>
|
||||||
|
<p>
|
||||||
|
Odoo Online runs Odoo's standard apps only. Odoo's own documentation states it is
|
||||||
|
<em>"incompatible with custom modules or modules from the Odoo Apps Store"</em>, so you cannot
|
||||||
|
add an app that is not on Odoo's list. Upgrades are automatic and mandatory on Odoo's
|
||||||
|
schedule, whether the timing suits your quarter or not. You can download your data from Odoo
|
||||||
|
Online; what you cannot take with you is the system you built on top of it.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The honest part: if Odoo's standard apps cover everything you will ever need, Odoo Online is
|
||||||
|
the cheaper and simpler answer and we are not the right choice. We are for the business that
|
||||||
|
will need an app Odoo does not have, or that wants to keep running the version it uses today.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="cmp-note">
|
||||||
|
<h3>Claude Code and Hermes</h3>
|
||||||
|
<p>
|
||||||
|
We ship our MCP server directly in the apps. If you use an AI assistant, it can restart the
|
||||||
|
server, upload a module, add a domain or read the log for you, and you never open a hosting
|
||||||
|
panel. It is optional. The business works exactly the same without it.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Cost over time -->
|
||||||
|
<section class="section-light" id="lifetime-cost">
|
||||||
|
<div class="container">
|
||||||
|
<p class="section-kicker">The bill behind the bill</p>
|
||||||
|
<h2 class="section-title">What the price really is over three to five years</h2>
|
||||||
|
<p class="cmp-lead">
|
||||||
|
Over three to five years, the monthly figure is the small half of the bill. A rented server costs
|
||||||
|
about $102 a year (OVH VPS-2, VAT excluded). What is not in that number is the person who installs
|
||||||
|
Odoo, patches the operating system, watches the certificate, takes the backups and runs the
|
||||||
|
version upgrade.
|
||||||
|
</p>
|
||||||
|
<p class="cmp-lead">
|
||||||
|
Odoo's own documentation says updating is <em>"most appropriately accomplished by the person who
|
||||||
|
deployed Odoo initially"</em>. OVH's own FAQ says a VPS <em>"requires basic knowledge of server
|
||||||
|
administration"</em>. On a VPS, that person is you or someone you pay, and neither line appears on
|
||||||
|
the invoice.
|
||||||
|
</p>
|
||||||
|
<p class="cmp-lead">
|
||||||
|
Our price is one number, once a year, and it covers that work: the server, the certificate, the
|
||||||
|
backups, the upgrade ticket and support when something breaks. Over five years, $214 a year is
|
||||||
|
$1,070. That is the whole cost of the hosting, not the deposit on it.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<figure class="cmp-figure">
|
||||||
|
<svg viewBox="0 0 760 260" role="img" aria-labelledby="cmpChartTitle cmpChartDesc" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<title id="cmpChartTitle">Five-year total cost at list price: ODOO4projects Side Hustle $1,070, Odoo Online $23,340, odoo.sh $49,188</title>
|
||||||
|
<desc id="cmpChartDesc">Horizontal bar chart comparing five-year list-price totals. ODOO4projects Side Hustle is $1,070 and is by far the shortest bar. Odoo Online is $23,340 and odoo.sh is $49,188. The Odoo Online and odoo.sh totals do not include your own time.</desc>
|
||||||
|
|
||||||
|
<!-- baseline -->
|
||||||
|
<line x1="196" y1="20" x2="196" y2="230" stroke="rgba(23,28,38,0.18)" stroke-width="1" />
|
||||||
|
|
||||||
|
<!-- Side Hustle (ours) -->
|
||||||
|
<text class="cmp-bar-label is-us" x="0" y="60">ODOO4projects</text>
|
||||||
|
<text class="cmp-bar-label is-us" x="0" y="76" fill="rgba(23,28,38,0.55)">Side Hustle</text>
|
||||||
|
<rect class="cmp-bar" x="196" y="40" width="22" height="34" rx="3" fill="#c9a227" />
|
||||||
|
<text class="cmp-bar-value" x="228" y="62">$1,070</text>
|
||||||
|
|
||||||
|
<!-- Odoo Online -->
|
||||||
|
<text class="cmp-bar-label" x="0" y="130">Odoo Online</text>
|
||||||
|
<text class="cmp-bar-label" x="0" y="146" fill="rgba(23,28,38,0.55)">(not supported by us)</text>
|
||||||
|
<rect class="cmp-bar" x="196" y="110" width="240" height="34" rx="3" fill="#8ea0b8" />
|
||||||
|
<text class="cmp-bar-value" x="446" y="132">$23,340</text>
|
||||||
|
|
||||||
|
<!-- odoo.sh -->
|
||||||
|
<text class="cmp-bar-label" x="0" y="200">odoo.sh</text>
|
||||||
|
<text class="cmp-bar-label" x="0" y="216" fill="rgba(23,28,38,0.55)">+ Enterprise licence</text>
|
||||||
|
<rect class="cmp-bar" x="196" y="180" width="506" height="34" rx="3" fill="#4d5f79" />
|
||||||
|
<text class="cmp-bar-value" x="712" y="202">$49,188</text>
|
||||||
|
|
||||||
|
<!-- scale ticks -->
|
||||||
|
<g stroke="rgba(23,28,38,0.15)" stroke-width="1">
|
||||||
|
<line x1="322" y1="20" x2="322" y2="230" />
|
||||||
|
<line x1="448" y1="20" x2="448" y2="230" />
|
||||||
|
<line x1="574" y1="20" x2="574" y2="230" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<figcaption>
|
||||||
|
Five-year totals at list price. Odoo Online and odoo.sh do not include your own time; ours
|
||||||
|
carries no per-user licence.
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Cost comparison -->
|
||||||
|
<section class="section-dark" id="cost">
|
||||||
|
<div class="container">
|
||||||
|
<p class="section-kicker">The same table for everyone</p>
|
||||||
|
<h2 class="section-title">What a ten-user business pays in a year</h2>
|
||||||
|
<p class="cmp-lead" style="color: rgba(255, 255, 255, 0.72)">
|
||||||
|
Our own price is in the same table as everyone else's.
|
||||||
|
</p>
|
||||||
|
<div class="cmp-table-wrap">
|
||||||
|
<table class="cmp-table">
|
||||||
|
<caption class="cmp-sr-only">
|
||||||
|
Annual cost for a ten-user business by route, with what each figure covers.
|
||||||
|
</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Route</th>
|
||||||
|
<th scope="col">Per year (10 users)</th>
|
||||||
|
<th scope="col">What the number covers</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="is-us">ODOO4projects — Side Hustle</th>
|
||||||
|
<td class="is-us"><strong>$214</strong></td>
|
||||||
|
<td class="is-us">Managed Odoo Community hosting: server, backups, SSL, support. No per-user licence. No module installation on this plan.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="is-us">ODOO4projects — On the Rise</th>
|
||||||
|
<td class="is-us"><strong>$395</strong></td>
|
||||||
|
<td class="is-us">The same, plus Git and one-click module installs.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Self-managed VPS</th>
|
||||||
|
<td><strong>about $102</strong></td>
|
||||||
|
<td>A rented OVH VPS-2 (4 vCores, 8 GB), VAT excluded. Odoo Community itself is free. Does not include any of the administration.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">odoo.sh</th>
|
||||||
|
<td><strong>$9,837.60 at list price</strong> ($8,013.60 in year one)</td>
|
||||||
|
<td>$693.60 hosting plus the Odoo Enterprise Custom licence at $76.20 per user per month at list ($61.00 in year one).</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Odoo Online <span class="cmp-not-us">Not supported by us</span></th>
|
||||||
|
<td><strong>$4,668 at list price</strong> ($3,732 in year one)</td>
|
||||||
|
<td>Odoo Standard at $38.90 per user per month at list ($31.10 in year one). Odoo's apps, hosting and support included.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Own hardware</th>
|
||||||
|
<td><strong>no verified total</strong></td>
|
||||||
|
<td>A comparable single-tenant rented machine is €708 a year (Hetzner AX41, VAT excluded). The purchase price of a server, and its power, network and IT labour, are not verified, so we do not print a figure.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="cmp-cost-note">
|
||||||
|
<li>
|
||||||
|
Prices are list prices captured on 21 October 2026, in US dollars unless stated, VAT excluded.
|
||||||
|
Vendors change prices. We will re-check every number before this page goes up for 2027.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Odoo's $31.10 and $61.00 rates are twelve-month introductory discounts. The list rates are
|
||||||
|
$38.90 and $76.20. Both are shown, because a reader in 2027 may be past the discount.
|
||||||
|
</li>
|
||||||
|
<li>The per-user prices are for a ten-user company. Ours carries no per-user licence, because Odoo Community has none.</li>
|
||||||
|
<li>
|
||||||
|
<strong>Odoo Online is cheaper than us for a business that only needs Odoo's standard apps.</strong>
|
||||||
|
If that is you, it is the right answer and we are not.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Five-year totals at list: Side Hustle $1,070, Odoo Online $23,340, odoo.sh $49,188. The last two
|
||||||
|
do not include your time, and ours carries no per-user licence.
|
||||||
|
</li>
|
||||||
|
<li>Our Powerhouse and Empire plans are quoted on the plans page.</li>
|
||||||
|
<li>
|
||||||
|
Prices are from the vendors' own published pages (odoo.com/pricing, odoo.sh/pricing,
|
||||||
|
ovhcloud.com, hetzner.com), so you can check every figure here yourself.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FAQ -->
|
||||||
|
<section class="section-light" id="faq">
|
||||||
|
<div class="container">
|
||||||
|
<p class="section-kicker">Straight answers</p>
|
||||||
|
<h2 class="section-title">Questions the table raises</h2>
|
||||||
|
<div class="cmp-faq-grid">
|
||||||
|
<details class="cmp-faq">
|
||||||
|
<summary>What does "five minutes" actually mean?</summary>
|
||||||
|
<div class="cmp-a">
|
||||||
|
<p>Five minutes is the time to a running instance, not to a finished system. Putting your own customers, products and stock in is the first week's work, and it is the same week on any of the routes above.</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<details class="cmp-faq">
|
||||||
|
<summary>Do you support Odoo Online?</summary>
|
||||||
|
<div class="cmp-a">
|
||||||
|
<p>No. Odoo Online runs Odoo's standard apps only and is incompatible with custom modules or modules from the Odoo Apps Store, so you cannot add an app that is not on Odoo's list. Upgrades are automatic and mandatory on Odoo's schedule. If Odoo's standard apps cover everything you will ever need, Odoo Online is the cheaper and simpler answer and we are not the right choice.</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<details class="cmp-faq">
|
||||||
|
<summary>Can I add my own apps or OCA modules?</summary>
|
||||||
|
<div class="cmp-a">
|
||||||
|
<p>Odoo's own apps are all there on every plan. Custom and OCA modules install from On the Rise up, by Git or one click. Side Hustle has no module installation.</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<details class="cmp-faq">
|
||||||
|
<summary>Do I need an AI assistant to use ODOO4projects?</summary>
|
||||||
|
<div class="cmp-a">
|
||||||
|
<p>No. We ship our MCP server directly in the apps, so an AI assistant such as Claude Code or Hermes can restart the server, upload a module, add a domain or read the log for you, and you never open a hosting panel. It is optional: the business works exactly the same without it.</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<details class="cmp-faq">
|
||||||
|
<summary>Can we move to Odoo Enterprise later?</summary>
|
||||||
|
<div class="cmp-a">
|
||||||
|
<p>Yes. Bring your own Odoo Enterprise licence and keep the same instance. No migration.</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<details class="cmp-faq">
|
||||||
|
<summary>Is there a per-user licence?</summary>
|
||||||
|
<div class="cmp-a">
|
||||||
|
<p>No. Odoo Community has no per-user licence; our plans are one flat yearly price. Odoo Enterprise, if you bring it, is licensed per user by Odoo S.A.</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Final CTA -->
|
||||||
|
<section class="section-dark cmp-cta" id="start">
|
||||||
|
<div class="container">
|
||||||
|
<p class="section-kicker">One login. One yearly price.</p>
|
||||||
|
<h2 class="section-title">Your business in one system, on a server you never think about</h2>
|
||||||
|
<p class="cmp-lead">
|
||||||
|
Your stock, your orders, your invoices and who owes you money in one system, on a server you never
|
||||||
|
have to think about. One login. One yearly price. No per-user licence.
|
||||||
|
</p>
|
||||||
|
<div class="cmp-cta-actions">
|
||||||
|
<a href="index.html#trialCard" class="btn btn-brass btn-lg">Start the free trial</a>
|
||||||
|
<a href="index.html#pricing" class="btn btn-outline btn-lg">See plans and pricing</a>
|
||||||
|
</div>
|
||||||
|
<p class="cmp-cta-answers">
|
||||||
|
Prices on this page were captured on 21 October 2026 and are re-checked before 2027.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Footer (copied from index.html; icon-font glyphs replaced with inline SVG so the page
|
||||||
|
carries no external icon dependency) -->
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="container">
|
||||||
|
<div class="fgrid">
|
||||||
|
<div>
|
||||||
|
<h4>Useful Links</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="index.html">Home</a></li>
|
||||||
|
<li><a href="odoo-hosting-2027.html">Odoo hosting 2027</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>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Partners</h4>
|
||||||
|
<div class="partner-list">
|
||||||
|
<a href="https://oc-guy.com" target="_blank" rel="noopener" class="partner-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#c9a227" stroke-width="2" aria-hidden="true"><path d="M20 7h-9M14 17H5M20 7l-4-4M20 7l-4 4M4 17l4 4M4 17l4-4" /></svg> OC Guy</a>
|
||||||
|
<a href="https://oca-py.org" target="_blank" rel="noopener" class="partner-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#c9a227" stroke-width="2" aria-hidden="true"><path d="M20 7h-9M14 17H5M20 7l-4-4M20 7l-4 4M4 17l4 4M4 17l4-4" /></svg> OCA Paraguay</a>
|
||||||
|
<a href="https://OD8N.com" target="_blank" rel="noopener" class="partner-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#c9a227" stroke-width="2" aria-hidden="true"><path d="M20 7h-9M14 17H5M20 7l-4-4M20 7l-4 4M4 17l4 4M4 17l4-4" /></svg> OD8N</a>
|
||||||
|
</div>
|
||||||
|
</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>From streamlined sales to global rollouts, our <strong>lean, eco-friendly</strong> approach helps businesses cut costs, boost efficiency, and grow without limits.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Follow us on</h4>
|
||||||
|
<div class="social">
|
||||||
|
<a href="https://www.linkedin.com/company/odoo4projects/" target="_blank" aria-label="LinkedIn"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3zM9 9h3.8v1.7h.05c.53-.95 1.83-1.95 3.76-1.95 4.02 0 4.76 2.5 4.76 5.75V21h-4v-5.5c0-1.31-.02-3-1.9-3-1.9 0-2.19 1.42-2.19 2.9V21H9z" /></svg></a>
|
||||||
|
<a href="https://www.youtube.com/@ODOO4projects" target="_blank" aria-label="YouTube"><svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M23 12s0-3.2-.41-4.73a2.5 2.5 0 0 0-1.76-1.77C19.3 5.1 12 5.1 12 5.1s-7.3 0-8.83.4A2.5 2.5 0 0 0 1.4 7.27C1 8.8 1 12 1 12s0 3.2.41 4.73a2.5 2.5 0 0 0 1.76 1.77c1.53.4 8.83.4 8.83.4s7.3 0 8.83-.4a2.5 2.5 0 0 0 1.76-1.77C23 15.2 23 12 23 12zM9.75 15.02V8.98L15.5 12z" /></svg></a>
|
||||||
|
</div>
|
||||||
|
<form class="footer-contact-form" id="footerContactForm" action="mailto:hello@odoo4projects.com" method="post" enctype="text/plain">
|
||||||
|
<label class="cmp-sr-only" for="footerContactEmail">Your email address</label>
|
||||||
|
<input type="email" id="footerContactEmail" name="email" placeholder="Your email address" required />
|
||||||
|
<div class="footer-textarea-wrap">
|
||||||
|
<label class="cmp-sr-only" for="footerContactText">Your message</label>
|
||||||
|
<textarea id="footerContactText" name="message" placeholder="Your message..." required></textarea>
|
||||||
|
<button type="submit" class="footer-send-btn" aria-label="Send message"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M2 21l21-9L2 3v7l15 2-15 2z" /></svg></button>
|
||||||
|
</div>
|
||||||
|
<div class="footer-form-status" id="footerFormStatus" role="status"></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fcopy">Copyright © ODOO4projects LLC</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>ODOO4projects - Support Chat</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
:root{
|
||||||
|
--odoo-purple: #875A7B;
|
||||||
|
--odoo-dark: #5a3d52;
|
||||||
|
--bg: #f6f7fb;
|
||||||
|
--card: #ffffff;
|
||||||
|
--muted: #7b7f87;
|
||||||
|
--accent: #6bbf59;
|
||||||
|
--radius: 14px;
|
||||||
|
font-family: 'Rubik', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
|
||||||
|
}
|
||||||
|
*{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}
|
||||||
|
|
||||||
|
/* 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}
|
||||||
|
.brand{display:flex;gap:12px;align-items:center}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 9px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 6px 18px rgba(135,90,123,0.12);
|
||||||
|
overflow: hidden; /* ensures image respects border radius */
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover; /* ensures the image fills the container */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.brand h1{margin:0;font-size:18px;color:var(--odoo-dark)}
|
||||||
|
.brand p{margin:0;font-size:12px;color:var(--muted)}
|
||||||
|
|
||||||
|
.sidebar .meta{margin-top:18px;font-size:13px;color:var(--muted)}
|
||||||
|
.sidebar .meta strong{color:var(--odoo-dark)}
|
||||||
|
|
||||||
|
.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-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-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}
|
||||||
|
.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}
|
||||||
|
|
||||||
|
.avatar{width:36px;height:36px;border-radius:10px;background:#eef1f6;display:flex;align-items:center;justify-content:center;color:var(--odoo-dark);font-weight:600}
|
||||||
|
|
||||||
|
.composer{padding:14px;border-top:1px solid #eef1f6;display:flex;gap:12px;align-items:center}
|
||||||
|
.input{flex:1;background:#f2f6fb;border-radius:12px;padding:8px 12px;display:flex;gap:8px;align-items:center}
|
||||||
|
.input input{border:0;background:transparent;outline:none;padding:10px;font-size:14px;width:100%}
|
||||||
|
.send{background:var(--odoo-purple);color:white;border:none;padding:10px 14px;border-radius:10px;font-weight:600;cursor:pointer;box-shadow:0 8px 18px rgba(135,90,123,0.14)}
|
||||||
|
.send[disabled]{opacity:0.5;cursor:default}
|
||||||
|
|
||||||
|
.small{font-size:12px;color:var(--muted)}
|
||||||
|
|
||||||
|
/* typing indicator */
|
||||||
|
.typing{display:flex;gap:6px;align-items:center;padding:6px 10px;border-radius:10px;background:#fff6fb;color:#6b3a55;width:max-content}
|
||||||
|
.dot{width:7px;height:7px;border-radius:50%;background:#d6a0c8;animation:blink 1.2s linear infinite}
|
||||||
|
.dot:nth-child(2){animation-delay:0.2s}
|
||||||
|
.dot:nth-child(3){animation-delay:0.4s}
|
||||||
|
@keyframes blink{0%{opacity:0.2}50%{opacity:1}100%{opacity:0.2}}
|
||||||
|
|
||||||
|
/* small screens */
|
||||||
|
@media (max-width:760px){
|
||||||
|
.app{grid-template-columns:1fr;}
|
||||||
|
.sidebar{display:none}
|
||||||
|
.chat-card{height:82vh}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="app">
|
||||||
|
<aside class="sidebar">
|
||||||
|
<div class="brand">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="/static/images/favicon.png" alt="ODOO4projects Logo" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1>Odoo Chat</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hint">
|
||||||
|
This chat is dedicated to support for ODOO4projects hosting services only.<br>
|
||||||
|
Please note: it does not cover general Odoo usage or functional questions.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div style="margin-top:18px; font-size:13px; color:var(--muted); line-height:1.5;">
|
||||||
|
<strong>Usage Tips:</strong>
|
||||||
|
<ul style="padding-left:20px; margin:8px 0; color:var(--muted);">
|
||||||
|
<li>
|
||||||
|
<strong>Operations Agent</strong><br>
|
||||||
|
Our agent can analyze the odoo and git log files for you. We are currently working on other tasks for him.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Support Ticket</strong><br>
|
||||||
|
Type <code>/ticket</code> to get in touch with our support team.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Feature Requests</strong><br>
|
||||||
|
Suggest a new feature for our services by leaving a comment in the chat using this format:<br>
|
||||||
|
<code>/feature: [Your description here]</code><br>
|
||||||
|
<em>Example:</em><br>
|
||||||
|
<code>/feature: Add an automatic backup notification email</code>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div style="margin-top:10px;">
|
||||||
|
⚠️ <strong>Important:</strong> If you cannot access Odoo due to a Git change, you can easily <a href="https://ODOO4projects.com" style="color:inherit; text-decoration:underline;">revert the last change via our homepage</a>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<main class="chat-card" role="main">
|
||||||
|
<div class="chat-header">
|
||||||
|
<div style="display:flex;flex-direction:column">
|
||||||
|
<div class="title">Chat with the ODOO4projects support</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="messages" id="messages" aria-live="polite">
|
||||||
|
<div class="messages-inner" id="messagesInner">
|
||||||
|
<!-- messages go here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="composer">
|
||||||
|
<div class="input" role="search">
|
||||||
|
<input id="messageInput" placeholder="Write a message..." aria-label="Message input" />
|
||||||
|
</div>
|
||||||
|
<button id="sendBtn" class="send">Send</button>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Configuration - use your webhook
|
||||||
|
const WEBHOOK = 'https://n8n.odoo4projects.com/webhook/960d7f0f-d0ef-42a5-a8f1-79db6a7d70bd/chat';
|
||||||
|
|
||||||
|
const messagesEl = document.getElementById('messagesInner');
|
||||||
|
const input = document.getElementById('messageInput');
|
||||||
|
const sendBtn = document.getElementById('sendBtn');
|
||||||
|
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const uuid = params.get("uuid");
|
||||||
|
|
||||||
|
// Generate UUID once per page load
|
||||||
|
function generateChatID(){
|
||||||
|
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||||
|
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const chatId = generateChatID();
|
||||||
|
|
||||||
|
function formatTime(date){
|
||||||
|
return date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendMessage(text, who='them'){
|
||||||
|
const wrap = document.createElement('div');
|
||||||
|
wrap.className = 'msg' + (who==='me' ? ' me' : '');
|
||||||
|
|
||||||
|
const avatar = document.createElement('div');
|
||||||
|
avatar.className = 'avatar';
|
||||||
|
avatar.textContent = who==='me' ? 'ME' : '4';
|
||||||
|
|
||||||
|
const bubble = document.createElement('div');
|
||||||
|
bubble.className = 'bubble' + (who==='me' ? ' me' : '');
|
||||||
|
bubble.innerHTML = text.replace(/\n/g,'<br>');
|
||||||
|
|
||||||
|
const meta = document.createElement('div');
|
||||||
|
meta.className = 'meta-time';
|
||||||
|
meta.textContent = formatTime(new Date());
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
messagesEl.appendChild(wrap);
|
||||||
|
messagesEl.parentElement.scrollTop = messagesEl.parentElement.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
let firstMessage = true;
|
||||||
|
|
||||||
|
async function sendMessage(){
|
||||||
|
let text = input.value.trim();
|
||||||
|
if(!text) return;
|
||||||
|
// show user message
|
||||||
|
|
||||||
|
if (firstMessage) {
|
||||||
|
text = `${uuid}: ${text}`;
|
||||||
|
firstMessage = false;
|
||||||
|
}
|
||||||
|
if(text.toLowerCase().startsWith('/ticket')){
|
||||||
|
text = `/ticket UUID:${uuid} chatId: ${chatId}`; // Add UUID after /ticket
|
||||||
|
}
|
||||||
|
appendMessage(text, 'me');
|
||||||
|
input.value = '';
|
||||||
|
sendBtn.disabled = true;
|
||||||
|
|
||||||
|
// show typing indicator
|
||||||
|
const typingEl = document.createElement('div');
|
||||||
|
typingEl.className = 'msg';
|
||||||
|
typingEl.id = 'typing';
|
||||||
|
typingEl.innerHTML = `
|
||||||
|
<div class="avatar">4</div>
|
||||||
|
<div class="typing" style="margin-left:6px"><div class="dot"></div><div class="dot"></div><div class="dot"></div></div>
|
||||||
|
`;
|
||||||
|
messagesEl.appendChild(typingEl);
|
||||||
|
messagesEl.parentElement.scrollTop = messagesEl.parentElement.scrollHeight;
|
||||||
|
|
||||||
|
try{
|
||||||
|
// Post to webhook - expecting a JSON response. Adapt to your backend.
|
||||||
|
const payload = {text: text, uuid: uuid, chatid: chatId};
|
||||||
|
const res = await fetch(WEBHOOK, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
|
||||||
|
let data;
|
||||||
|
const ct = res.headers.get('content-type') || '';
|
||||||
|
if(ct.includes('application/json')) data = await res.json();
|
||||||
|
else data = {text: await res.text()};
|
||||||
|
|
||||||
|
// remove typing indicator
|
||||||
|
const t = document.getElementById('typing');
|
||||||
|
if(t) t.remove();
|
||||||
|
|
||||||
|
// Decide where message text is
|
||||||
|
// Common patterns: {message: '...'}, {text: '...'}, {reply: '...'}, plain text
|
||||||
|
let replyText = '';
|
||||||
|
if(typeof data === 'string') replyText = data;
|
||||||
|
else if(data === null) replyText = 'No response';
|
||||||
|
else if(data.reply) replyText = data.reply;
|
||||||
|
else if(data.message) replyText = data.message;
|
||||||
|
else if(data.text) replyText = data.text;
|
||||||
|
else if(data.output) replyText = data.output;
|
||||||
|
else replyText = JSON.stringify(data);
|
||||||
|
|
||||||
|
appendMessage(replyText, 'them');
|
||||||
|
|
||||||
|
}catch(err){
|
||||||
|
const t = document.getElementById('typing');
|
||||||
|
if(t) t.remove();
|
||||||
|
appendMessage('Error: ' + (err && err.message ? err.message : String(err)), 'them');
|
||||||
|
} finally {
|
||||||
|
sendBtn.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wire events
|
||||||
|
sendBtn.addEventListener('click', sendMessage);
|
||||||
|
input.addEventListener('keydown', (e)=>{ if(e.key === 'Enter' && !e.shiftKey){ e.preventDefault(); sendMessage(); } });
|
||||||
|
|
||||||
|
// friendly welcome
|
||||||
|
appendMessage('I am here to help with all your hosting-related questions.Type /ticket to contact our support team directly. Your UUID is '+uuid, 'them');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,490 @@
|
|||||||
|
<!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://n8n.odoo4projects.com/webhook/ODOO4projects/upsell";
|
||||||
|
|
||||||
|
// ── 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 || "–";
|
||||||
|
|
||||||
|
// ── Product ID mapping ─────────────────────────────────────────
|
||||||
|
const PRODUCT_IDS = {
|
||||||
|
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) {
|
||||||
|
alert("Missing uuid parameter in URL.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var pid = PRODUCT_IDS[productId];
|
||||||
|
if (!pid) {
|
||||||
|
alert("Unknown product.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var form = document.createElement("form");
|
||||||
|
form.method = "POST";
|
||||||
|
form.action = "https://20.odoo4projects.com/shop/post_basket";
|
||||||
|
form.target = "_blank";
|
||||||
|
form.style.display = "none";
|
||||||
|
var basket = document.createElement("input");
|
||||||
|
basket.type = "hidden";
|
||||||
|
basket.name = "basket";
|
||||||
|
var item = { product_id: pid, qty: 1, info: uuid };
|
||||||
|
basket.value = JSON.stringify([item]);
|
||||||
|
form.appendChild(basket);
|
||||||
|
var clear = document.createElement("input");
|
||||||
|
clear.type = "hidden";
|
||||||
|
clear.name = "clear";
|
||||||
|
clear.value = "1";
|
||||||
|
form.appendChild(clear);
|
||||||
|
appendUTM(form);
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
document.body.removeChild(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 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 " + 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" }
|
||||||
|
// (tolerate an array wrapper and snake_case keys as well)
|
||||||
|
const record = Array.isArray(payload)
|
||||||
|
? payload[0]
|
||||||
|
: payload;
|
||||||
|
const contractName =
|
||||||
|
record && (record.contractName || record.contract_name);
|
||||||
|
if (contractName) {
|
||||||
|
applyPlanState(contractName, record.expires);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Could not load contract data:", err);
|
||||||
|
// Graceful degradation: page remains usable with default button states
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadContract();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -6,6 +6,121 @@ var si = 0,
|
|||||||
autoStop = false,
|
autoStop = false,
|
||||||
autoInterval = 7000;
|
autoInterval = 7000;
|
||||||
|
|
||||||
|
/* ---- UTM tracking helpers ---- */
|
||||||
|
(function () {
|
||||||
|
function getCookie(name) {
|
||||||
|
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
|
||||||
|
return match ? decodeURIComponent(match[2]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCookie(name, value, days) {
|
||||||
|
var expires = '';
|
||||||
|
if (days) {
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||||
|
expires = '; expires=' + date.toUTCString();
|
||||||
|
}
|
||||||
|
document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=/; SameSite=Lax';
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseUTM() {
|
||||||
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
|
var utm = {};
|
||||||
|
var keys = ['source', 'medium', 'campaign'];
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
var val = urlParams.get('utm_' + keys[i]);
|
||||||
|
if (val) {
|
||||||
|
utm[keys[i]] = val;
|
||||||
|
setCookie('utm_' + keys[i], val, 90);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return utm;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStoredUTM() {
|
||||||
|
var utm = {};
|
||||||
|
var keys = ['source', 'medium', 'campaign'];
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
var val = getCookie('utm_' + keys[i]);
|
||||||
|
if (val) utm[keys[i]] = val;
|
||||||
|
}
|
||||||
|
return utm;
|
||||||
|
}
|
||||||
|
|
||||||
|
function injectUTM(data) {
|
||||||
|
var stored = getStoredUTM();
|
||||||
|
if (Object.keys(stored).length > 0) {
|
||||||
|
data.utm_source = stored.source || null;
|
||||||
|
data.utm_medium = stored.medium || null;
|
||||||
|
data.utm_campaign = stored.campaign || null;
|
||||||
|
}
|
||||||
|
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(); // Parse on page load
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ---- Spinning Up Widget (shown when ?message=spinning_up) ---- */
|
||||||
|
(function () {
|
||||||
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
|
if (urlParams.get('message') === 'spinning_up') {
|
||||||
|
var el = document.getElementById('spinningUp');
|
||||||
|
if (el) el.style.display = 'block';
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ---- 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) {
|
function show(i, direction) {
|
||||||
if (direction === undefined) return;
|
if (direction === undefined) return;
|
||||||
var current = slides[si];
|
var current = slides[si];
|
||||||
@@ -67,20 +182,6 @@ var si = 0,
|
|||||||
t = setInterval(nextSlide, autoInterval);
|
t = setInterval(nextSlide, autoInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function () {
|
|
||||||
var o = document.getElementById("spinner");
|
|
||||||
o.classList.add("hidden");
|
|
||||||
setTimeout(function () {
|
|
||||||
o.style.display = "none";
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
setTimeout(function () {
|
|
||||||
var o = document.getElementById("spinner");
|
|
||||||
o.classList.add("hidden");
|
|
||||||
setTimeout(function () {
|
|
||||||
o.style.display = "none";
|
|
||||||
}, 500);
|
|
||||||
}, 3000);
|
|
||||||
t = setInterval(nextSlide, autoInterval);
|
t = setInterval(nextSlide, autoInterval);
|
||||||
|
|
||||||
for (var s = 0; s < slides.length; s++) {
|
for (var s = 0; s < slides.length; s++) {
|
||||||
@@ -90,22 +191,23 @@ var si = 0,
|
|||||||
t = null;
|
t = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(function () {
|
/* spinner guard */
|
||||||
var blogSection = document.getElementById("blog");
|
(function() {
|
||||||
if (blogSection) {
|
var sp = document.getElementById("spinner");
|
||||||
function onBlogScroll() {
|
if (!sp) return;
|
||||||
var rect = blogSection.getBoundingClientRect();
|
sp.classList.add("hidden");
|
||||||
if (rect.top < window.innerHeight && rect.bottom > 0) {
|
setTimeout(function() { sp.style.display = "none"; }, 500);
|
||||||
openTrialWidget();
|
setTimeout(function() {
|
||||||
window.removeEventListener("scroll", onBlogScroll);
|
if (document.getElementById("spinner")) {
|
||||||
}
|
document.getElementById("spinner").classList.add("hidden");
|
||||||
|
document.getElementById("spinner").style.display = "none";
|
||||||
}
|
}
|
||||||
window.addEventListener("scroll", onBlogScroll);
|
}, 3000);
|
||||||
}
|
})();
|
||||||
}, 3000);
|
|
||||||
|
|
||||||
document.querySelectorAll(".tab-btn").forEach(function (b) {
|
document.querySelectorAll(".tab-btn").forEach(function (b) {
|
||||||
b.addEventListener("click", function () {
|
b.addEventListener("click", function () {
|
||||||
document.querySelectorAll(".tab-btn").forEach(function (x) {
|
document.querySelectorAll(".tab-btn").forEach(function (x) {
|
||||||
x.classList.remove("active");
|
x.classList.remove("active");
|
||||||
@@ -126,65 +228,51 @@ var si = 0,
|
|||||||
var orderPopupShown = false;
|
var orderPopupShown = false;
|
||||||
function openOrderWidget(
|
function openOrderWidget(
|
||||||
plan,
|
plan,
|
||||||
monthlyPrice,
|
|
||||||
yearlyPrice,
|
yearlyPrice,
|
||||||
isEmpire,
|
isEmpire,
|
||||||
) {
|
) {
|
||||||
document.getElementById("orderPanelTrial").style.display =
|
|
||||||
"none";
|
|
||||||
document.getElementById("orderPanelBuy").style.display =
|
document.getElementById("orderPanelBuy").style.display =
|
||||||
"block";
|
"block";
|
||||||
var widget = document.getElementById("orderWidgetOverlay");
|
var widget = document.getElementById("orderWidgetOverlay");
|
||||||
document.getElementById("orderPlanTitle").textContent = plan;
|
document.getElementById("orderPlanTitle").textContent = plan;
|
||||||
var yearly = yearlyMode;
|
var price = yearlyPrice;
|
||||||
var price = yearly ? yearlyPrice : monthlyPrice;
|
|
||||||
var amountEl = document.getElementById("orderPlanPrice");
|
var amountEl = document.getElementById("orderPlanPrice");
|
||||||
var prefix = isEmpire ? ">$" : "$";
|
var prefix = isEmpire ? ">" : "";
|
||||||
amountEl.textContent = prefix + " " + price.toFixed(2);
|
amountEl.textContent = prefix + "$ " + price.toFixed(2);
|
||||||
document.getElementById("orderPlanPeriod").textContent = yearly
|
document.getElementById("orderPlanPeriod").textContent = "/ year";
|
||||||
? "/ year"
|
|
||||||
: "/ month";
|
|
||||||
var couponMsg = document.getElementById("orderCouponMsg");
|
var couponMsg = document.getElementById("orderCouponMsg");
|
||||||
var yearlySave = document.getElementById("orderYearlySave");
|
var yearlySave = document.getElementById("orderYearlySave");
|
||||||
if (!yearly) {
|
couponMsg.style.display = "none";
|
||||||
couponMsg.style.display = "block";
|
yearlySave.style.display = "block";
|
||||||
yearlySave.style.display = "none";
|
|
||||||
} else {
|
|
||||||
couponMsg.style.display = "none";
|
|
||||||
yearlySave.style.display = "block";
|
|
||||||
var saved = Math.round(
|
|
||||||
(1 - yearlyPrice / (monthlyPrice * 12)) * 100,
|
|
||||||
);
|
|
||||||
document.getElementById("orderSavePercent").textContent =
|
|
||||||
saved;
|
|
||||||
}
|
|
||||||
var buyBtn = document.getElementById("orderBuyBtn");
|
var buyBtn = document.getElementById("orderBuyBtn");
|
||||||
var loc = document.getElementById("orderServerLocation").value;
|
var loc = document.getElementById("orderServerLocation").value;
|
||||||
|
var utmQuery = UTM.toQuery();
|
||||||
buyBtn.href =
|
buyBtn.href =
|
||||||
"/3/" +
|
"/3/" +
|
||||||
price.toFixed(2) +
|
price.toFixed(2) +
|
||||||
"/4/" +
|
"/4/" +
|
||||||
encodeURIComponent(plan) +
|
encodeURIComponent(plan) +
|
||||||
"?location=" +
|
"?location=" +
|
||||||
encodeURIComponent(loc);
|
encodeURIComponent(loc) +
|
||||||
|
(utmQuery ? "&" + utmQuery : "");
|
||||||
widget.style.display = "flex";
|
widget.style.display = "flex";
|
||||||
orderPopupShown = true;
|
orderPopupShown = true;
|
||||||
}
|
}
|
||||||
function openTrialWidget() {
|
|
||||||
document.getElementById("orderPanelBuy").style.display = "none";
|
|
||||||
document.getElementById("orderPanelTrial").style.display =
|
|
||||||
"block";
|
|
||||||
document.getElementById("orderWidgetOverlay").style.display =
|
|
||||||
"flex";
|
|
||||||
orderPopupShown = true;
|
|
||||||
}
|
|
||||||
function switchToBuyPanel() {
|
|
||||||
openOrderWidget("On the Rise", 36.21, 395.0, false);
|
|
||||||
}
|
|
||||||
function closeOrderWidget() {
|
function closeOrderWidget() {
|
||||||
document.getElementById("orderWidgetOverlay").style.display =
|
document.getElementById("orderWidgetOverlay").style.display =
|
||||||
"none";
|
"none";
|
||||||
}
|
}
|
||||||
|
// Escape key closes the order widget
|
||||||
|
document.addEventListener("keydown", function (e) {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
var widget = document.getElementById(
|
||||||
|
"orderWidgetOverlay",
|
||||||
|
);
|
||||||
|
if (widget && widget.style.display === "flex") {
|
||||||
|
closeOrderWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
document
|
document
|
||||||
.getElementById("orderServerLocation")
|
.getElementById("orderServerLocation")
|
||||||
.addEventListener("change", function () {
|
.addEventListener("change", function () {
|
||||||
@@ -197,13 +285,15 @@ var si = 0,
|
|||||||
.trim();
|
.trim();
|
||||||
var price = parseFloat(priceText);
|
var price = parseFloat(priceText);
|
||||||
var loc = this.value;
|
var loc = this.value;
|
||||||
|
var utmQuery = UTM.toQuery();
|
||||||
document.getElementById("orderBuyBtn").href =
|
document.getElementById("orderBuyBtn").href =
|
||||||
"/3/" +
|
"/3/" +
|
||||||
price.toFixed(2) +
|
price.toFixed(2) +
|
||||||
"/4/" +
|
"/4/" +
|
||||||
encodeURIComponent(plan) +
|
encodeURIComponent(plan) +
|
||||||
"?location=" +
|
"?location=" +
|
||||||
encodeURIComponent(loc);
|
encodeURIComponent(loc) +
|
||||||
|
(utmQuery ? "&" + utmQuery : "");
|
||||||
});
|
});
|
||||||
function applyCoupon() {
|
function applyCoupon() {
|
||||||
var input = document.getElementById("orderCouponInput");
|
var input = document.getElementById("orderCouponInput");
|
||||||
@@ -212,75 +302,13 @@ var si = 0,
|
|||||||
if (code.toLowerCase() === "free trial") {
|
if (code.toLowerCase() === "free trial") {
|
||||||
status.textContent =
|
status.textContent =
|
||||||
"\u2713 Coupon FREE TRIAL applied - 1 month free";
|
"\u2713 Coupon FREE TRIAL applied - 1 month free";
|
||||||
status.style.color = "#28a745";
|
status.style.color = "#1a7f37";
|
||||||
} else {
|
} else {
|
||||||
status.textContent = "Invalid coupon code";
|
status.textContent = "Invalid coupon code";
|
||||||
status.style.color = "#dc3545";
|
status.style.color = "#dc3545";
|
||||||
}
|
}
|
||||||
status.style.display = "block";
|
status.style.display = "block";
|
||||||
}
|
}
|
||||||
/* ---- Billing Toggle ---- */
|
|
||||||
var yearlyMode = false;
|
|
||||||
var biSwitch = document.getElementById("billingSwitch");
|
|
||||||
var labels = document.querySelectorAll(".toggle-label");
|
|
||||||
var monthlyLabel = document.querySelector(".toggle-label-monthly");
|
|
||||||
var yearlyLabel = document.querySelector(".toggle-label-yearly");
|
|
||||||
|
|
||||||
function updatePrices(yearly) {
|
|
||||||
var amounts = document.querySelectorAll(".price-amount");
|
|
||||||
for (var k = 0; k < amounts.length; k++) {
|
|
||||||
var el = amounts[k];
|
|
||||||
var val = yearly
|
|
||||||
? el.getAttribute("data-yearly")
|
|
||||||
: el.getAttribute("data-monthly");
|
|
||||||
var prefix =
|
|
||||||
el.textContent.trim().charAt(0) === ">" ? ">" : "";
|
|
||||||
el.textContent = prefix + "$ " + parseFloat(val).toFixed(2);
|
|
||||||
}
|
|
||||||
var periods = document.querySelectorAll(".price-period");
|
|
||||||
for (var k = 0; k < periods.length; k++) {
|
|
||||||
periods[k].textContent = yearly ? "/ year" : "/ month";
|
|
||||||
}
|
|
||||||
var saves = document.querySelectorAll(".price-save");
|
|
||||||
for (var k = 0; k < saves.length; k++) {
|
|
||||||
var s = saves[k];
|
|
||||||
if (yearly) {
|
|
||||||
s.style.display = "block";
|
|
||||||
s.textContent = s.getAttribute("data-yearly-text");
|
|
||||||
} else {
|
|
||||||
s.style.display = "block";
|
|
||||||
s.textContent = s.getAttribute("data-monthly-text");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setBilling(yearly) {
|
|
||||||
yearlyMode = yearly;
|
|
||||||
if (yearly) {
|
|
||||||
biSwitch.classList.add("yearly");
|
|
||||||
monthlyLabel.classList.remove("active");
|
|
||||||
yearlyLabel.classList.add("active");
|
|
||||||
} else {
|
|
||||||
biSwitch.classList.remove("yearly");
|
|
||||||
monthlyLabel.classList.add("active");
|
|
||||||
yearlyLabel.classList.remove("active");
|
|
||||||
}
|
|
||||||
updatePrices(yearly);
|
|
||||||
}
|
|
||||||
|
|
||||||
biSwitch.addEventListener("click", function () {
|
|
||||||
setBilling(!yearlyMode);
|
|
||||||
});
|
|
||||||
monthlyLabel.addEventListener("click", function () {
|
|
||||||
setBilling(false);
|
|
||||||
});
|
|
||||||
yearlyLabel.addEventListener("click", function () {
|
|
||||||
setBilling(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
/* init billing display to monthly */
|
|
||||||
updatePrices(false);
|
|
||||||
|
|
||||||
/* ---- Blog Module ---- */
|
/* ---- Blog Module ---- */
|
||||||
var blogState = {
|
var blogState = {
|
||||||
allPosts: [],
|
allPosts: [],
|
||||||
@@ -397,38 +425,24 @@ var si = 0,
|
|||||||
var pag = document.getElementById("blogPagination");
|
var pag = document.getElementById("blogPagination");
|
||||||
var pagHtml = "";
|
var pagHtml = "";
|
||||||
if (totalPages > 1) {
|
if (totalPages > 1) {
|
||||||
pagHtml +=
|
var prevPage = blogState.currentPage > 1 ? blogState.currentPage - 1 : null;
|
||||||
'<button class="blog-page-btn" onclick="blogGo(1)"' +
|
var nextPage = blogState.currentPage < totalPages ? blogState.currentPage + 1 : null;
|
||||||
(blogState.currentPage <= 1 ? ' disabled"' : '"') +
|
var isFirst = blogState.currentPage <= 1;
|
||||||
">«</button>";
|
var isLast = blogState.currentPage >= totalPages;
|
||||||
pagHtml +=
|
|
||||||
'<button class="blog-page-btn" onclick="blogGo(' +
|
pagHtml += '<a class="blog-page-btn' + (isFirst ? ' blog-page-btn-disabled' : '') + '" href="?page=1"' + (isFirst ? ' aria-disabled="true"' : ' aria-label="Go to first page"') + '>«</a>';
|
||||||
(blogState.currentPage - 1) +
|
if (prevPage) {
|
||||||
')"' +
|
pagHtml += '<a class="blog-page-btn" href="?page=' + prevPage + '" rel="prev" aria-label="Go to previous page">‹ Prev</a>';
|
||||||
(blogState.currentPage <= 1 ? ' disabled"' : '"') +
|
} else {
|
||||||
">‹ Prev</button>";
|
pagHtml += '<span class="blog-page-btn-disabled">‹ Prev</span>';
|
||||||
pagHtml +=
|
}
|
||||||
'<span class="blog-page-info">Page ' +
|
pagHtml += '<span class="blog-page-info" aria-live="polite">Page ' + blogState.currentPage + " of " + totalPages + "</span>";
|
||||||
blogState.currentPage +
|
if (nextPage) {
|
||||||
" of " +
|
pagHtml += '<a class="blog-page-btn" href="?page=' + nextPage + '" rel="next" aria-label="Go to next page">Next ›</a>';
|
||||||
totalPages +
|
} else {
|
||||||
"</span>";
|
pagHtml += '<span class="blog-page-btn-disabled">Next ›</span>';
|
||||||
pagHtml +=
|
}
|
||||||
'<button class="blog-page-btn" onclick="blogGo(' +
|
pagHtml += '<a class="blog-page-btn' + (isLast ? ' blog-page-btn-disabled' : '') + '" href="?page=' + totalPages + '"' + (isLast ? ' aria-disabled="true"' : ' aria-label="Go to last page"') + '>»</a>';
|
||||||
(blogState.currentPage + 1) +
|
|
||||||
')"' +
|
|
||||||
(blogState.currentPage >= totalPages
|
|
||||||
? ' disabled"'
|
|
||||||
: '"') +
|
|
||||||
">Next ›</button>";
|
|
||||||
pagHtml +=
|
|
||||||
'<button class="blog-page-btn" onclick="blogGo(' +
|
|
||||||
totalPages +
|
|
||||||
')"' +
|
|
||||||
(blogState.currentPage >= totalPages
|
|
||||||
? ' disabled"'
|
|
||||||
: '"') +
|
|
||||||
">»</button>";
|
|
||||||
}
|
}
|
||||||
pag.innerHTML = pagHtml;
|
pag.innerHTML = pagHtml;
|
||||||
}
|
}
|
||||||
@@ -438,6 +452,197 @@ var si = 0,
|
|||||||
renderBlog();
|
renderBlog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- Silent ping for hero carousel ---- */
|
||||||
|
(function() {
|
||||||
|
var SERVERS = [
|
||||||
|
{ host: 'api.meppel.odoo4projects.com', city: 'Amsterdam' },
|
||||||
|
{ host: 'api.boston.odoo4projects.com', city: 'Boston' },
|
||||||
|
{ host: 'api.manchester.odoo4projects.com', city: 'Manchester' },
|
||||||
|
{ host: 'api.mumbai.odoo4projects.com', city: 'Mumbai' },
|
||||||
|
{ host: 'api.saopaulo.odoo4projects.com', city: 'S\u00e3o Paulo' },
|
||||||
|
{ host: 'api.sydney.odoo4projects.com', city: 'Sydney' }
|
||||||
|
];
|
||||||
|
var heroImages = {
|
||||||
|
'api.meppel.odoo4projects.com': 'images/hero/amsterdam.webp',
|
||||||
|
'api.boston.odoo4projects.com': 'images/hero/boston.webp',
|
||||||
|
'api.manchester.odoo4projects.com': 'images/hero/london.webp',
|
||||||
|
'api.mumbai.odoo4projects.com': 'images/hero/mumbai.webp',
|
||||||
|
'api.saopaulo.odoo4projects.com': 'images/hero/brazil.webp',
|
||||||
|
'api.sydney.odoo4projects.com': 'images/hero/sydney.webp'
|
||||||
|
};
|
||||||
|
|
||||||
|
function pingServer(host) {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
var start = performance.now();
|
||||||
|
var img = new Image();
|
||||||
|
var timedOut = false;
|
||||||
|
var timer = setTimeout(function() {
|
||||||
|
timedOut = true; img.src = '';
|
||||||
|
resolve({ host: host, time: -1 });
|
||||||
|
}, 2000);
|
||||||
|
img.onload = function() {
|
||||||
|
var elapsed = performance.now() - start;
|
||||||
|
if (!timedOut) { clearTimeout(timer); resolve({ host: host, time: elapsed }); }
|
||||||
|
};
|
||||||
|
img.onerror = function() {
|
||||||
|
var elapsed = performance.now() - start;
|
||||||
|
if (!timedOut) { clearTimeout(timer); resolve({ host: host, time: elapsed }); }
|
||||||
|
};
|
||||||
|
img.src = 'https://' + host + '/favicon.ico?_=' + Date.now() + '_' + Math.random().toString(36).slice(2,6);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Click on a server card — slide its city into hero, no label */
|
||||||
|
var serverCards = document.querySelectorAll('.server-card');
|
||||||
|
serverCards.forEach(function(card, idx) {
|
||||||
|
card.addEventListener('click', function() {
|
||||||
|
var s = SERVERS[idx];
|
||||||
|
if (!s || !heroImages[s.host]) return;
|
||||||
|
/* Move golden frame */
|
||||||
|
serverCards.forEach(function(c) { c.classList.remove('server-best'); });
|
||||||
|
card.classList.add('server-best');
|
||||||
|
/* Slide hero bg without label */
|
||||||
|
animateHero(null, heroImages[s.host], false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function animateHero(city, image, showLabel) {
|
||||||
|
var hero = document.querySelector('.hero');
|
||||||
|
if (!hero) return;
|
||||||
|
var bg = hero.querySelector('.hero-bg');
|
||||||
|
if (!bg) {
|
||||||
|
bg = document.createElement('div');
|
||||||
|
bg.className = 'hero-bg';
|
||||||
|
hero.insertBefore(bg, hero.firstChild);
|
||||||
|
}
|
||||||
|
var hasExisting = bg.children.length > 0;
|
||||||
|
var newEl = document.createElement('div');
|
||||||
|
newEl.className = 'hero-bg-slide';
|
||||||
|
newEl.style.backgroundImage = "url('" + image + "')";
|
||||||
|
bg.appendChild(newEl);
|
||||||
|
|
||||||
|
var tl = gsap.timeline();
|
||||||
|
gsap.set(newEl, { x: '100%' });
|
||||||
|
|
||||||
|
var label = null;
|
||||||
|
if (showLabel !== false && city) {
|
||||||
|
label = document.createElement('div');
|
||||||
|
label.className = 'hero-city-label';
|
||||||
|
label.innerHTML = 'Our <strong>' + city + '</strong> server fits your location';
|
||||||
|
hero.appendChild(label);
|
||||||
|
gsap.set(label, { x: '150%' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasExisting) {
|
||||||
|
var oldEl = bg.children[0];
|
||||||
|
gsap.set(oldEl, { x: '0%' });
|
||||||
|
tl.to(oldEl, { x: '100%', duration: 3, ease: 'power2.out' }, 0)
|
||||||
|
.to(newEl, { x: '0%', duration: 3, ease: 'power2.out' }, 0);
|
||||||
|
if (label) {
|
||||||
|
tl.to(label, { x: '0%', duration: 2.5, ease: 'power2.out' }, 0.3);
|
||||||
|
}
|
||||||
|
tl.call(function() { oldEl.remove(); });
|
||||||
|
} else {
|
||||||
|
tl.to(newEl, { x: '0%', duration: 3, ease: 'power2.out' }, 0);
|
||||||
|
if (label) {
|
||||||
|
tl.to(label, { x: '0%', duration: 2.5, ease: 'power2.out' }, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ping all servers, pick best, animate hero */
|
||||||
|
var results = [];
|
||||||
|
var pending = SERVERS.length;
|
||||||
|
|
||||||
|
/* Populate trial form AND pricing server location dropdowns */
|
||||||
|
var trialLoc = document.getElementById('trialLocation');
|
||||||
|
var pricingLoc = document.getElementById('pricingServerLocation');
|
||||||
|
[trialLoc, pricingLoc].forEach(function(el) {
|
||||||
|
if (el) {
|
||||||
|
SERVERS.forEach(function(s) {
|
||||||
|
var opt = document.createElement('option');
|
||||||
|
// Extract city from host: api.saopaulo.odoo4projects.com -> saopaulo
|
||||||
|
var cityVal = s.host.replace('api.', '').replace('.odoo4projects.com', '');
|
||||||
|
opt.value = cityVal;
|
||||||
|
opt.textContent = s.city;
|
||||||
|
el.appendChild(opt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SERVERS.forEach(function(s) {
|
||||||
|
pingServer(s.host).then(function(r) {
|
||||||
|
results.push(r);
|
||||||
|
pending--;
|
||||||
|
if (pending === 0) {
|
||||||
|
var valid = results.filter(function(x) { return x.time >= 0; });
|
||||||
|
if (valid.length === 0) return;
|
||||||
|
valid.sort(function(a, b) { return a.time - b.time; });
|
||||||
|
var best = valid[0];
|
||||||
|
var bestServer = SERVERS.filter(function(s) { return s.host === best.host; })[0];
|
||||||
|
/* Preselect best server in trial and pricing forms */
|
||||||
|
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) {
|
||||||
|
el.selectedIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (bestServer && heroImages[best.host]) {
|
||||||
|
/* Highlight the matching server card */
|
||||||
|
var cards = document.querySelectorAll('.server-card');
|
||||||
|
for (var i = 0; i < SERVERS.length && i < cards.length; i++) {
|
||||||
|
if (SERVERS[i].host === best.host) {
|
||||||
|
cards[i].classList.add('server-best');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Preload and animate hero */
|
||||||
|
var img = new Image();
|
||||||
|
img.onload = function() { animateHero(bestServer.city, heroImages[best.host]); };
|
||||||
|
img.src = heroImages[best.host];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Trial form submission */
|
||||||
|
var trialForm = document.getElementById('trialForm');
|
||||||
|
if (trialForm) {
|
||||||
|
trialForm.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var email = document.getElementById('trialEmail').value.trim();
|
||||||
|
var location = trialLoc.value;
|
||||||
|
if (!email) return;
|
||||||
|
var btn = trialForm.querySelector('.btn-brass');
|
||||||
|
btn.textContent = 'Sending...';
|
||||||
|
btn.disabled = true;
|
||||||
|
fetch('https://n8n.odoo4projects.com/webhook/ODOO4projects/trial', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(UTM.inject({ email: email, location: location }))
|
||||||
|
}).then(function() {
|
||||||
|
trialForm.style.display = 'none';
|
||||||
|
document.getElementById('trialSuccess').classList.add('visible');
|
||||||
|
}).catch(function() {
|
||||||
|
btn.textContent = 'Send';
|
||||||
|
btn.disabled = false;
|
||||||
|
var errorMsg = document.createElement('div');
|
||||||
|
errorMsg.className = 'trial-error visible';
|
||||||
|
errorMsg.textContent = 'Something went wrong. Please try again.';
|
||||||
|
trialForm.appendChild(errorMsg);
|
||||||
|
setTimeout(function() { errorMsg.classList.remove('visible'); }, 3000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
fetch("blog/index.json?_=" + Date.now())
|
fetch("blog/index.json?_=" + Date.now())
|
||||||
.then(function (r) {
|
.then(function (r) {
|
||||||
return r.json();
|
return r.json();
|
||||||
@@ -458,3 +663,311 @@ var si = 0,
|
|||||||
blogState.currentPage = 1;
|
blogState.currentPage = 1;
|
||||||
renderBlog();
|
renderBlog();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* ---- Scroll-triggered section animations ---- */
|
||||||
|
(function () {
|
||||||
|
var animated = {};
|
||||||
|
var observer = new IntersectionObserver(function (entries) {
|
||||||
|
entries.forEach(function (entry) {
|
||||||
|
if (!entry.isIntersecting) return;
|
||||||
|
var grid = entry.target;
|
||||||
|
if (!grid || !grid.children || grid.children.length === 0) return;
|
||||||
|
var key = grid.className || 'anon';
|
||||||
|
if (animated[key]) return;
|
||||||
|
animated[key] = true;
|
||||||
|
gsap.fromTo(
|
||||||
|
grid.children,
|
||||||
|
{ y: 30, opacity: 0 },
|
||||||
|
{
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
duration: 0.7,
|
||||||
|
ease: 'power2.out',
|
||||||
|
stagger: 0.08,
|
||||||
|
overwrite: 'auto'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, { threshold: 0.1 });
|
||||||
|
|
||||||
|
var grids = document.querySelectorAll(
|
||||||
|
'.features-grid, .faq-grid, .pricing-grid, .blog-grid, .biz-wizard .container'
|
||||||
|
);
|
||||||
|
grids.forEach(function (g) {
|
||||||
|
/* Pre-set children invisible so no flash even before observer fires */
|
||||||
|
if (g.children.length > 0) {
|
||||||
|
gsap.set(g.children, { y: 30, opacity: 0 });
|
||||||
|
}
|
||||||
|
observer.observe(g);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* ---- Business Wizard Form ---- */
|
||||||
|
(function () {
|
||||||
|
var form = document.getElementById('bizForm');
|
||||||
|
if (!form) return;
|
||||||
|
var success = document.getElementById('bizSuccess');
|
||||||
|
var submitBtn = document.getElementById('bizSubmitBtn');
|
||||||
|
|
||||||
|
form.addEventListener('submit', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var description = document.getElementById('bizDescription').value.trim();
|
||||||
|
var goals = document.getElementById('bizGoals').value.trim();
|
||||||
|
var challenges = document.getElementById('bizChallenges').value.trim();
|
||||||
|
if (!description || !goals || !challenges) return;
|
||||||
|
|
||||||
|
var email = document.getElementById('bizEmail').value.trim();
|
||||||
|
if (!email) return;
|
||||||
|
|
||||||
|
var hasHomepage = document.getElementById('bizHasHomepage').checked;
|
||||||
|
var usesOdoo = document.getElementById('bizUsesOdoo').checked;
|
||||||
|
var hasDeveloper = document.getElementById('bizHasDeveloper').checked;
|
||||||
|
|
||||||
|
submitBtn.textContent = 'Generating...';
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
|
||||||
|
/* POST silently to webhook — the report will be emailed */
|
||||||
|
fetch('https://n8n.odoo4projects.com/webhook/bring-your-business', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(UTM.inject({
|
||||||
|
email: email,
|
||||||
|
description: description,
|
||||||
|
goals: goals,
|
||||||
|
challenges: challenges,
|
||||||
|
has_homepage: hasHomepage,
|
||||||
|
uses_odoo: usesOdoo,
|
||||||
|
has_developer: hasDeveloper
|
||||||
|
}))
|
||||||
|
}).catch(function () { /* ignore */ });
|
||||||
|
|
||||||
|
/* Show success message — we'll email the report */
|
||||||
|
form.style.display = 'none';
|
||||||
|
success.style.display = 'block';
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
/* Buy Now — POST basket via form with server location, opens checkout in new tab */
|
||||||
|
window.buyNow = function (productId) {
|
||||||
|
var locSelect = document.getElementById('pricingServerLocation');
|
||||||
|
var location = locSelect ? locSelect.value : '';
|
||||||
|
var verSelect = document.getElementById('pricingOdooVersion');
|
||||||
|
var version = verSelect ? verSelect.value : '';
|
||||||
|
var form = document.createElement('form');
|
||||||
|
form.method = 'POST';
|
||||||
|
form.action = 'https://20.odoo4projects.com/shop/post_basket';
|
||||||
|
form.target = '_blank';
|
||||||
|
form.style.display = 'none';
|
||||||
|
var basket = document.createElement('input');
|
||||||
|
basket.type = 'hidden';
|
||||||
|
basket.name = 'basket';
|
||||||
|
var item = { product_id: productId, qty: 1 };
|
||||||
|
var info = location ? location.replace('.odoo4projects.com', '') : '';
|
||||||
|
if (version) { info += (info ? '|' : '') + version; }
|
||||||
|
if (info) { item.info = info; }
|
||||||
|
basket.value = JSON.stringify([item]);
|
||||||
|
console.log('Buy basket:', basket.value);
|
||||||
|
form.appendChild(basket);
|
||||||
|
var clear = document.createElement('input');
|
||||||
|
clear.type = 'hidden';
|
||||||
|
clear.name = 'clear';
|
||||||
|
clear.value = '1';
|
||||||
|
form.appendChild(clear);
|
||||||
|
UTM.appendToForm(form);
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
document.body.removeChild(form);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---- OCA Modules Status ---- */
|
||||||
|
(function () {
|
||||||
|
var tbody = document.getElementById('ocaTbody');
|
||||||
|
var searchInput = document.getElementById('ocaSearch');
|
||||||
|
var empty = document.getElementById('ocaEmpty');
|
||||||
|
var loading = document.getElementById('ocaLoading');
|
||||||
|
var allModules = [];
|
||||||
|
|
||||||
|
function render(filter) {
|
||||||
|
var q = (filter || '').toLowerCase();
|
||||||
|
var matched = q ? allModules.filter(function (m) { return (m.name + ' ' + m.area).toLowerCase().indexOf(q) !== -1; }) : allModules;
|
||||||
|
if (matched.length === 0) {
|
||||||
|
tbody.innerHTML = '';
|
||||||
|
empty.style.display = 'block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
empty.style.display = 'none';
|
||||||
|
var html = '';
|
||||||
|
for (var i = 0; i < matched.length; i++) {
|
||||||
|
var mod = matched[i];
|
||||||
|
var v19 = mod.v19 ? '<span class="oca-check">✓</span>' : '<span class="oca-cross">–</span>';
|
||||||
|
var v20 = mod.v20 ? '<span class="oca-check">✓</span>' : '<span class="oca-cross">–</span>';
|
||||||
|
html += '<tr>' +
|
||||||
|
'<td>' + esc(mod.name) + '</td>' +
|
||||||
|
'<td>' + esc(mod.area) + '</td>' +
|
||||||
|
'<td>' + v19 + '</td>' +
|
||||||
|
'<td>' + v20 + '</td>' +
|
||||||
|
'<td><a href="' + esc(mod.URL) + '" target="_blank" rel="noopener" class="oca-icon-link" title="View on GitHub"><i class="fas fa-external-link-alt"></i></a></td>' +
|
||||||
|
'</tr>';
|
||||||
|
}
|
||||||
|
tbody.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function esc(s) {
|
||||||
|
var d = document.createElement('div');
|
||||||
|
d.appendChild(document.createTextNode(s || ''));
|
||||||
|
return d.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('https://n8n.odoo4projects.com/webhook/oc-guy/modules')
|
||||||
|
.then(function (r) { return r.json(); })
|
||||||
|
.then(function (data) {
|
||||||
|
if (data && Array.isArray(data.data)) {
|
||||||
|
allModules = data.data;
|
||||||
|
} else if (Array.isArray(data) && data.length > 0 && Array.isArray(data[0].data)) {
|
||||||
|
allModules = data[0].data;
|
||||||
|
} else if (Array.isArray(data)) {
|
||||||
|
allModules = data;
|
||||||
|
}
|
||||||
|
loading.style.display = 'none';
|
||||||
|
render(searchInput ? searchInput.value : '');
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
loading.textContent = 'Could not load module status.';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.addEventListener('input', function () {
|
||||||
|
render(this.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buy Now buttons (no inline onclick) */
|
||||||
|
document.querySelectorAll('.btn-buy').forEach(function(btn) {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
var id = this.getAttribute('data-id');
|
||||||
|
if (id) buyNow(parseInt(id));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
@@ -1,55 +1,61 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/</loc>
|
<loc>https://odoo4projects.com/</loc>
|
||||||
<lastmod>2026-06-24</lastmod>
|
<lastmod>2026-06-24</lastmod>
|
||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
<priority>1.0</priority>
|
<priority>1.0</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/news-platform-update.html</loc>
|
<loc>https://odoo4projects.com/odoo-hosting-2027.html</loc>
|
||||||
|
<lastmod>2026-10-21</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.9</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://odoo4projects.com/blog/posts/news-platform-update.html</loc>
|
||||||
<lastmod>2026-06-24</lastmod>
|
<lastmod>2026-06-24</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/guide-migrate-enterprise.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/guide-migrate-enterprise.html</loc>
|
||||||
<lastmod>2026-06-20</lastmod>
|
<lastmod>2026-06-20</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/howto-custom-module.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/howto-custom-module.html</loc>
|
||||||
<lastmod>2026-06-17</lastmod>
|
<lastmod>2026-06-17</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/news-official-partner.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/news-official-partner.html</loc>
|
||||||
<lastmod>2026-06-14</lastmod>
|
<lastmod>2026-06-14</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/speed-run-backup.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/speed-run-backup.html</loc>
|
||||||
<lastmod>2026-06-10</lastmod>
|
<lastmod>2026-06-10</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/howto-ai-automation.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/howto-ai-automation.html</loc>
|
||||||
<lastmod>2026-06-06</lastmod>
|
<lastmod>2026-06-06</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/speed-run-deploy.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/speed-run-deploy.html</loc>
|
||||||
<lastmod>2026-06-02</lastmod>
|
<lastmod>2026-06-02</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://ODOO4projects.com/blog/posts/my-first-post.html</loc>
|
<loc>https://odoo4projects.com/blog/posts/my-first-post.html</loc>
|
||||||
<lastmod>2026-05-28</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
/* ================= Chat Toggle Button ================= */
|
||||||
|
#cw-chatToggle {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 24px;
|
||||||
|
right: 24px;
|
||||||
|
width: 100px;
|
||||||
|
height: 50px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 25px;
|
||||||
|
padding: 0;
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 100000;
|
||||||
|
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
|
||||||
|
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatToggle:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatToggle img {
|
||||||
|
width: 80%;
|
||||||
|
height: 80%;
|
||||||
|
object-fit: contain;
|
||||||
|
display: block;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= Chat Widget ================= */
|
||||||
|
#cw-chatWidget {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 100px;
|
||||||
|
right: 24px;
|
||||||
|
width: 500px;
|
||||||
|
max-height: 70vh;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 12px;
|
||||||
|
flex-direction: column;
|
||||||
|
z-index: 100000;
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatWidget.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatWidget .cw-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px 0 10px 0;
|
||||||
|
background: #f8f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatWidget .cw-header img {
|
||||||
|
width: 80%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status Bar */
|
||||||
|
#cw-status {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
max-height: 0;
|
||||||
|
transition: max-height 0.5s ease, padding 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Messages */
|
||||||
|
#cw-chatMessages {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
background: #fafafa;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form */
|
||||||
|
#cw-chatForm {
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatInput {
|
||||||
|
flex: 1;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 20px;
|
||||||
|
font-size: 1rem;
|
||||||
|
border-radius: 0 0 0 12px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatForm button {
|
||||||
|
background-color: #0070c0;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 0 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 0 0 12px 0;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw-chatForm button:hover {
|
||||||
|
background-color: #005a9e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Messages Bubbles */
|
||||||
|
.cw-message {
|
||||||
|
max-width: 75%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cw-message.user {
|
||||||
|
background-color: #DCF8C6;
|
||||||
|
color: #333;
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cw-message.bot {
|
||||||
|
background-color: #E0E0E0;
|
||||||
|
color: #333;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= Wizard ================= */
|
||||||
|
.wizard-headline {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 20px 0;
|
||||||
|
background-color: #f8f9f9;
|
||||||
|
color: #2c3e50;
|
||||||
|
border-bottom: 2px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard li {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-right: 2px solid #fff;
|
||||||
|
color: white;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard li:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard .header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard .text {
|
||||||
|
padding: 20px 10px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wizard state colors */
|
||||||
|
.wizard li.open {
|
||||||
|
background-color: #7f8c8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard li.open .header {
|
||||||
|
background-color: #5d6d7e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard li.done {
|
||||||
|
background-color: #1e8449;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard li.done .header {
|
||||||
|
background-color: #145a32;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wizard i {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
// ================= CONFIG =================
|
||||||
|
//const baseUrl = 'http://localhost:8000'; // Base URL for all resources
|
||||||
|
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
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
// ================= WIDGET HTML =================
|
||||||
|
const widgetHTML = `
|
||||||
|
<div id="cw-chatWidget">
|
||||||
|
<div class="cw-header">
|
||||||
|
<img src="${config.logoImage}" alt="Logo" class="cw-logo"/>
|
||||||
|
</div>
|
||||||
|
<div id="cw-chatMessages" class="cw-messages"></div>
|
||||||
|
<form id="cw-chatForm" class="cw-form">
|
||||||
|
<input type="text" id="cw-chatInput" placeholder="Type your message..." />
|
||||||
|
<button type="submit">Send</button>
|
||||||
|
</form>
|
||||||
|
<div id="cw-status" class="cw-status"></div>
|
||||||
|
</div>
|
||||||
|
<button id="cw-chatToggle">
|
||||||
|
<img src="${config.buttonImage}" alt="Chat"/>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// ================= UTILS =================
|
||||||
|
function loadCSS(url) {
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = url;
|
||||||
|
document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendMessage(chatMessages, text, sender) {
|
||||||
|
const msg = document.createElement('div');
|
||||||
|
msg.classList.add('cw-message', sender === 'user' ? 'user' : 'bot');
|
||||||
|
msg.innerHTML = text;
|
||||||
|
chatMessages.appendChild(msg);
|
||||||
|
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= MAIN =================
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
try {
|
||||||
|
// Load CSS
|
||||||
|
loadCSS(config.cssUrl);
|
||||||
|
|
||||||
|
// Inject chat widget HTML
|
||||||
|
document.body.insertAdjacentHTML('beforeend', widgetHTML);
|
||||||
|
document.dispatchEvent(new CustomEvent('JSsucks'));
|
||||||
|
|
||||||
|
// ================= DOM REFERENCES =================
|
||||||
|
const chatToggle = document.getElementById('cw-chatToggle');
|
||||||
|
const chatWidget = document.getElementById('cw-chatWidget');
|
||||||
|
const chatForm = document.getElementById('cw-chatForm');
|
||||||
|
const chatInput = document.getElementById('cw-chatInput');
|
||||||
|
const chatMessages = document.getElementById('cw-chatMessages');
|
||||||
|
const statusDiv = document.getElementById('cw-status');
|
||||||
|
|
||||||
|
const chatid = crypto.randomUUID();
|
||||||
|
let chatOpened = false;
|
||||||
|
|
||||||
|
// ================= BOT COMMUNICATION =================
|
||||||
|
async function sendMessageToBot(messageText) {
|
||||||
|
chatWidget.classList.add('active');
|
||||||
|
appendMessage(chatMessages, messageText, 'user');
|
||||||
|
chatInput.value = '';
|
||||||
|
chatInput.focus();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(config.api, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
action: 'sendMessage',
|
||||||
|
chatid,
|
||||||
|
chatInput: messageText
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (data.status) {
|
||||||
|
statusDiv.innerHTML = data.status;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
statusDiv.style.maxHeight = statusDiv.scrollHeight + 'px';
|
||||||
|
statusDiv.style.padding = '10px';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
statusDiv.style.maxHeight = '0';
|
||||||
|
statusDiv.style.padding = '0 10px';
|
||||||
|
}
|
||||||
|
|
||||||
|
appendMessage(chatMessages, data.output, 'bot');
|
||||||
|
} catch (error) {
|
||||||
|
appendMessage(chatMessages, 'Fehler beim Verbinden mit dem Server. Bitte versuchen Sie es später erneut.', 'bot');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.sendMessageToBot = sendMessageToBot;
|
||||||
|
|
||||||
|
// ================= EVENT LISTENERS =================
|
||||||
|
chatToggle.addEventListener('click', () => {
|
||||||
|
const isVisible = chatWidget.classList.contains('active');
|
||||||
|
chatWidget.classList.toggle('active', !isVisible);
|
||||||
|
|
||||||
|
if (!isVisible && !chatOpened) {
|
||||||
|
appendMessage(chatMessages, config.preamble, 'bot');
|
||||||
|
chatOpened = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chatForm.addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const input = chatInput.value.trim();
|
||||||
|
if (input) sendMessageToBot(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to initialize chat widget:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="26.458334mm"
|
||||||
|
height="26.458334mm"
|
||||||
|
viewBox="0 0 26.458334 26.458334"
|
||||||
|
version="1.1"
|
||||||
|
id="svg351"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
sodipodi:docname="4.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview353"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2"
|
||||||
|
inkscape:cx="141.75"
|
||||||
|
inkscape:cy="-67.25"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1127"
|
||||||
|
inkscape:window-x="1920"
|
||||||
|
inkscape:window-y="37"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs348" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-27.042028,-166.7327)">
|
||||||
|
<g
|
||||||
|
id="g22"
|
||||||
|
transform="matrix(0.15346171,0,0,0.15347061,-71.664544,106.29597)">
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="713.07,486.53 750.82,441.47 742.83,486.53 "
|
||||||
|
id="polygon14"
|
||||||
|
style="fill:#ed703e" />
|
||||||
|
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="752.1,393.8 669.3,488.25 663.26,523.19 733.12,523.19 725.6,566.2 643.2,566.2 643.2,393.8 "
|
||||||
|
id="polygon16"
|
||||||
|
style="fill:#ed703e" />
|
||||||
|
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="798.47,393.8 815.61,393.8 815.61,486.53 782.29,486.53 "
|
||||||
|
id="polygon18"
|
||||||
|
style="fill:#ed703e" />
|
||||||
|
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="767.94,566.2 775.83,523.19 815.61,523.19 815.61,566.2 "
|
||||||
|
id="polygon20"
|
||||||
|
style="fill:#ed703e" />
|
||||||
|
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 27.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 671.21002 172.39999"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="logo-01.svg"
|
||||||
|
width="671.21002"
|
||||||
|
height="172.39999"
|
||||||
|
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs47" /><sodipodi:namedview
|
||||||
|
id="namedview45"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.86041667"
|
||||||
|
inkscape:cx="335.30266"
|
||||||
|
inkscape:cy="86.004843"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="37"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" />
|
||||||
|
<style
|
||||||
|
type="text/css"
|
||||||
|
id="style2">
|
||||||
|
.st0{fill:#68696D;}
|
||||||
|
.st1{fill:#ED703E;}
|
||||||
|
</style>
|
||||||
|
<g
|
||||||
|
id="g42"
|
||||||
|
transform="translate(-144.4,-393.8)">
|
||||||
|
<g
|
||||||
|
id="g8">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 427.65,509.26 c -9.27,-5.19 -16.61,-12.39 -22.02,-21.6 -5.42,-9.21 -8.12,-19.62 -8.12,-31.23 0,-11.61 2.71,-22.02 8.12,-31.23 5.41,-9.21 12.75,-16.38 22.02,-21.52 9.26,-5.13 19.42,-7.7 30.47,-7.7 11.16,0 21.35,2.57 30.56,7.7 9.21,5.14 16.49,12.31 21.85,21.52 5.36,9.21 8.04,19.62 8.04,31.23 0,11.61 -2.68,22.02 -8.04,31.23 -5.36,9.21 -12.67,16.41 -21.93,21.6 -9.27,5.19 -19.42,7.79 -30.47,7.79 -11.06,-0.01 -21.22,-2.6 -30.48,-7.79 z m 50.31,-30.9 c 4.86,-5.47 7.28,-12.78 7.28,-21.93 0,-9.38 -2.43,-16.77 -7.28,-22.19 -4.86,-5.41 -11.47,-8.12 -19.84,-8.12 -8.48,0 -15.13,2.71 -19.93,8.12 -4.8,5.42 -7.2,12.81 -7.2,22.19 0,9.27 2.4,16.61 7.2,22.02 4.8,5.42 11.44,8.12 19.93,8.12 8.37,0 14.99,-2.74 19.84,-8.21 z"
|
||||||
|
id="path4" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 528.4,509.26 c -9.27,-5.19 -16.61,-12.39 -22.02,-21.6 -5.42,-9.21 -8.12,-19.62 -8.12,-31.23 0,-11.61 2.71,-22.02 8.12,-31.23 5.41,-9.21 12.75,-16.38 22.02,-21.52 9.26,-5.13 19.42,-7.7 30.47,-7.7 11.16,0 21.35,2.57 30.56,7.7 9.21,5.14 16.49,12.31 21.85,21.52 5.36,9.21 8.04,19.62 8.04,31.23 0,11.61 -2.68,22.02 -8.04,31.23 -5.36,9.21 -12.67,16.41 -21.93,21.6 -9.27,5.19 -19.42,7.79 -30.47,7.79 -11.05,-0.01 -21.21,-2.6 -30.48,-7.79 z m 50.32,-30.9 c 4.86,-5.47 7.28,-12.78 7.28,-21.93 0,-9.38 -2.43,-16.77 -7.28,-22.19 -4.86,-5.41 -11.47,-8.12 -19.84,-8.12 -8.48,0 -15.13,2.71 -19.93,8.12 -4.8,5.42 -7.2,12.81 -7.2,22.19 0,9.27 2.4,16.61 7.2,22.02 4.8,5.42 11.44,8.12 19.93,8.12 8.37,0 14.98,-2.74 19.84,-8.21 z"
|
||||||
|
id="path6" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="M 260.51,423.82 C 255,414.35 247.52,407 238.07,401.72 c -9.47,-5.28 -19.93,-7.92 -31.39,-7.92 -11.35,0 -21.79,2.64 -31.32,7.92 -9.52,5.28 -17.05,12.64 -22.62,22.1 -5.57,9.47 -8.34,20.16 -8.34,32.08 0,11.94 2.77,22.63 8.34,32.08 5.56,9.47 13.09,16.86 22.62,22.19 9.52,5.33 19.96,8 31.32,8 11.35,0 21.78,-2.67 31.3,-8 9.52,-5.33 17.03,-12.73 22.54,-22.19 5.51,-9.45 8.26,-20.14 8.26,-32.08 -0.01,-11.92 -2.77,-22.61 -8.27,-32.08 z m -33.46,54.62 c -4.99,5.62 -11.79,8.44 -20.38,8.44 -8.72,0 -15.54,-2.78 -20.48,-8.34 -4.93,-5.56 -7.39,-13.11 -7.39,-22.63 0,-9.63 2.46,-17.23 7.39,-22.79 4.93,-5.56 11.75,-8.34 20.48,-8.34 8.6,0 15.39,2.78 20.38,8.34 4.99,5.56 7.47,13.16 7.47,22.79 0.01,9.4 -2.48,16.91 -7.47,22.53 z"
|
||||||
|
id="path10" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 381.04,424.95 c -5.15,-9.18 -12.52,-16.32 -22.1,-21.41 -9.58,-5.1 -20.73,-7.66 -33.46,-7.66 h -48 v 121.28 h 48 c 12.61,0 23.7,-2.61 33.28,-7.83 9.58,-5.22 16.97,-12.41 22.19,-21.59 5.22,-9.18 7.83,-19.62 7.83,-31.31 0.01,-11.82 -2.58,-22.31 -7.74,-31.48 z m -34.92,54.35 c -5.62,5.39 -13.36,8.09 -23.22,8.09 h -11.7 v -62.27 h 11.7 c 9.87,0 17.6,2.72 23.22,8.17 5.62,5.45 8.44,13.16 8.44,23.13 -0.01,9.87 -2.82,17.49 -8.44,22.88 z"
|
||||||
|
id="path12" />
|
||||||
|
<g
|
||||||
|
id="g22">
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="742.83,486.53 713.07,486.53 750.82,441.47 "
|
||||||
|
id="polygon14" />
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="669.3,488.25 663.26,523.19 733.12,523.19 725.6,566.2 643.2,566.2 643.2,393.8 752.1,393.8 "
|
||||||
|
id="polygon16" />
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="782.29,486.53 798.47,393.8 815.61,393.8 815.61,486.53 "
|
||||||
|
id="polygon18" />
|
||||||
|
<polygon
|
||||||
|
class="st1"
|
||||||
|
points="815.61,566.2 767.94,566.2 775.83,523.19 815.61,523.19 "
|
||||||
|
id="polygon20" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g40">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 162.99,549.74 c -1.81,1.75 -4.58,2.63 -8.3,2.63 h -6.13 v 13.31 H 144.4 V 533.8 h 10.29 c 3.6,0 6.34,0.87 8.21,2.61 1.87,1.74 2.81,3.98 2.81,6.72 0,2.65 -0.91,4.85 -2.72,6.61 z m -3.18,-2.31 c 1.1,-1.01 1.65,-2.44 1.65,-4.3 0,-3.93 -2.26,-5.9 -6.77,-5.9 h -6.13 v 11.71 h 6.13 c 2.31,0 4.02,-0.51 5.12,-1.51 z"
|
||||||
|
id="path24" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 224.26,565.68 -7.59,-13.04 h -5.03 v 13.04 h -4.16 V 533.8 h 10.29 c 2.41,0 4.44,0.41 6.11,1.23 1.66,0.82 2.9,1.94 3.73,3.34 0.82,1.4 1.23,3 1.23,4.8 0,2.2 -0.63,4.13 -1.9,5.81 -1.27,1.68 -3.16,2.79 -5.7,3.34 l 8.01,13.36 z M 211.64,549.3 h 6.13 c 2.26,0 3.95,-0.56 5.08,-1.67 1.13,-1.11 1.69,-2.6 1.69,-4.46 0,-1.89 -0.56,-3.35 -1.67,-4.39 -1.11,-1.04 -2.81,-1.56 -5.1,-1.56 h -6.13 z"
|
||||||
|
id="path26" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 278.24,563.92 c -2.44,-1.39 -4.37,-3.32 -5.79,-5.81 -1.42,-2.49 -2.13,-5.28 -2.13,-8.39 0,-3.11 0.71,-5.91 2.13,-8.39 1.42,-2.49 3.35,-4.42 5.79,-5.81 2.44,-1.39 5.14,-2.08 8.1,-2.08 2.99,0 5.7,0.69 8.14,2.08 2.44,1.39 4.36,3.32 5.76,5.79 1.4,2.47 2.1,5.28 2.1,8.42 0,3.14 -0.7,5.95 -2.1,8.42 -1.4,2.47 -3.32,4.4 -5.76,5.79 -2.44,1.39 -5.15,2.08 -8.14,2.08 -2.96,-0.02 -5.66,-0.71 -8.1,-2.1 z m 14.12,-3.09 c 1.78,-1.04 3.19,-2.52 4.21,-4.44 1.02,-1.92 1.53,-4.15 1.53,-6.68 0,-2.56 -0.51,-4.8 -1.53,-6.7 -1.02,-1.91 -2.42,-3.38 -4.19,-4.41 -1.77,-1.04 -3.78,-1.56 -6.04,-1.56 -2.26,0 -4.27,0.52 -6.04,1.56 -1.77,1.04 -3.16,2.51 -4.19,4.41 -1.02,1.91 -1.53,4.14 -1.53,6.7 0,2.53 0.51,4.76 1.53,6.68 1.02,1.92 2.42,3.4 4.21,4.44 1.78,1.04 3.79,1.56 6.02,1.56 2.23,-0.01 4.23,-0.52 6.02,-1.56 z"
|
||||||
|
id="path28" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 360.5,533.79 v 23.56 c 0,2.62 -0.81,4.72 -2.42,6.29 -1.62,1.57 -3.75,2.36 -6.4,2.36 -2.68,0 -4.83,-0.8 -6.45,-2.4 -1.62,-1.6 -2.42,-3.79 -2.42,-6.56 h 4.16 c 0.03,1.56 0.43,2.82 1.21,3.8 0.78,0.98 1.94,1.46 3.5,1.46 1.56,0 2.71,-0.46 3.48,-1.39 0.76,-0.93 1.14,-2.11 1.14,-3.55 V 533.8 h 4.2 z"
|
||||||
|
id="path30" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 409.44,537.18 v 10.66 h 11.62 v 3.43 h -11.62 v 10.98 h 12.99 v 3.43 h -17.15 v -31.93 h 17.15 v 3.43 z"
|
||||||
|
id="path32" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 465.89,541.32 c 1.4,-2.49 3.32,-4.43 5.74,-5.83 2.42,-1.4 5.12,-2.1 8.07,-2.1 3.48,0 6.51,0.84 9.1,2.52 2.59,1.68 4.48,4.06 5.67,7.14 h -4.99 c -0.89,-1.92 -2.16,-3.4 -3.82,-4.44 -1.66,-1.04 -3.65,-1.56 -5.97,-1.56 -2.23,0 -4.22,0.52 -5.99,1.56 -1.77,1.04 -3.16,2.51 -4.16,4.41 -1.01,1.91 -1.51,4.14 -1.51,6.7 0,2.53 0.5,4.75 1.51,6.66 1.01,1.91 2.39,3.38 4.16,4.41 1.77,1.04 3.77,1.56 5.99,1.56 2.32,0 4.31,-0.51 5.97,-1.53 1.66,-1.02 2.93,-2.49 3.82,-4.41 h 4.99 c -1.19,3.05 -3.08,5.41 -5.67,7.07 -2.59,1.66 -5.63,2.49 -9.1,2.49 -2.96,0 -5.65,-0.69 -8.07,-2.08 -2.42,-1.39 -4.34,-3.32 -5.74,-5.79 -1.4,-2.47 -2.1,-5.26 -2.1,-8.37 0,-3.11 0.7,-5.92 2.1,-8.41 z"
|
||||||
|
id="path34" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 556.88,533.79 v 3.38 h -8.69 v 28.5 h -4.16 v -28.5 h -8.74 v -3.38 z"
|
||||||
|
id="path36" />
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 603.06,564.88 c -1.66,-0.75 -2.97,-1.78 -3.91,-3.11 -0.95,-1.33 -1.43,-2.86 -1.46,-4.6 h 4.44 c 0.15,1.49 0.77,2.75 1.85,3.77 1.08,1.02 2.66,1.53 4.73,1.53 1.98,0 3.55,-0.49 4.69,-1.49 1.14,-0.99 1.72,-2.26 1.72,-3.82 0,-1.22 -0.34,-2.21 -1.01,-2.97 -0.67,-0.76 -1.51,-1.34 -2.52,-1.74 -1.01,-0.4 -2.36,-0.82 -4.07,-1.28 -2.1,-0.55 -3.79,-1.1 -5.06,-1.65 -1.27,-0.55 -2.35,-1.41 -3.25,-2.59 -0.9,-1.17 -1.35,-2.75 -1.35,-4.73 0,-1.74 0.44,-3.28 1.33,-4.62 0.88,-1.34 2.13,-2.38 3.73,-3.11 1.6,-0.73 3.44,-1.1 5.51,-1.1 2.99,0 5.44,0.75 7.34,2.24 1.91,1.5 2.98,3.48 3.22,5.95 h -4.57 c -0.15,-1.22 -0.79,-2.29 -1.92,-3.23 -1.13,-0.93 -2.62,-1.39 -4.48,-1.39 -1.74,0 -3.16,0.45 -4.25,1.35 -1.1,0.9 -1.65,2.16 -1.65,3.77 0,1.16 0.33,2.11 0.98,2.84 0.66,0.73 1.46,1.29 2.42,1.67 0.96,0.38 2.31,0.82 4.05,1.3 2.1,0.58 3.8,1.15 5.08,1.72 1.28,0.57 2.38,1.43 3.29,2.61 0.91,1.17 1.37,2.77 1.37,4.78 0,1.56 -0.41,3.02 -1.24,4.39 -0.83,1.37 -2.04,2.49 -3.66,3.34 -1.62,0.85 -3.52,1.28 -5.72,1.28 -2.08,0.01 -3.97,-0.36 -5.63,-1.11 z"
|
||||||
|
id="path38" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,560 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
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" />
|
||||||
|
<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 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
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
||||||
|
/>
|
||||||
|
<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>
|
||||||
|
/* ---- Support Hero ---- */
|
||||||
|
.support-hero {
|
||||||
|
padding: 4rem 0 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
background: var(--light);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.support-hero h1 {
|
||||||
|
font-size: clamp(1.8rem, 3.2vw, 2.8rem);
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
.support-hero p {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
.support-hero strong {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- FAQ Section ---- */
|
||||||
|
.faq-section {
|
||||||
|
padding: 3rem 0 4rem;
|
||||||
|
}
|
||||||
|
.faq-section h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-tabs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.4rem;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.faq-tab-btn {
|
||||||
|
padding: 0.55rem 1.1rem;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #212529;
|
||||||
|
transition: all 0.2s;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
.faq-tab-btn small {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: rgba(33, 37, 41, 0.5);
|
||||||
|
margin-top: 0.1rem;
|
||||||
|
}
|
||||||
|
.faq-tab-btn:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
.faq-tab-btn.active {
|
||||||
|
background: linear-gradient(135deg, rgba(113,75,103,0.08), rgba(113,75,103,0.03));
|
||||||
|
border-color: var(--primary);
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.faq-tab-btn.active small {
|
||||||
|
color: rgba(113, 75, 103, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-panel {
|
||||||
|
display: none;
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.faq-panel.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
margin-bottom: 0.6rem;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.faq-question {
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0.9rem 1.1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--dark);
|
||||||
|
font-family: "Inter Tight", sans-serif;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: left;
|
||||||
|
transition: background 0.2s;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.faq-question:hover {
|
||||||
|
background: var(--light);
|
||||||
|
}
|
||||||
|
.faq-question .faq-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: var(--primary);
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
.faq-question.open .faq-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.faq-answer {
|
||||||
|
display: none;
|
||||||
|
padding: 0 1.1rem 0.9rem;
|
||||||
|
color: rgba(33, 37, 41, 0.7);
|
||||||
|
font-size: 0.88rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
.faq-answer.open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.faq-answer ul {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
}
|
||||||
|
.faq-answer li {
|
||||||
|
margin: 0.3rem 0;
|
||||||
|
}
|
||||||
|
.faq-answer a {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.faq-answer strong {
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Contact Section ---- */
|
||||||
|
.contact-section {
|
||||||
|
padding: 3rem 0 4rem;
|
||||||
|
background: var(--light);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.contact-section h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
color: var(--dark);
|
||||||
|
}
|
||||||
|
.contact-form {
|
||||||
|
max-width: 580px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1.1rem;
|
||||||
|
}
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
color: rgba(33, 37, 41, 0.6);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
.form-group label .required {
|
||||||
|
color: #dc3545;
|
||||||
|
}
|
||||||
|
.form-group input,
|
||||||
|
.form-group textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.65rem 0.85rem;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
color: var(--dark);
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.form-group input:focus,
|
||||||
|
.form-group textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
|
.form-group textarea {
|
||||||
|
min-height: 90px;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
.contact-form .btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.7rem;
|
||||||
|
}
|
||||||
|
.form-success {
|
||||||
|
display: none;
|
||||||
|
background: #d4edda;
|
||||||
|
border: 1px solid #c3e6cb;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 0.8rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
color: #155724;
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
}
|
||||||
|
.form-success.visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.support-hero { padding: 2.5rem 0 1.5rem; }
|
||||||
|
.faq-tab-btn { padding: 0.4rem 0.8rem; font-size: 0.75rem; }
|
||||||
|
.contact-form { padding: 1.25rem; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="blog-header">
|
||||||
|
<a href="index.html">← Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="support-hero">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Support and FAQ</h1>
|
||||||
|
<p>
|
||||||
|
For the fastest help, please read our <strong>FAQ</strong> first — our support
|
||||||
|
bot can assist with quick fixes like <strong>git pull</strong> or restarts — or
|
||||||
|
simply send a <strong>ticket</strong> to our support team for further assistance.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FAQ -->
|
||||||
|
<section class="faq-section" id="faq">
|
||||||
|
<div class="container">
|
||||||
|
<h2>FAQ</h2>
|
||||||
|
|
||||||
|
<div class="faq-tabs" id="faqTabs">
|
||||||
|
<button class="faq-tab-btn active" data-tab="first-steps">
|
||||||
|
First Steps
|
||||||
|
<small>What is your service about</small>
|
||||||
|
</button>
|
||||||
|
<button class="faq-tab-btn" data-tab="advanced">
|
||||||
|
Advanced Users
|
||||||
|
<small>Install Modules, configure Backup</small>
|
||||||
|
</button>
|
||||||
|
<button class="faq-tab-btn" data-tab="trouble">
|
||||||
|
Trouble Shooting
|
||||||
|
<small>Service is unavailable</small>
|
||||||
|
</button>
|
||||||
|
<button class="faq-tab-btn" data-tab="commercial">
|
||||||
|
Commercial
|
||||||
|
<small>All information about our services</small>
|
||||||
|
</button>
|
||||||
|
<button class="faq-tab-btn" data-tab="migrate">
|
||||||
|
Bring your Database
|
||||||
|
<small>Migrate from another provider</small>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- First Steps -->
|
||||||
|
<div class="faq-panel active" id="panel-first-steps">
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>My Odoo seems empty. What can I do with it?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>We provide a vanilla Odoo installation, which means your Odoo comes empty but fully ready for <strong>you to customize</strong> with the apps your business needs. To get started, go to the Apps menu, browse the available apps, and click Install — each app will appear in your main menu once installed, ready to use.</p>
|
||||||
|
<p>Here are some examples for different types of businesses:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Manufacturing unit</strong>: Install the Manufacturing and Inventory/Logistics apps.</li>
|
||||||
|
<li><strong>Online store</strong>: Install Website, eCommerce, and Sales apps.</li>
|
||||||
|
<li><strong>Service company</strong>: Install Project and Timesheets apps.</li>
|
||||||
|
<li><strong>Retail shop</strong>: Install Point of Sale (POS) and Inventory apps.</li>
|
||||||
|
<li><strong>Accounting firm</strong>: Install Accounting and Invoicing apps.</li>
|
||||||
|
<li><strong>Marketing agency</strong>: Install CRM, Marketing, and Email Marketing apps.</li>
|
||||||
|
<li><strong>Event company</strong>: Install Events and Website apps.</li>
|
||||||
|
</ul>
|
||||||
|
<p>No matter your business type, you can pick the apps that match your needs, and gradually build your Odoo system step by step.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How do I install a new app?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>Open the Apps menu, search for the app you want, and click Install. Once installed, the app will appear in your main menu, ready to use. For additional apps not included by default, you can also install them via Git or use our one-click Quick Git feature for faster setup.</p>
|
||||||
|
<p>All Odoo Community apps are included, and more free apps can be found at <a href="https://odoo-community.org/" target="_blank" rel="noopener">odoo-community.org</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How do I add my email Server for sending messages from Odoo?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>To send emails from Odoo, you need to configure an Outgoing Mail Server. Go to Settings → Technical → Email → Outgoing Mail Servers and enter your email server details, such as SMTP server, port, username, and password. You can get the SMTP server information from your domain or email provider. After entering the information, test the connection to ensure it works correctly.</p>
|
||||||
|
<p>If you also want to receive emails in Odoo, you can set up Incoming Mail Servers under the same menu, using the IMAP/POP3 details from your provider.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How do I change my login name or password?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>Before making any changes, it is advised to <strong>set up your outgoing email server</strong> to ensure notifications and password resets work correctly.</p>
|
||||||
|
<p>Your login name is the email address associated with your account. To change it, go to Settings → Users & Companies → Users, select your user, and update the Email field. After changing your login name, you must log in using the new email and your existing password. To change your password, go to the same user settings, click Change Password, or use the "Forgot Password" link on the login page to reset it via email.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Advanced Users -->
|
||||||
|
<div class="faq-panel" id="panel-advanced">
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>Do I get SSH access to my service?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>No — SSH access is limited to Git operations only. All other management and configuration options are available through our Odoo Settings module.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How do I configure my Backup frequency?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>The backup job runs as a scheduled action within Odoo, ensuring your data is regularly saved. You can access and manage this job only when Development Mode is enabled, which allows you to view technical settings and scheduled actions that are otherwise hidden in the standard interface. This way, you can review, adjust, or trigger backups as needed.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How long are Backups stored?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>We store backups in slots, which are retained until they are overwritten. Backups are managed using a first-in, first-out (FIFO) queue. When a backup is overwritten, it is permanently deleted. If you need to keep more backups, you can upgrade your contract and purchase additional slots.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How do I route my domain to my Odoo?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>To route your domain to Odoo, you first need to update the A record at your domain provider to point to our server's IP address. You can find the A record settings in your domain registrar's control panel under DNS settings. Once the A record is updated, the server will need to be restarted to recognize the new domain.</p>
|
||||||
|
<p>After updating the A record, add your domain in Odoo: Settings → 4 Server → Domains and enter each domain on a separate line. Check your contract to see how many domain routings are included.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How can I install Odoo Enterprise?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>To install Odoo Enterprise, you first need to purchase a separate license from Odoo. Our prepared Git repository already includes an Enterprise folder where you can add the Enterprise addons, which can then be installed via Git.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Trouble Shooting -->
|
||||||
|
<div class="faq-panel" id="panel-trouble">
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>After a git check in, my server does not come up again or shows an error 500</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>If you've pushed a new module to the server and it prevents the service from starting, first revert your changes in Git and push the corrected version back to the server. Then open the support chat — you'll need your UUID (sent in the confirmation email). After you tell our chatbot to git pull and restart the server, you'll receive a confirmation email; once confirmed, we'll bring your Odoo instance back online.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>Why does my domain show an "Unknown Certificate" or "Bad Gateway"?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>This usually happens because the server has not been restarted after routing your domain to our service. Simply restart your server — once it comes back online, Odoo will generate the correct SSL certificate for your domain. If the error persists, please submit a support ticket.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Commercial -->
|
||||||
|
<div class="faq-panel" id="panel-commercial">
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>Is the Odoo Enterprise License included?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>No, the Odoo Enterprise License needs to be purchased separately.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How can I upgrade my service?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>You can upgrade your service directly in Odoo by going to Settings → 4 Server → Upgrade. From there, you can choose to move to a higher plan or add additional features individually, such as extra backup slots or additional domain routings.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bring your Database -->
|
||||||
|
<div class="faq-panel" id="panel-migrate">
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>How can I migrate my Odoo database from another service provider?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>To migrate your database to our service, please submit a support ticket indicating that you want to migrate. Our team will then send you a link to a secure form where you can upload your database. Once received, we will spin up a new server according to your requirements and provide you with the credentials.</p>
|
||||||
|
<p>We do not support patch releases (e.g., 18.1 or 17.2) — only the main releases (18.0, 17.0, 19.0) are supported. Our migration service currently supports databases based on Odoo 17, 18, and 19.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<button class="faq-question">
|
||||||
|
<span>Can I update my Odoo database from an older version, e.g., 14 → 19?</span>
|
||||||
|
<span class="faq-icon"><i class="fas fa-chevron-down"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="faq-answer">
|
||||||
|
<p>Yes, we can help you upgrade your database from older versions to a supported release (17, 18, or 19), but only after reviewing your database to ensure compatibility. Please submit a support ticket to start the process.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Contact -->
|
||||||
|
<section class="contact-section" id="contact">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Still questions? Contact our support.</h2>
|
||||||
|
<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" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Your Email <span class="required">*</span></label>
|
||||||
|
<input type="email" id="contactEmail" name="email_from" required placeholder="Your Email" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>UUID</label>
|
||||||
|
<input type="text" id="contactUuid" name="UUID" placeholder="Paste your ODOO4projects UUID here" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Subject <span class="required">*</span></label>
|
||||||
|
<input type="text" id="contactSubject" name="name" required placeholder="Subject" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Your Question <span class="required">*</span></label>
|
||||||
|
<textarea id="contactQuestion" name="description" required placeholder="Describe your issue or question in detail..."></textarea>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
<div class="form-success" id="formSuccess">
|
||||||
|
<i class="fas fa-check-circle"></i> Thank you! Your ticket has been submitted.
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll(".faq-question").forEach(function (btn) {
|
||||||
|
btn.addEventListener("click", function () {
|
||||||
|
var answer = this.nextElementSibling;
|
||||||
|
var isOpen = answer.classList.contains("open");
|
||||||
|
document.querySelectorAll(".faq-answer.open, .faq-question.open").forEach(function (el) {
|
||||||
|
el.classList.remove("open");
|
||||||
|
});
|
||||||
|
if (!isOpen) { answer.classList.add("open"); this.classList.add("open"); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.querySelectorAll(".faq-tab-btn").forEach(function (tab) {
|
||||||
|
tab.addEventListener("click", function () {
|
||||||
|
document.querySelectorAll(".faq-tab-btn, .faq-panel").forEach(function (el) {
|
||||||
|
el.classList.remove("active");
|
||||||
|
});
|
||||||
|
this.classList.add("active");
|
||||||
|
var panel = document.getElementById("panel-" + this.getAttribute("data-tab"));
|
||||||
|
if (panel) panel.classList.add("active");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var form = document.getElementById("supportForm");
|
||||||
|
var submitBtn = form.querySelector(".btn");
|
||||||
|
var successDiv = document.getElementById("formSuccess");
|
||||||
|
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.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||