1import { hasAuthenticatedSession } from '../auth/sessionState.js'; 2import { navigate } from '../front.js'; 3import { getAppSpaRedirectUrl } from '../runtime/appChannel.js'; 4import { computeAnnualSavings, formatAnnualSavingsHint, formatAnnualSavingsLabel } from './pricingSavings.js'; 5export const goToJoinOrDashboard = (event) => { 6 event.preventDefault(); 7 if (hasAuthenticatedSession()) { 8 navigate("/dashboard-extract", event); 9 } 10 else { 11 window.location.href = getAppSpaRedirectUrl('/register-business') ?? "https://app.refect.app/register-business"; 12 } 13}; 14function formatMarketingPrice(amount) { 15 return `${amount}â¬`; 16} 17export function initPricingToggle() { 18 const pill = document.getElementById('pricingTogglePill'); 19 const monthlyBtn = document.getElementById('pricingMonthlyBtn'); 20 const yearlyBtn = document.getElementById('pricingYearlyBtn'); 21 if (!pill || !monthlyBtn || !yearlyBtn) 22 return; 23 const starterPriceEl = document.getElementById('pricingStarterPrice'); 24 const starterDiscountEl = document.getElementById('pricingStarterDiscount'); 25 const proPriceEl = document.getElementById('pricingProPrice'); 26 const proDiscountEl = document.getElementById('pricingProDiscount'); 27 const autoPriceEl = document.getElementById('pricingAutoPrice'); 28 const autoDiscountEl = document.getElementById('pricingAutoDiscount'); 29 const locale = document.documentElement.lang || 'fr'; 30 const monthlySuffix = locale.startsWith('en') ? '/month' : '/mois'; 31 window.__pricingCurrency = 'eur'; 32 function positionPill(isMonthly) { 33 const activeBtn = isMonthly ? monthlyBtn : yearlyBtn; 34 pill.style.left = `${activeBtn.offsetLeft}px`; 35 pill.style.width = `${activeBtn.offsetWidth}px`; 36 } 37 function setToggle(isMonthly) { 38 positionPill(isMonthly); 39 monthlyBtn.className = 'relative z-10 px-4 py-1.5 text-sm font-medium rounded-full cursor-pointer transition-colors duration-300 ' + (isMonthly ? 'text-white' : 'text-gray-700'); 40 yearlyBtn.className = 'relative z-10 px-4 py-1.5 text-sm font-medium rounded-full cursor-pointer transition-colors duration-300 ' + (isMonthly ? 'text-gray-700' : 'text-white'); 41 const starterMonthly = 69; 42 const starterYearlyTotal = 708; 43 const proMonthly = 219; 44 const proYearlyTotal = 2148; 45 const autoMonthly = 539; 46 const autoYearlyTotal = 5388; 47 function renderPlan(priceEl, discountEl, monthly, yearlyTotal) { 48 const effectiveMonthly = Math.round(yearlyTotal / 12); 49 const savings = formatMarketingPrice(computeAnnualSavings(monthly, yearlyTotal)); 50 if (priceEl) { 51 priceEl.innerHTML = isMonthly 52 ? `${formatMarketingPrice(monthly)}<span class="text-base font-normal text-gray-600">${monthlySuffix}</span>` 53 : `${formatMarketingPrice(effectiveMonthly)}<span class="text-base font-normal text-gray-600">${monthlySuffix}</span>`; 54 } 55 if (discountEl) { 56 discountEl.innerHTML = isMonthly 57 ? `<span class="text-fuchsia-800 font-semibold">${formatAnnualSavingsHint(savings)}</span>` 58 : `<span class="text-fuchsia-800 font-semibold">${formatAnnualSavingsLabel(savings)}</span>`; 59 discountEl.classList.remove('invisible'); 60 } 61 } 62 renderPlan(starterPriceEl, starterDiscountEl, starterMonthly, starterYearlyTotal); 63 renderPlan(proPriceEl, proDiscountEl, proMonthly, proYearlyTotal); 64 renderPlan(autoPriceEl, autoDiscountEl, autoMonthly, autoYearlyTotal); 65 } 66 let isMonthlySelected = false; 67 setToggle(false); 68 monthlyBtn.addEventListener('click', () => { isMonthlySelected = true; setToggle(true); }); 69 yearlyBtn.addEventListener('click', () => { isMonthlySelected = false; setToggle(false); }); 70 window.addEventListener('resize', () => positionPill(isMonthlySelected)); 71 // Les libellés d'économie viennent de l'i18n : re-rendu si les traductions arrivent après. 72 document.addEventListener('nearby:localeChanged', () => setToggle(isMonthlySelected)); 73} 74export function bindLandingPricingBlocks() { 75 document.getElementById("joinLandingPricing")?.addEventListener("click", goToJoinOrDashboard); 76 document.getElementById("joinLandingStarter")?.addEventListener("click", goToJoinOrDashboard); 77 document.getElementById("joinLandingMensuel")?.addEventListener("click", goToJoinOrDashboard); 78 document.getElementById("joinLandingAnnuel")?.addEventListener("click", goToJoinOrDashboard); 79 document.getElementById("joinLandingAuto")?.addEventListener("click", goToJoinOrDashboard); 80 document.getElementById("contactLandingCTA")?.addEventListener("click", (e) => { 81 e.preventDefault(); 82 navigate("/contact", e); 83 }); 84 document.querySelectorAll(".nav-to-features").forEach(el => { 85 el.addEventListener("click", (e) => { 86 e.preventDefault(); 87 navigate("/features/claude-connector", e); 88 }); 89 }); 90}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.