waiver admin section,
This commit is contained in:
@@ -1077,6 +1077,16 @@
|
||||
.sl-otf-waived .otf-amt { text-decoration: line-through; text-decoration-color: var(--green); }
|
||||
.sl-otf-waived .otf-waived-label { text-decoration: none; font-weight: 600; letter-spacing: 0.06em; }
|
||||
|
||||
/* ── ADMIN FEE WAIVED display */
|
||||
.admin-fee-header { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
|
||||
.admin-fee-waive-toggle { margin-left: auto; }
|
||||
.admin-fee-strike { text-decoration: line-through; color: var(--muted); text-decoration-color: var(--muted); }
|
||||
.admin-fee-waived-badge { font-family: 'DM Mono', monospace; font-size: 12px; font-weight: 700; letter-spacing: 0.08em; color: var(--green); background: rgba(33,112,69,0.12); border: 1px solid rgba(33,112,69,0.28); border-radius: 4px; padding: 2px 7px; vertical-align: middle; }
|
||||
.sl-admin-waived > span:first-child { text-decoration: line-through; text-decoration-color: var(--muted); color: var(--muted); }
|
||||
.admin-waive-savings { display: flex; align-items: center; gap: 7px; font-family: 'DM Mono', monospace; font-size: 12px; letter-spacing: 0.04em; color: var(--green); background: rgba(33,112,69,0.08); border: 1px solid rgba(33,112,69,0.22); border-radius: 6px; padding: 8px 12px; margin-top: 10px; margin-bottom: 4px; }
|
||||
.admin-waive-savings.hidden { display: none; }
|
||||
#adminWaivedAmt { font-weight: 700; }
|
||||
|
||||
/* Nudge banner internal flex rows */
|
||||
.nudge-header-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
|
||||
.nudge-nav-group { display: flex; gap: 4px; }
|
||||
|
||||
@@ -308,6 +308,11 @@
|
||||
<div class="admin-fee-header">
|
||||
<span class="admin-fee-title">Site Admin Fee</span>
|
||||
<span id="adminFeeDisplay" class="admin-fee-val">$150/mo</span>
|
||||
<label class="qs-toggle-row admin-fee-waive-toggle">
|
||||
<input type="checkbox" id="adminWaived" onchange="update()">
|
||||
<span class="qs-switch"></span>
|
||||
<span class="qs-toggle-label">Waive</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="admin-fee-sub">Calculated from services below · floor $150/mo</div>
|
||||
|
||||
@@ -329,6 +334,11 @@
|
||||
<tr class="fee-total"><td>Total Admin Fee</td><td id="fb-total">—</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="admin-waive-savings hidden" id="adminWaivedSavings">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="11" height="11" fill="currentColor"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>
|
||||
Site admin fee waived — saving <span id="adminWaivedAmt">$0</span>/mo on this quote
|
||||
</div>
|
||||
|
||||
<!-- What's Covered collapsible -->
|
||||
<div class="collapsible-header collapsible-header--mt16" onclick="toggleCollapsible('adminCovered')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('adminCovered');event.preventDefault();}">
|
||||
<span class="collapsible-toggle" id="adminCovered-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||||
|
||||
@@ -121,6 +121,7 @@ function calcQuote() {
|
||||
const hstEnabled = document.getElementById('hstToggle')?.checked || false;
|
||||
const oneTimeFee = parseFloat(document.getElementById('oneTimeFee')?.value) || 0;
|
||||
const ztActive = addZT || ztSeats > 0;
|
||||
const adminWaived = document.getElementById('adminWaived')?.checked || false;
|
||||
|
||||
const VOIP_RATES = { basic: VOIP_RATE_BASIC, standard: VOIP_RATE_STANDARD, premium: VOIP_RATE_PREMIUM };
|
||||
const CONTRACT_DISCOUNT = { 'm2m': DISCOUNT_M2M, '12mo': DISCOUNT_12MO, '24mo': DISCOUNT_24MO };
|
||||
@@ -145,7 +146,8 @@ function calcQuote() {
|
||||
const baseSubtotal = userBase + endpointBase + serverBase;
|
||||
const siteAdminBase = Math.max(ADMIN_FEE_FLOOR, ADMIN_FEE_MINIMUM - baseSubtotal);
|
||||
const admin1PWM = addPWM ? Math.round(userPWM * ADMIN_1PWM_PCT) : 0;
|
||||
const adminFeeNet = siteAdminBase + (ztActive ? ADMIN_FEE_ZT : 0) + admin1PWM;
|
||||
const adminFeeNet = siteAdminBase + (ztActive ? ADMIN_FEE_ZT : 0) + admin1PWM;
|
||||
const adminFeeEffective = adminWaived ? 0 : adminFeeNet;
|
||||
|
||||
const ztNetSeats = ztSeats * ZT_SEAT_RATE;
|
||||
const ztNetRouters = ztRouters * ZT_ROUTER_RATE;
|
||||
@@ -157,7 +159,7 @@ function calcQuote() {
|
||||
const voipFaxAmt = addVoipFax ? VOIP_FAX_RATE : 0;
|
||||
const voipTotal = voipSeatsAmt + voipPhoneAmt + voipFaxAmt;
|
||||
|
||||
const MRR = userTotal + endpointTotal + adminFeeNet + ztNetTotal + voipTotal;
|
||||
const MRR = userTotal + endpointTotal + adminFeeEffective + ztNetTotal + voipTotal;
|
||||
const annual = MRR * 12;
|
||||
const perUserAllin = users > 0 ? MRR / users : 0;
|
||||
|
||||
@@ -258,7 +260,12 @@ function update() {
|
||||
});
|
||||
|
||||
// Admin Fee
|
||||
getEl('adminFeeDisplay').textContent = fmt(adminFeeNet) + '/mo';
|
||||
if (adminWaived) {
|
||||
getEl('adminFeeDisplay').innerHTML =
|
||||
`<span class="admin-fee-strike">${fmt(adminFeeNet)}/mo</span> <span class="admin-fee-waived-badge">WAIVED</span>`;
|
||||
} else {
|
||||
getEl('adminFeeDisplay').textContent = fmt(adminFeeNet) + '/mo';
|
||||
}
|
||||
const fillPct = Math.min(100, Math.max(0, (baseSubtotal / ADMIN_FEE_MINIMUM) * 100));
|
||||
getEl('floorBar').style.width = fillPct + '%';
|
||||
getEl('floorProgress').textContent = fmt(baseSubtotal) + ' / ' + fmt(ADMIN_FEE_MINIMUM);
|
||||
@@ -272,7 +279,19 @@ function update() {
|
||||
getEl('fb-zt-row').classList.toggle('hidden', !ztActive);
|
||||
getEl('fb-pwm-row').classList.toggle('hidden', !addPWM);
|
||||
getEl('fb-pwm').textContent = '+' + fmt(admin1PWM);
|
||||
getEl('fb-total').textContent = fmt(adminFeeNet);
|
||||
if (adminWaived) {
|
||||
getEl('fb-total').innerHTML =
|
||||
`<span class="admin-fee-strike">${fmt(adminFeeNet)}</span> <span class="admin-fee-waived-badge">WAIVED</span>`;
|
||||
} else {
|
||||
getEl('fb-total').textContent = fmt(adminFeeNet);
|
||||
}
|
||||
// Savings callout below fee table
|
||||
const adminWaivedSavingsEl = document.getElementById('adminWaivedSavings');
|
||||
if (adminWaivedSavingsEl) {
|
||||
adminWaivedSavingsEl.classList.toggle('hidden', !adminWaived || adminFeeNet === 0);
|
||||
const awAmt = document.getElementById('adminWaivedAmt');
|
||||
if (awAmt) awAmt.textContent = fmt(adminFeeNet);
|
||||
}
|
||||
|
||||
// Sidebar lines
|
||||
const show = (id, val) => {
|
||||
@@ -309,7 +328,16 @@ function update() {
|
||||
if (ztNetTotal > 0) getEl('sl-zt-val').textContent = fmt(ztNetTotal);
|
||||
show('sl-voip', voipTotal > 0);
|
||||
if (voipTotal > 0) getEl('sl-voip-val').textContent = fmt(voipTotal);
|
||||
getEl('sl-admin-val').textContent = fmt(adminFeeNet);
|
||||
const slAdminEl = getEl('sl-admin');
|
||||
const slAdminValEl = getEl('sl-admin-val');
|
||||
if (adminWaived) {
|
||||
slAdminEl?.classList.add('sl-admin-waived');
|
||||
if (slAdminValEl) slAdminValEl.innerHTML =
|
||||
`<span class="otf-amt">${fmt(adminFeeNet)}</span> <span class="otf-waived-label">WAIVED</span>`;
|
||||
} else {
|
||||
slAdminEl?.classList.remove('sl-admin-waived');
|
||||
if (slAdminValEl) slAdminValEl.textContent = fmt(adminFeeNet);
|
||||
}
|
||||
|
||||
// MRR + totals — show effective MRR (after term discount) as the headline number
|
||||
getEl('mrrDisplay').textContent = fmt(effectiveMrr);
|
||||
@@ -518,7 +546,7 @@ function updateSectionSummaries(q) {
|
||||
el.style.display = show ? 'inline-block' : 'none';
|
||||
};
|
||||
|
||||
setSummary('sec01-summary', fmt(q.adminFeeNet) + '/mo');
|
||||
setSummary('sec01-summary', q.adminWaived ? 'WAIVED' : fmt(q.adminFeeNet) + '/mo');
|
||||
setSummary('sec02-summary', q.users > 0 ? `${q.users} user${q.users !== 1 ? 's' : ''} · ${fmt(q.userTotal)}/mo` : '');
|
||||
setSummary('sec03-summary', q.endpoints > 0 ? `${q.endpoints} endpoint${q.endpoints !== 1 ? 's' : ''} · ${fmt(q.endpointTotal - q.serverBase)}/mo` : '');
|
||||
setSummary('sec04-summary', q.servers > 0 ? `${q.servers} server${q.servers !== 1 ? 's' : ''} · ${fmt(q.serverBase)}/mo` : '');
|
||||
|
||||
Reference in New Issue
Block a user