From c74315e950263f35a14623bdfe61f383b9ef3ab5 Mon Sep 17 00:00:00 2001 From: webmaster Date: Tue, 3 Nov 2026 11:47:05 +0000 Subject: [PATCH] fix(freelancer-directory): apply the ICP's five ship-blockers - hide the inert client request form; announce it as coming soon with an email fallback (no reachable error state, no submit that refuses a completed brief) - soften the contact claim to 'where a freelancer published their details' and make a card with no contact say so instead of showing an empty space - move the admin add/edit panel off the public page to its own draft page (/odoo-community-developers/admin/), unlinked, reachable only by URL - admin edit: load-and-confirm the record before writing, and read-modify-write the booleans so an untouched OCA_member/is_individual keeps its current value - application form: add Country + Odoo versions (the filters' inputs), GitHub and OCA profile URLs, and an explicit email-publication consent line - tighten 'How this works' from ~120 words to two short options + one caveat - build-directory.py: skip records with no Name; render GitHub/OCA links and the no-contact line; read Country via alias --- odoo-community-developers/admin/index.html | 548 +++++++++++++++++++++ odoo-community-developers/index.html | 298 +++-------- 2 files changed, 604 insertions(+), 242 deletions(-) create mode 100644 odoo-community-developers/admin/index.html diff --git a/odoo-community-developers/admin/index.html b/odoo-community-developers/admin/index.html new file mode 100644 index 0000000..062aabc --- /dev/null +++ b/odoo-community-developers/admin/index.html @@ -0,0 +1,548 @@ + + + + + + Freelancer records — admin + + + + + + + + + + + + +
+
+ ODOO4projects + Freelancer records — internal +
+
+ +
+
+

Add or correct a freelancer record

+

+ Internal page — not linked from the directory. Add a new record, or load an existing one by + its id, confirm it is the right person, then correct what is wrong. A save + posts to the one odoo_experts webhook and is applied after email confirmation. + Fields you leave alone keep the record's current value. +

+ +
+
+
+ + +
+
+ + +
+

Enter a record id and load it — you will see who it is before anything is written.

