From 7267a27cda6170fb9f6eefff6a1ec3e1ff390264 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Wed, 3 Jun 2026 18:16:19 -0400 Subject: [PATCH] =?UTF-8?q?Portail=20self-service=20abonnement=20(staging?= =?UTF-8?q?=20/signup):=20stepper=20=C3=A9pur=C3=A9=20Forfait=E2=86=92Coor?= =?UTF-8?q?donn=C3=A9es=E2=86=92R=C3=A9cap=E2=86=92Confirmation,=20catalog?= =?UTF-8?q?ue=20r=C3=A9el,=20capture=20Lead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- services/targo-hub/lib/signup.js | 129 +++++++++++++++++++++++++++++++ services/targo-hub/server.js | 2 + 2 files changed, 131 insertions(+) create mode 100644 services/targo-hub/lib/signup.js diff --git a/services/targo-hub/lib/signup.js b/services/targo-hub/lib/signup.js new file mode 100644 index 0000000..e96a336 --- /dev/null +++ b/services/targo-hub/lib/signup.js @@ -0,0 +1,129 @@ +'use strict' +/** + * signup.js — portail self-service d'abonnement (STAGING, servi par le hub). + * Parcours épuré type e-commerce : Forfait → Coordonnées → Récap → Confirmation. + * Réutilise /api/catalog (existant). PAS publié sur Lovable tant que non validé. + * + * Routes publiques : + * GET /signup → page (stepper) + * POST /signup/submit → crée un Lead ERPNext + retourne la confirmation + */ +const { json, parseBody, erpFetch } = require('./helpers') + +async function createLead (body) { + const name = [body.first_name, body.last_name].filter(Boolean).join(' ').trim() || 'Client web' + const payload = { + lead_name: name, + email_id: body.email || '', + mobile_no: body.phone || '', + status: 'Lead', + // résumé de la demande dans le titre de la requête pour le suivi staff + request_type: 'Product Enquiry', + } + try { + const r = await erpFetch('/api/resource/Lead', { method: 'POST', body: JSON.stringify(payload) }) + if (r.status === 200 && r.data?.data) return r.data.data.name + } catch (e) { /* best-effort */ } + return null +} + +const PAGE = `Abonnement Gigafibre +
+
+
Chargement…
+
Gigafibre · propulsé par Targo
+
+` + +async function handle (req, res, method, path) { + if (path === '/signup' && method === 'GET') { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); return res.end(PAGE) } + if (path === '/signup/submit' && method === 'POST') { + const b = await parseBody(req) + const lead = await createLead(b) + return json(res, 200, { ok: true, lead, plan: b.plan_name }) + } + return json(res, 404, { error: 'not found' }) +} + +module.exports = { handle } diff --git a/services/targo-hub/server.js b/services/targo-hub/server.js index 29299a8..b406b78 100644 --- a/services/targo-hub/server.js +++ b/services/targo-hub/server.js @@ -130,6 +130,8 @@ const server = http.createServer(async (req, res) => { if (path.startsWith('/roster')) return require('./lib/roster').handle(req, res, method, path, url) // Portail public de prise de RDV (staging) — page + API client, PUBLIC (pas de SSO). if (path === '/book' || path.startsWith('/book/')) return require('./lib/roster').handlePublicBooking(req, res, method, path, url) + // Portail self-service d'abonnement (staging) — page + submit, PUBLIC. + if (path === '/signup' || path.startsWith('/signup/')) return require('./lib/signup').handle(req, res, method, path) if (path.startsWith('/campaigns')) return require('./lib/campaigns').handle(req, res, method, path) // Gift redirect wrapper — short public URLs in campaign emails that // 302 to the underlying Giftbit shortlink (subject to our expiry/revoke).