From 8843af6402234129087b3d1f099bd038754607c8 Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Tue, 17 Mar 2026 16:15:12 +0000 Subject: [PATCH] Add analytics link to page headers, event tracking to calculator, update deploy script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add analytics.html to STATIC_FILES in deploy.sh - Add trackEvent/getVisitorId to script.js with page_view, show_results, copy_email hooks - Add "Analytics →" nav link to index.html and market.html headers Co-Authored-By: Claude Sonnet 4.6 --- deploy.sh | 2 +- index.html | 1 + market.html | 4 +++- script.js | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/deploy.sh b/deploy.sh index 46c34c3..f108270 100755 --- a/deploy.sh +++ b/deploy.sh @@ -13,7 +13,7 @@ ENV_FILE="${REPO_DIR}/server/.env" COMPOSE_FILE="${REPO_DIR}/docker-compose.yml" # Static files to deploy to Apache web root -STATIC_FILES=(index.html auth.js script.js config.json market.html market-script.js) +STATIC_FILES=(index.html auth.js script.js config.json market.html market-script.js analytics.html) # ── Colours ─────────────────────────────────────────────────────────────────── GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m' diff --git a/index.html b/index.html index 4a31f68..0b896c1 100755 --- a/index.html +++ b/index.html @@ -215,6 +215,7 @@
+ Analytics → - diff --git a/script.js b/script.js index a06d13e..dd235b3 100755 --- a/script.js +++ b/script.js @@ -29,6 +29,36 @@ let currentStep = 1; let activeStages = [false, false, false, false, false, false, false, false]; let lastCalculationData = null; +// ---- Usage Tracking ---- +const TRACK_API = (() => { + if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') return null; + const base = location.pathname.replace(/\/[^/]*$/, ''); + return `${base}/api/events`; +})(); + +async function getVisitorId() { + const raw = [ + navigator.language, + screen.width + 'x' + screen.height, + screen.colorDepth, + Intl.DateTimeFormat().resolvedOptions().timeZone, + navigator.hardwareConcurrency || '', + ].join('|'); + const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(raw)); + return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join(''); +} + +function trackEvent(event, metadata = {}) { + if (!TRACK_API) return; + getVisitorId().then(visitor_id => { + fetch(TRACK_API, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ event, page: 'calculator', visitor_id, metadata }), + }).catch(() => {}); + }); +} + // ---- Bootstrap ---- document.addEventListener('DOMContentLoaded', async () => { await initAuth(); @@ -37,6 +67,7 @@ document.addEventListener('DOMContentLoaded', async () => { initStepper(); initDatePickers(); bindEvents(); + trackEvent('page_view'); }); async function loadConfig() { @@ -664,6 +695,8 @@ function intVal(id) { // ---- Render Results ---- function renderResults(data) { lastCalculationData = data; + const briefType = document.getElementById('briefType').selectedOptions[0]?.text; + trackEvent('show_results', { briefType }); // Verdict banner const banner = document.getElementById('verdictBanner'); @@ -948,8 +981,9 @@ function csvEscape(str) { // ---- Copy for Email (Rich HTML) ---- function copyForEmail() { if (!lastCalculationData) return; - const data = lastCalculationData; const briefType = document.getElementById('briefType').selectedOptions[0]?.text || ''; + trackEvent('copy_email', { briefType }); + const data = lastCalculationData; // Inline styles for Outlook compatibility const tbl = 'border-collapse:collapse;width:100%;font-family:Calibri,Arial,sans-serif;font-size:13px;';