+
+ +
+ + +
+
+ + +
+
+ + + Our own count, not the freelancer's. +
+
+ + +
+
+ + +
+
+ + +
+
+ + + Separate with commas. +
+
+ + + Separate with commas. +
+
+ + + Separate with commas. +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+ + +
+
+
+
+
+ + + + diff --git a/odoo-community-developers/index.html b/odoo-community-developers/index.html index 141b35e..721cff8 100644 --- a/odoo-community-developers/index.html +++ b/odoo-community-developers/index.html @@ -4,14 +4,14 @@ Find an Odoo Freelancer for Your Project - + - + @@ -338,6 +338,13 @@ .dev-links a { color: var(--brass-deep); } + /* A card with no published contact says so — it never shows an empty space. */ + .dev-contact-none { + margin: 0; + font-size: 0.82rem; + font-style: italic; + color: var(--ink-soft); + } /* The three forms */ .dir-forms { @@ -453,47 +460,6 @@ color: #b3452f; } - /* Collapsed admin block */ - .dir-admin { - max-width: 860px; - margin: 1.75rem auto 0; - } - .dir-admin summary { - cursor: pointer; - list-style: none; - padding: 0.95rem 1.25rem; - display: flex; - justify-content: space-between; - align-items: center; - gap: 0.75rem; - font-family: Marcellus, Georgia, serif; - font-size: 1.02rem; - color: var(--midnight); - background: var(--ivory); - border: 1px solid var(--line); - border-radius: var(--radius-lg); - } - .dir-admin summary::-webkit-details-marker { - display: none; - } - .dir-admin summary::after { - content: "+"; - font-family: Inter, sans-serif; - color: var(--brass); - font-size: 1.15rem; - line-height: 1; - } - .dir-admin[open] summary::after { - content: "\2212"; - } - .dir-admin[open] summary { - border-radius: var(--radius-lg) var(--radius-lg) 0 0; - } - .dir-admin .form-card { - border-radius: 0 0 var(--radius-lg) var(--radius-lg); - border-top: 0; - } - /* Final CTA */ .cmp-cta { text-align: center; @@ -560,7 +526,7 @@ "@id": "https://odoo4projects.com/odoo-community-developers/#webpage", "url": "https://odoo4projects.com/odoo-community-developers/", "name": "Find an Odoo Freelancer for Your Project", - "description": "Browse independent Odoo freelancers for your project. Contact a freelancer directly, or post your brief and we forward it to them anonymously.", + "description": "Browse independent Odoo freelancers for your project and write to one directly, using the contact details they have published.", "inLanguage": "en-US", "isPartOf": { "@id": "https://odoo4projects.com/#organization" @@ -621,10 +587,10 @@

ODOO COMMUNITY FREELANCERS

Find an Odoo freelancer for your next project

-

Independent Odoo specialists you can hire for the piece you cannot do yourself — a custom module, a migration, an integration, an app your business needs. Contact a freelancer directly, or post your brief and we forward it to them without your name attached.

+

Independent Odoo specialists you can hire for the piece you cannot do yourself — a custom module, a migration, an integration, an app your business needs. Write to a freelancer directly, using the contact details they publish on their card.

@@ -634,9 +600,9 @@

How this works

-

You have an Odoo Community system and a job that needs a specialist. Below is a list of independent Odoo freelancers. Each one wrote their own profile — their focus, their languages, the work they take on — and we publish it as theirs. We do not rate them and we do not recommend one over another.

-

You have two ways to reach them. Contact them directly — every freelancer's own contact details are published for exactly that purpose, so you can write to whoever looks right. Or post your project and stay anonymous: we forward your brief to the freelancer or freelancers you pick, they answer, and we send their answer back to you. Your name and your contact details are not shown to them until you decide to engage.

-

Either way, the work is agreed between you and the freelancer. We list people and pass messages; the project and the contract are yours.

+

Write to a freelancer directly. Each card carries what that freelancer published — their focus, their languages, the work they take on, and their contact details where they chose to publish them. We do not rate them and we do not recommend one over another.

+

Or let us ask them for you. We forward your brief to the freelancers you choose, without your name attached. That service is not switched on yet — see Post a request below.

+

Either way the work is agreed between you and the freelancer. We publish the listings; the project and the contract are yours.

@@ -672,6 +638,7 @@
  • OCA member (as declared)
  • Projects on ODOO4projects
    4 projects — a count from our own records
    +

    No contact details published for this freelancer.

    @@ -683,41 +650,18 @@ - +
    -

    Post a request — anonymously

    +

    Post a request — coming soon

    -

    Not sure who to ask? Write your brief once and we forward it to the freelancers you choose, with no name and no contact details attached. A freelancer who is interested answers us, and we send their answer straight back to you. You decide whether to take it further — your details are only shared once you choose to engage.

    +

    We are building the anonymous request: you write your brief once, we forward it to the freelancers you choose with no name attached, and we send their answers back to you. It is not switched on yet. Until it is, email hello@odoo4projects.com with your brief and we will pass it on by hand.

    - -
    -
    -
    -
    - - - So we can send the freelancer's answer back to you. It is not shared with anyone until you decide to engage. -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    @@ -738,8 +682,12 @@
    - Used to confirm your listing before it goes live. + We confirm it before your listing goes live — and it is published on your card (see the consent below).
    +
    @@ -748,6 +696,16 @@
    +
    + + + Where you work from. A two-letter code is enough (NL, DE, US). +
    +
    + + + Separate with commas. The versions you actually work in. +
    @@ -758,6 +716,14 @@ Separate with commas.
    +
    + + +
    +
    + + +
    @@ -794,93 +760,16 @@
    - -
    -
    -
    - Admin: add or correct a freelancer record -
    -
    -
    - - - With an id, the record is updated. Without one, a new record is created. -
    -
    - - - Our own count, not the freelancer's. -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - - Separate with commas. -
    -
    - - - Separate with commas. -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    - - -
    - - -
    -
    -
    -
    -
    -
    -

    Start

    -

    Send your brief and we will forward it to the freelancers who fit it — anonymously, if you prefer. Or write to a freelancer directly from their card.

    +

    Browse the freelancers and write to one directly from their card — or email us your brief and we will pass it on by hand until the anonymous request service is switched on.

    @@ -939,6 +828,10 @@ /* ============================================================================ Odoo freelancer directory — page script. + This page FILTERS the build-time HTML and posts the freelancer application. + The admin add/edit form is NOT here — it lives on its own page at + /odoo-community-developers/admin/ (a draft, not linked from this page). + ONE webhook, for everything. The freelancer platform is a SEPARATE system from the CRM: there is no /crm, no /crm_odoo and nothing from the CRM skill here. If you find yourself reaching for a CRM endpoint, stop — wrong system. @@ -951,19 +844,8 @@ var ODOO_EXPERTS_WEBHOOK = "https://n8n.odoo4projects.com/webhook/ODOO4projects/odoo_experts"; - /* FORM 3 — client request / anonymous get-quote. - NOT BUILT YET. Deliberately inert: we do not guess a URL. When the workflow - exists, set this to the odoo_experts webhook or a new endpoint the user names - (nothing else), and the form below starts working unchanged. */ - var CLIENT_REQUEST_ENDPOINT = ""; - - /* OPTIONAL-LATER (do not build now): a mail-based "send me their details" gate - against bots — the client asks for a freelancer's contact and we mail it, so a - scraper reading the page gets nothing usable. Left out because the mail webhook - is currently 404 (spec §5). */ - - var MULTI_FIELDS = ["languages", "specialities"]; // comma-separated → array - var BOOL_FIELDS = ["OCA_member", "is_individual"]; + var MULTI_FIELDS = ["languages", "specialities", "odoo_versions"]; // comma-separated → array + var BOOL_FIELDS = ["OCA_member", "is_individual", "email_public_consent"]; var NUM_FIELDS = ["odoo4projects_clients"]; function fieldElements(form, name) { @@ -1127,76 +1009,8 @@ }); } - /* ---- Form 2: admin upload / edit (update when an id is present) ---- */ - function initAdminForm() { - var form = document.getElementById("adminForm"); - if (!form) return; - var status = document.getElementById("adminStatus"); - form.addEventListener("submit", function (event) { - event.preventDefault(); - if (!form.reportValidity()) return; - var submit = form.querySelector('button[type="submit"]'); - var hasId = !!form.querySelector('[name="id"]').value.trim(); - submit.disabled = true; - setStatus(status, "Saving…", null); - - var payload = buildPayload(form, true); - postToWebhook(payload) - .then(function () { - setStatus( - status, - hasId - ? "Saved. Check your inbox to confirm the change before it is applied." - : "New record sent. Check your inbox to confirm it before it goes live.", - "ok" - ); - }) - .catch(function () { - setStatus(status, "That did not save. Please try again.", "err"); - }) - .then(function () { - submit.disabled = false; - }); - }); - } - - /* ---- Form 3: client request (inert until CLIENT_REQUEST_ENDPOINT exists) ---- */ - function initClientRequestForm() { - var form = document.getElementById("clientRequestForm"); - if (!form) return; - var status = document.getElementById("clientRequestStatus"); - form.addEventListener("submit", function (event) { - event.preventDefault(); - if (!form.reportValidity()) return; - if (!CLIENT_REQUEST_ENDPOINT) { - // Not wired yet — say so plainly rather than pretend. - setStatus( - status, - "This request form is not switched on yet. For now, email us at hello@odoo4projects.com and we will pass your brief along.", - "err" - ); - return; - } - var payload = buildPayload(form, false); - fetch(CLIENT_REQUEST_ENDPOINT, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(payload) - }) - .then(function () { - setStatus(status, "Sent. We will forward it and come back to you with any answers.", "ok"); - form.reset(); - }) - .catch(function () { - setStatus(status, "That did not send. Please try again.", "err"); - }); - }); - } - initFilters(); initApplyForm(); - initAdminForm(); - initClientRequestForm();