tweak config section layout

This commit is contained in:
Tobias Brunner 2025-07-23 14:35:15 +02:00
parent 491dbacda4
commit e4ba1378b6
Signed by: tobru
SSH key fingerprint: SHA256:kOXg1R6c11XW3/Pt9dbLdQvOJGFAy+B2K6v6PtRWBGQ
3 changed files with 394 additions and 115 deletions

View file

@ -394,15 +394,171 @@
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.main-config-section .form-label {
color: #495057;
font-weight: 600;
.main-config-fields {
padding: 1.5rem;
background: #ffffff;
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
border: 1px solid #e9ecef;
}
.main-config-section .input-group-text {
background-color: #e9ecef;
border-color: #ced4da;
font-weight: 500;
.main-config-fields .form-label {
color: #2c3e50;
font-weight: 600;
font-size: 1.1rem;
margin-bottom: 0.75rem;
}
.main-config-fields .input-group-text {
background-color: #f8f9fa;
border-color: #dee2e6;
font-weight: 600;
color: #495057;
}
.main-config-fields .form-control {
border-color: #dee2e6;
font-size: 1.1rem;
}
.main-config-fields .form-control:focus {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.15);
}
.main-config-fields .form-select {
border-color: #dee2e6;
font-size: 1.1rem;
}
.main-config-fields .form-select:focus {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.15);
}
/* Results Panel Styling */
.results-panel {
position: sticky;
top: 1rem;
}
.results-panel .card {
border-radius: 12px;
overflow: hidden;
background: #ffffff;
}
.results-panel .card-header {
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
border-bottom: none;
padding: 1.25rem;
}
.results-panel .card-body {
padding: 2rem 1.5rem;
min-height: 400px;
}
.result-item {
transition: all 0.3s ease;
padding: 0.5rem;
border-radius: 8px;
}
.result-item:hover {
background: rgba(0, 123, 255, 0.02);
transform: translateX(5px);
}
.result-icon {
flex-shrink: 0;
font-size: 1.2rem;
transition: all 0.3s ease;
}
.result-item:hover .result-icon {
transform: scale(1.1);
}
.result-metrics {
border: 1px solid #dee2e6;
transition: all 0.3s ease;
}
.result-item:hover .result-metrics {
border-color: #007bff;
background: rgba(248, 249, 250, 0.8) !important;
}
/* Enhanced form styling */
.form-check-lg .form-check-input {
width: 1.5rem;
height: 1.5rem;
margin-top: 0.125rem;
}
.form-check-lg .form-check-label {
font-size: 1.1rem;
margin-left: 0.5rem;
}
/* Enhanced range sliders */
.form-range {
height: 8px;
background: linear-gradient(to right, #e9ecef 0%, #dee2e6 100%);
border-radius: 4px;
margin: 1rem 0 0.5rem 0;
}
.form-range::-webkit-slider-thumb {
width: 24px;
height: 24px;
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
border: 3px solid #ffffff;
border-radius: 50%;
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.3);
cursor: pointer;
transition: all 0.2s ease;
}
.form-range::-webkit-slider-thumb:hover {
transform: scale(1.1);
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.4);
}
.form-range::-moz-range-thumb {
width: 24px;
height: 24px;
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
border: 3px solid #ffffff;
border-radius: 50%;
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.3);
cursor: pointer;
transition: all 0.2s ease;
}
.form-range::-moz-range-thumb:hover {
transform: scale(1.1);
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.4);
}
/* Button styling improvements */
.btn-lg {
padding: 0.75rem 1.5rem;
font-size: 1.1rem;
font-weight: 600;
border-radius: 8px;
transition: all 0.3s ease;
}
.btn-outline-info:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(23, 162, 184, 0.3);
}
.btn-outline-secondary:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(108, 117, 125, 0.3);
}
/* Advanced controls styling */
@ -482,10 +638,70 @@
}
/* Responsive improvements */
@media (max-width: 991px) {
.results-panel {
position: static;
margin-top: 2rem;
}
.results-panel .card-body {
min-height: auto;
padding: 1.5rem;
}
.result-item {
margin-bottom: 1.5rem;
}
.result-item:last-child {
margin-bottom: 0;
}
}
@media (max-width: 768px) {
.main-config-section {
.main-config-fields {
padding: 1rem;
margin: 0 -15px;
border-radius: 0;
border-left: none;
border-right: none;
}
.main-config-fields .form-label {
font-size: 1rem;
}
.main-config-fields .form-control,
.main-config-fields .form-select {
font-size: 1rem;
}
.btn-lg {
font-size: 1rem;
padding: 0.6rem 1.2rem;
}
.form-check-lg .form-check-input {
width: 1.25rem;
height: 1.25rem;
}
.form-check-lg .form-check-label {
font-size: 1rem;
}
.results-panel .card-header {
padding: 1rem;
}
.results-panel .card-body {
padding: 1rem;
}
.result-icon {
width: 35px !important;
height: 35px !important;
font-size: 1rem;
}
.advanced-controls-section .card {
@ -497,6 +713,34 @@
}
}
@media (max-width: 576px) {
.d-flex.gap-3.flex-wrap {
flex-direction: column;
gap: 0.75rem !important;
}
.btn-lg {
width: 100%;
justify-content: center;
}
.form-check-lg {
margin-bottom: 0.75rem;
}
.results-panel .card-body {
padding: 0.75rem;
}
.result-metrics .row {
text-align: center;
}
.result-metrics .col-6 {
margin-bottom: 0.5rem;
}
}
/* Model comparison box */
.model-comparison-box {
border: 1px solid #dee2e6;

View file

@ -127,117 +127,152 @@ document.addEventListener('DOMContentLoaded', function() {
<!-- Main Configuration Section -->
<div class="py-4">
<!-- Investment & Timeframe Row -->
<div class="row mb-4">
<!-- Investment Amount -->
<div class="col-lg-4 col-md-6 mb-3">
<label class="form-label fw-semibold mb-2">Initial Investment</label>
<div class="input-group">
<span class="input-group-text">CHF</span>
<input type="text" class="form-control" id="investment-amount"
data-value="500000" value="500,000"
oninput="handleInvestmentAmountInput(this)"
onchange="updateCalculations()">
</div>
<input type="range" class="form-range mt-2" id="investment-slider"
min="100000" max="2000000" step="50000" value="500000"
onchange="updateInvestmentAmount(this.value)">
<div class="d-flex justify-content-between">
<small class="text-muted">CHF 100K</small>
<small class="text-muted">CHF 2M</small>
</div>
</div>
<!-- Timeframe -->
<div class="col-lg-2 col-md-3 mb-3">
<label class="form-label fw-semibold mb-2">Analysis Period</label>
<select class="form-select" id="timeframe" onchange="updateCalculations()">
<option value="1">1 Year</option>
<option value="2">2 Years</option>
<option value="3" selected>3 Years</option>
<option value="4">4 Years</option>
<option value="5">5 Years</option>
</select>
</div>
<!-- Service Revenue -->
<div class="col-lg-3 col-md-6 mb-3">
<label class="form-label fw-semibold mb-2">Service Revenue per Instance</label>
<div class="input-group">
<input type="number" class="form-control" id="revenue-per-instance"
min="20" max="200" step="5" value="50" onchange="updateCalculations()">
<span class="input-group-text">CHF/month</span>
</div>
<input type="range" class="form-range mt-2" id="revenue-slider"
min="20" max="200" step="5" value="50"
onchange="updateRevenuePerInstance(this.value)">
<div class="d-flex justify-content-between">
<small class="text-muted">CHF 20</small>
<small class="text-muted">CHF 200</small>
</div>
</div>
<!-- Actions -->
<div class="col-lg-3 col-md-3 mb-3 d-flex align-items-end">
<div class="d-flex gap-2 w-100">
<button class="btn btn-outline-info" type="button" onclick="toggleAdvancedControls()" id="advancedToggleBtn">
<i class="bi bi-gear"></i> Advanced Settings
</button>
<a href="{% url 'services:roi_calculator_help' %}" class="btn btn-outline-secondary" target="_blank">
<i class="bi bi-question-circle"></i> Help
</a>
</div>
</div>
</div>
<!-- Scenarios & Results Row -->
<div class="row">
<!-- Growth Scenarios -->
<div class="col-lg-6 mb-3">
<label class="form-label fw-semibold mb-2">Growth Scenarios</label>
<div class="d-flex gap-4 flex-wrap">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="conservative-enabled" checked onchange="toggleScenario('conservative')">
<label class="form-check-label fw-medium" for="conservative-enabled" data-bs-toggle="tooltip" title="Conservative: 2% churn, steady growth">
<span class="text-success fs-5"></span> Conservative
</label>
<!-- Left Column: Configuration Fields -->
<div class="col-lg-8 col-xl-7">
<div class="main-config-fields">
<!-- Investment Amount -->
<div class="mb-4">
<label class="form-label fw-semibold mb-2">Initial Investment</label>
<div class="input-group input-group-lg">
<span class="input-group-text">CHF</span>
<input type="text" class="form-control" id="investment-amount"
data-value="500000" value="500,000"
oninput="handleInvestmentAmountInput(this)"
onchange="updateCalculations()">
</div>
<input type="range" class="form-range mt-3" id="investment-slider"
min="100000" max="2000000" step="50000" value="500000"
onchange="updateInvestmentAmount(this.value)">
<div class="d-flex justify-content-between mt-1">
<small class="text-muted">CHF 100K</small>
<small class="text-muted">CHF 2M</small>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="moderate-enabled" checked onchange="toggleScenario('moderate')">
<label class="form-check-label fw-medium" for="moderate-enabled" data-bs-toggle="tooltip" title="Moderate: 3% churn, balanced growth">
<span class="text-warning fs-5"></span> Moderate
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="aggressive-enabled" checked onchange="toggleScenario('aggressive')">
<label class="form-check-label fw-medium" for="aggressive-enabled" data-bs-toggle="tooltip" title="Aggressive: 5% churn, rapid growth">
<span class="text-danger fs-5"></span> Aggressive
</label>
</div>
</div>
</div>
<!-- Model Results -->
<div class="col-lg-6 mb-3">
<label class="form-label fw-semibold mb-2">Real-Time Results</label>
<div class="row g-2">
<div class="col-6">
<div class="card h-100">
<div class="card-body text-center p-3">
<div class="text-success fw-bold mb-2">Direct Investment</div>
<div class="h5 mb-1" id="net-position-direct">CHF 0</div>
<div class="text-primary fw-bold" id="roi-percentage-direct">0%</div>
<small class="text-muted">Net Profit / ROI</small>
<!-- Analysis Period & Service Revenue Row -->
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label fw-semibold mb-2">Analysis Period</label>
<select class="form-select form-select-lg" id="timeframe" onchange="updateCalculations()">
<option value="1">1 Year</option>
<option value="2">2 Years</option>
<option value="3" selected>3 Years</option>
<option value="4">4 Years</option>
<option value="5">5 Years</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold mb-2">Service Revenue per Instance</label>
<div class="input-group input-group-lg">
<input type="number" class="form-control" id="revenue-per-instance"
min="20" max="200" step="5" value="50" onchange="updateCalculations()">
<span class="input-group-text">CHF/month</span>
</div>
<input type="range" class="form-range mt-3" id="revenue-slider"
min="20" max="200" step="5" value="50"
onchange="updateRevenuePerInstance(this.value)">
<div class="d-flex justify-content-between mt-1">
<small class="text-muted">CHF 20</small>
<small class="text-muted">CHF 200</small>
</div>
</div>
</div>
<div class="col-6">
<div class="card h-100">
<div class="card-body text-center p-3">
<div class="text-warning fw-bold mb-2">Loan Model</div>
<div class="h5 mb-1" id="net-position-loan">CHF 0</div>
<div class="text-primary fw-bold" id="roi-percentage-loan">0%</div>
<small class="text-muted">Net Profit / ROI</small>
<!-- Growth Scenarios -->
<div class="mb-4">
<label class="form-label fw-semibold mb-3">Growth Scenarios</label>
<div class="d-flex gap-4 flex-wrap">
<div class="form-check form-check-lg">
<input class="form-check-input" type="checkbox" id="conservative-enabled" checked onchange="toggleScenario('conservative')">
<label class="form-check-label fw-medium" for="conservative-enabled" data-bs-toggle="tooltip" title="Conservative: 2% churn, steady growth">
<span class="text-success fs-4"></span> Conservative
</label>
</div>
<div class="form-check form-check-lg">
<input class="form-check-input" type="checkbox" id="moderate-enabled" checked onchange="toggleScenario('moderate')">
<label class="form-check-label fw-medium" for="moderate-enabled" data-bs-toggle="tooltip" title="Moderate: 3% churn, balanced growth">
<span class="text-warning fs-4"></span> Moderate
</label>
</div>
<div class="form-check form-check-lg">
<input class="form-check-input" type="checkbox" id="aggressive-enabled" checked onchange="toggleScenario('aggressive')">
<label class="form-check-label fw-medium" for="aggressive-enabled" data-bs-toggle="tooltip" title="Aggressive: 5% churn, rapid growth">
<span class="text-danger fs-4"></span> Aggressive
</label>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="d-flex gap-3 flex-wrap">
<button class="btn btn-outline-info btn-lg" type="button" onclick="toggleAdvancedControls()" id="advancedToggleBtn">
<i class="bi bi-gear"></i> Advanced Settings
</button>
<a href="{% url 'services:roi_calculator_help' %}" class="btn btn-outline-secondary btn-lg" target="_blank">
<i class="bi bi-question-circle"></i> Help
</a>
</div>
</div>
</div>
<!-- Right Column: Real-Time Results -->
<div class="col-lg-4 col-xl-5">
<div class="results-panel h-100">
<div class="card h-100 border-0 shadow">
<div class="card-header bg-primary text-white">
<h5 class="mb-0"><i class="bi bi-graph-up"></i> Real-Time Results</h5>
<small class="opacity-75">Live calculations based on your parameters</small>
</div>
<div class="card-body d-flex flex-column justify-content-center">
<!-- Direct Investment Results -->
<div class="result-item mb-4">
<div class="d-flex align-items-center mb-2">
<div class="result-icon bg-success text-white rounded-circle me-3 d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-rocket"></i>
</div>
<div>
<h6 class="mb-0 text-success fw-bold">Direct Investment</h6>
<small class="text-muted">Performance-based returns</small>
</div>
</div>
<div class="result-metrics bg-light rounded p-3">
<div class="row text-center">
<div class="col-6">
<div class="h4 mb-1 text-success fw-bold" id="net-position-direct">CHF 0</div>
<small class="text-muted">Net Profit</small>
</div>
<div class="col-6">
<div class="h4 mb-1 text-primary fw-bold" id="roi-percentage-direct">0%</div>
<small class="text-muted">Total ROI</small>
</div>
</div>
</div>
</div>
<!-- Loan Model Results -->
<div class="result-item">
<div class="d-flex align-items-center mb-2">
<div class="result-icon bg-warning text-dark rounded-circle me-3 d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-bank"></i>
</div>
<div>
<h6 class="mb-0 text-warning fw-bold">Loan Model</h6>
<small class="text-muted">Fixed guaranteed returns</small>
</div>
</div>
<div class="result-metrics bg-light rounded p-3">
<div class="row text-center">
<div class="col-6">
<div class="h4 mb-1 text-success fw-bold" id="net-position-loan">CHF 0</div>
<small class="text-muted">Net Profit</small>
</div>
<div class="col-6">
<div class="h4 mb-1 text-primary fw-bold" id="roi-percentage-loan">0%</div>
<small class="text-muted">Total ROI</small>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -103,7 +103,7 @@ html {
<i class="bi bi-lightbulb me-2"></i>Overview
</a>
<a class="list-group-item list-group-item-action" href="#loan-model">
<i class="bi bi-bank me-2"></i>Loan Model (3-7%)
<i class="bi bi-bank me-2"></i>Loan Model (3-8%)
</a>
<a class="list-group-item list-group-item-action" href="#direct-model">
<i class="bi bi-rocket me-2"></i>Direct Investment (15-40%)