frontend price calculator
This commit is contained in:
parent
4f9a39fd36
commit
475a4643fd
4 changed files with 617 additions and 64 deletions
|
@ -4,6 +4,11 @@
|
|||
|
||||
{% block title %}Managed {{ offering.service.name }} on {{ offering.cloud_provider.name }}{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script defer src="{% static "js/price-calculator.js" %}"></script>
|
||||
<link rel="stylesheet" type="text/css" href='{% static "css/price-calculator.css" %}'>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section bg-primary-subtle">
|
||||
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
|
||||
|
@ -152,76 +157,153 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Plans or Service Plans -->
|
||||
<!-- Price Calculator -->
|
||||
<div class="pt-24" id="plans" style="scroll-margin-top: 30px;">
|
||||
{% if offering.msp == "VS" and pricing_data_by_group_and_service_level %}
|
||||
<!-- Service Plans with Pricing Data -->
|
||||
<h3 class="fs-24 fw-semibold lh-1 mb-12">Service Plans</h3>
|
||||
<div class="accordion" id="servicePlansAccordion">
|
||||
{% for group_name, service_levels in pricing_data_by_group_and_service_level.items %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="heading{{ forloop.counter }}">
|
||||
<button class="accordion-button{% if not forloop.first %} collapsed{% endif %}" type="button" data-bs-toggle="collapse" data-bs-target="#collapse{{ forloop.counter }}" aria-expanded="{% if forloop.first %}true{% else %}false{% endif %}" aria-controls="collapse{{ forloop.counter }}">
|
||||
<strong>{{ group_name }}</strong>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapse{{ forloop.counter }}" class="accordion-collapse collapse{% if forloop.first %} show{% endif %}" aria-labelledby="heading{{ forloop.counter }}" data-bs-parent="#servicePlansAccordion">
|
||||
<div class="accordion-body">
|
||||
{% comment %} Display group description from first available plan {% endcomment %}
|
||||
{% for service_level, pricing_data in service_levels.items %}
|
||||
{% if pricing_data and forloop.first %}
|
||||
{% with pricing_data.0 as representative_plan %}
|
||||
{% if representative_plan.compute_plan_group_description %}
|
||||
<p class="text-muted mb-3">{{ representative_plan.compute_plan_group_description }}</p>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% if forloop.first %}
|
||||
{% comment %} Only show description for first service level {% endcomment %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- Interactive Price Calculator -->
|
||||
<h3 class="fs-24 fw-semibold lh-1 mb-12">Configure Your Plan</h3>
|
||||
<div class="bg-light rounded-4 p-4 mb-4">
|
||||
<div class="row">
|
||||
<!-- Calculator Controls -->
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title mb-4">Customize Your Configuration</h5>
|
||||
|
||||
{% for service_level, pricing_data in service_levels.items %}
|
||||
<div class="mb-4">
|
||||
<h4 class="mb-3 text-primary">{{ service_level }}</h4>
|
||||
{% if pricing_data %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Compute Plan</th>
|
||||
<th>vCPUs</th>
|
||||
<th>RAM (GB)</th>
|
||||
<th>Currency</th>
|
||||
<th>Compute Price</th>
|
||||
<th>Service Price</th>
|
||||
<th class="table-warning">Total Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in pricing_data %}
|
||||
<tr>
|
||||
<td>{{ row.compute_plan }}</td>
|
||||
<td>{{ row.vcpus }}</td>
|
||||
<td>{{ row.ram }}</td>
|
||||
<td>{{ row.currency }}</td>
|
||||
<td>{{ row.compute_plan_price|floatformat:2 }}</td>
|
||||
<td>{{ row.sla_price|floatformat:2 }}</td>
|
||||
<td class="table-warning fw-bold">{{ row.final_price|floatformat:2 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">No pricing data available for {{ service_level }}.</p>
|
||||
{% endif %}
|
||||
<!-- CPU Slider -->
|
||||
<div class="mb-4">
|
||||
<label for="cpuRange" class="form-label d-flex justify-content-between">
|
||||
<span>vCPUs</span>
|
||||
<span class="fw-bold" id="cpuValue">2</span>
|
||||
</label>
|
||||
<input type="range" class="form-range" id="cpuRange" min="1" max="32" value="2" step="1">
|
||||
<div class="d-flex justify-content-between text-muted small">
|
||||
<span>1</span>
|
||||
<span>32</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Memory Slider -->
|
||||
<div class="mb-4">
|
||||
<label for="memoryRange" class="form-label d-flex justify-content-between">
|
||||
<span>Memory (GB)</span>
|
||||
<span class="fw-bold" id="memoryValue">4</span>
|
||||
</label>
|
||||
<input type="range" class="form-range" id="memoryRange" min="1" max="128" value="4" step="1">
|
||||
<div class="d-flex justify-content-between text-muted small">
|
||||
<span>1 GB</span>
|
||||
<span>128 GB</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Storage Slider -->
|
||||
<div class="mb-4">
|
||||
<label for="storageRange" class="form-label d-flex justify-content-between">
|
||||
<span>Storage (GB)</span>
|
||||
<span class="fw-bold" id="storageValue">20</span>
|
||||
</label>
|
||||
<input type="range" class="form-range" id="storageRange" min="10" max="1000" value="20" step="10">
|
||||
<div class="d-flex justify-content-between text-muted small">
|
||||
<span>10 GB</span>
|
||||
<span>1000 GB</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Service Level Selection -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label">Service Level</label>
|
||||
<div class="btn-group w-100" role="group" id="serviceLevelGroup">
|
||||
<input type="radio" class="btn-check" name="serviceLevel" id="serviceLevelBestEffort" value="Best Effort" checked>
|
||||
<label class="btn btn-outline-primary" for="serviceLevelBestEffort">Best Effort</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="serviceLevel" id="serviceLevelGuaranteed" value="Guaranteed">
|
||||
<label class="btn btn-outline-primary" for="serviceLevelGuaranteed">Guaranteed Availability</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Direct Plan Selection -->
|
||||
<div class="mb-4">
|
||||
<label for="planSelect" class="form-label">Or choose a specific plan</label>
|
||||
<select class="form-select" id="planSelect">
|
||||
<option value="">Auto-select best matching plan</option>
|
||||
</select>
|
||||
<small class="form-text text-muted">Selecting a plan will override the slider configuration</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Results Panel -->
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card h-100 border-primary">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-primary mb-4">Your Configuration</h5>
|
||||
|
||||
<!-- Plan Match Status -->
|
||||
<div id="planMatchStatus" class="alert alert-info mb-3">
|
||||
<i class="bi bi-info-circle me-2"></i>
|
||||
<span>Finding best matching plan...</span>
|
||||
</div>
|
||||
|
||||
<!-- Selected Plan Details -->
|
||||
<div id="selectedPlanDetails" style="display: none;">
|
||||
<div class="mb-3">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<span class="badge me-2" id="planGroup"></span>
|
||||
<strong id="planName"></strong>
|
||||
</div>
|
||||
<small class="text-muted" id="planDescription"></small>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-6">
|
||||
<small class="text-muted">vCPUs</small>
|
||||
<div class="fw-bold" id="planCpus"></div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<small class="text-muted">Memory</small>
|
||||
<div class="fw-bold" id="planMemory"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pricing Breakdown -->
|
||||
<div class="border-top pt-3">
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span>Compute Plan</span>
|
||||
<span class="fw-bold">CHF <span id="computePrice">0.00</span></span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span>Service Price</span>
|
||||
<span class="fw-bold">CHF <span id="servicePrice">0.00</span></span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span>Storage (<span id="storageAmount">20</span> GB)</span>
|
||||
<span class="fw-bold">CHF <span id="storagePrice">0.00</span></span>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="fs-5 fw-bold">Total Monthly Price</span>
|
||||
<span class="fs-4 fw-bold text-primary">CHF <span id="totalPrice">0.00</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No Match Found -->
|
||||
<div id="noMatchFound" style="display: none;" class="alert alert-warning">
|
||||
<i class="bi bi-exclamation-triangle me-2"></i>
|
||||
No matching plan found for your requirements. Please adjust your configuration.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order Button -->
|
||||
<div class="text-center mt-4">
|
||||
<a href="#interest" class="btn btn-primary btn-lg px-5 py-3 fw-semibold">
|
||||
<i class="bi bi-cart me-2"></i>Order This Configuration
|
||||
</a>
|
||||
</div>
|
||||
{% elif offering.plans.all %}
|
||||
<!-- Traditional Plans -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue