diff --git a/hub/services/static/css/roi-calculator.css b/hub/services/static/css/roi-calculator.css index d441efe..d93efa5 100644 --- a/hub/services/static/css/roi-calculator.css +++ b/hub/services/static/css/roi-calculator.css @@ -495,4 +495,80 @@ .table th, .table td { padding: 0.5rem 0.25rem; } +} + +/* Monthly Breakdown Filter Controls */ +.breakdown-filters { + background: #f8f9fa; + border-radius: 6px; + padding: 1rem; + margin-bottom: 1rem; +} + +.breakdown-filters .form-check { + margin-bottom: 0.25rem; +} + +.breakdown-filters .form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd; +} + +.breakdown-filters .form-check-label { + cursor: pointer; + user-select: none; + font-size: 0.875rem; +} + +/* Responsive breakdown filters */ +@media (max-width: 768px) { + .breakdown-filters { + padding: 0.75rem; + } + + .breakdown-filters .d-flex { + flex-direction: column; + gap: 0.5rem !important; + } +} + +/* Enhanced sticky header for monthly breakdown table */ +.table-responsive { + position: relative; +} + +.table-responsive .sticky-top { + position: sticky; + top: 0; + z-index: 10; + background-color: #212529 !important; /* Ensure dark background stays */ +} + +.table-responsive .sticky-top th { + background-color: #212529 !important; + border-color: #454d55 !important; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +/* Ensure sticky header works in scrollable containers */ +.table-responsive[style*="max-height"] .sticky-top { + position: sticky; + top: 0; + z-index: 20; +} + +/* Additional styling for better visibility */ +.table-dark th { + font-weight: 600; + font-size: 0.875rem; + white-space: nowrap; + text-align: center; +} + +.table-dark th:first-child { + text-align: center; +} + +.table-dark th:nth-child(n+4) { + text-align: right; } \ No newline at end of file diff --git a/hub/services/static/js/roi-calculator/roi-calculator-app.js b/hub/services/static/js/roi-calculator/roi-calculator-app.js index 6c40b18..ba5281b 100644 --- a/hub/services/static/js/roi-calculator/roi-calculator-app.js +++ b/hub/services/static/js/roi-calculator/roi-calculator-app.js @@ -402,6 +402,16 @@ class ROICalculatorApp { // toggleInvestmentModel removed - both models are now calculated simultaneously + updateMonthlyBreakdownFilters() { + try { + if (this.uiManager) { + this.uiManager.updateMonthlyBreakdown(); + } + } catch (error) { + console.error('Error updating monthly breakdown filters:', error); + } + } + logout() { if (!confirm('Are you sure you want to logout?')) { return; diff --git a/hub/services/static/js/roi-calculator/ui-manager.js b/hub/services/static/js/roi-calculator/ui-manager.js index c31493c..cb0943e 100644 --- a/hub/services/static/js/roi-calculator/ui-manager.js +++ b/hub/services/static/js/roi-calculator/ui-manager.js @@ -131,12 +131,21 @@ class UIManager { tbody.innerHTML = ''; + // Get filter settings + const filters = this.getMonthlyBreakdownFilters(); + // Combine all monthly data and sort by month, then scenario, then model const allData = []; Object.keys(this.calculator.monthlyData).forEach(resultKey => { this.calculator.monthlyData[resultKey].forEach(monthData => { const model = resultKey.includes('_loan') ? 'loan' : 'direct'; const scenario = resultKey.replace('_direct', '').replace('_loan', ''); + + // Apply filters + if (!filters.models[model] || !filters.scenarios[scenario.toLowerCase()]) { + return; // Skip this entry if filtered out + } + allData.push({ ...monthData, model: model, @@ -176,6 +185,7 @@ class UIManager { ${data.totalInstances ? data.totalInstances.toLocaleString() : '0'} ${this.formatCurrencyDetailed(data.monthlyRevenue || 0)} ${this.formatCurrencyDetailed(data.cspRevenue || 0)} + ${this.formatCurrencyDetailed(data.servalaRevenue || 0)} ${this.formatCurrencyDetailed(data.netPosition || 0)} `; }); @@ -253,4 +263,27 @@ class UIManager { default: return '#6c757d'; } } + + getMonthlyBreakdownFilters() { + try { + return { + models: { + direct: document.getElementById('breakdown-direct-enabled')?.checked ?? true, + loan: document.getElementById('breakdown-loan-enabled')?.checked ?? true + }, + scenarios: { + conservative: document.getElementById('breakdown-conservative-enabled')?.checked ?? true, + moderate: document.getElementById('breakdown-moderate-enabled')?.checked ?? true, + aggressive: document.getElementById('breakdown-aggressive-enabled')?.checked ?? true + } + }; + } catch (error) { + console.error('Error getting monthly breakdown filters:', error); + // Return default filters if there's an error + return { + models: { direct: true, loan: true }, + scenarios: { conservative: true, moderate: true, aggressive: true } + }; + } + } } \ No newline at end of file diff --git a/hub/services/templates/calculator/csp_roi_calculator.html b/hub/services/templates/calculator/csp_roi_calculator.html index 7e56dd1..cc79b4c 100644 --- a/hub/services/templates/calculator/csp_roi_calculator.html +++ b/hub/services/templates/calculator/csp_roi_calculator.html @@ -36,6 +36,7 @@ function updateScenarioChurn(scenarioKey, churnRate) { window.ROICalculatorApp?. function updateScenarioPhase(scenarioKey, phaseIndex, newInstancesPerMonth) { window.ROICalculatorApp?.updateScenarioPhase(scenarioKey, phaseIndex, newInstancesPerMonth); } function resetAdvancedParameters() { window.ROICalculatorApp?.resetAdvancedParameters(); } function toggleScenario(scenarioKey) { window.ROICalculatorApp?.toggleScenario(scenarioKey); } +function updateMonthlyBreakdownFilters() { window.ROICalculatorApp?.updateMonthlyBreakdownFilters(); } function toggleCollapsible(elementId) { window.ROICalculatorApp?.toggleCollapsible(elementId); } function resetCalculator() { window.ROICalculatorApp?.resetCalculator(); } // toggleInvestmentModel function removed - both models calculated simultaneously @@ -392,12 +393,49 @@ document.addEventListener('DOMContentLoaded', function() {
Monthly Financial Breakdown
-
- - - This table shows month-by-month progression for all enabled scenarios and both investment models. - Use the scenario checkboxes above to filter results. - + + +
+
+ +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
@@ -409,6 +447,7 @@ document.addEventListener('DOMContentLoaded', function() { + diff --git a/hub/services/templates/calculator/roi_calculator_help.html b/hub/services/templates/calculator/roi_calculator_help.html index e79ccec..4544cd3 100644 --- a/hub/services/templates/calculator/roi_calculator_help.html +++ b/hub/services/templates/calculator/roi_calculator_help.html @@ -133,13 +133,13 @@ html {

Overview

-

The ROI Calculator helps you analyze potential returns from partnering with Servala through two distinct investment models:

+

The ROI Calculator provides simultaneous comparison of both investment models, showing real-time results for each scenario. You can instantly see how both models perform without switching between them.

Loan Model
-

3-7% Annual Returns

+

3-8% Annual Returns

Fixed interest lending with guaranteed monthly payments. Low risk, predictable returns.

@@ -160,21 +160,21 @@ html {

How It Works

You lend capital to Servala at a fixed interest rate, receiving guaranteed monthly payments regardless of business performance.

-

Key Features:

+

Key Features

  • Investment Range: CHF 100,000 - CHF 2,000,000
  • -
  • Interest Rates: Typically 3-7% annually
  • +
  • Interest Rates: 3-8% annually
  • Payment Schedule: Fixed monthly payments
  • Risk Level: Very low - contractually guaranteed
  • Break-even: Typically 12-18 months
-

Payment Calculation:

+

Payment Calculation

Monthly payments use standard amortization:

Monthly Payment = P × [r(1+r)^n] / [(1+r)^n - 1]

Where P = Principal, r = Monthly rate, n = Total payments

-

Best For:

+

Best For

  • CSPs prioritizing predictable, guaranteed returns
  • Limited capacity for active sales involvement
  • @@ -190,7 +190,7 @@ html {

    How It Works

    Invest directly in Servala's operations and earn returns through revenue sharing that scales with performance and investment size.

    -

    Progressive Scaling Benefits:

    +

    Progressive Scaling Benefits

Instances Monthly Revenue Your ShareServala Share Cumulative Net Position
@@ -224,7 +224,7 @@ html {
-

Grace Period Benefits:

+

Grace Period Benefits

Larger investments get longer periods of 100% revenue retention:

-

Performance Bonuses:

-

CSPs exceeding 110% of baseline performance receive up to 15% additional revenue share.

+

Performance Bonuses

+

CSPs exceeding 110% of baseline performance receive up to 15% additional revenue share. This is automatically calculated based on your actual vs. expected instance growth.

+ +

Performance Multiplier (Automatic)

+

This metric shows how your actual performance compares to baseline expectations:

+ +

This is calculated automatically based on your investment scaling and cannot be manually configured.

-

Best For:

+

Best For