refactor all the things

This commit is contained in:
Tobias Brunner 2025-01-28 13:55:43 +01:00
parent 8ed39690f1
commit bb5cb708bd
No known key found for this signature in database
36 changed files with 1563 additions and 931 deletions

View file

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Servala - The Cloud Native Services Hub</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<link rel="stylesheet" href='{% static "css/bootstrap-icons.min.css" %}'>
<link rel="stylesheet" type="text/css" href='{% static "css/bootstrap.min.css" %}'>
<style>
.rich-text-content {
@ -26,7 +26,30 @@
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{% url 'services:service_list' %}">Servala - The Cloud Native Services Hub</a>
<a class="navbar-brand" href="{% url 'services:service_list' %}">Servala</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.view_name == 'services:service_list' %}active{% endif %}"
href="{% url 'services:service_list' %}">Services</a>
</li>
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.view_name == 'services:offering_list' %}active{% endif %}"
href="{% url 'services:offering_list' %}">Service Offerings</a>
</li>
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.view_name == 'services:provider_list' %}active{% endif %}"
href="{% url 'services:provider_list' %}">Cloud Providers</a>
</li>
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.view_name == 'services:partner_list' %}active{% endif %}"
href="{% url 'services:partner_list' %}">Consulting Partners</a>
</li>
</ul>
</div>
</div>
</nav>
@ -35,6 +58,6 @@
{% endblock %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
</body>
</html>

View file

@ -9,16 +9,28 @@
<div class="mb-4">
<h5>Service Details</h5>
<p><strong>Provider:</strong> {{ service.cloud_provider.name }}</p>
<p><strong>Plan:</strong> {{ selected_plan.name }}</p>
{% if selected_offering %}
<p><strong>Provider:</strong> {{ selected_offering.cloud_provider.name }}</p>
{% endif %}
{% if selected_plan %}
<p><strong>Plan:</strong> {{ selected_plan.name }}</p>
{% if selected_plan.prices.exists %}
<p><strong>Pricing:</strong></p>
<ul class="list-unstyled">
{% for price in selected_plan.prices.all %}
<li>{{ price.currency.symbol }}{{ price.price }} {{ price.currency.code }} per {{ price.term.name }}</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
</div>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="post">
@ -28,9 +40,9 @@
<label for="{{ form.name.id_for_label }}" class="form-label">Name</label>
{{ form.name }}
{% if form.name.errors %}
<div class="invalid-feedback d-block">
{{ form.name.errors }}
</div>
<div class="invalid-feedback d-block">
{{ form.name.errors }}
</div>
{% endif %}
</div>
@ -38,9 +50,9 @@
<label for="{{ form.company.id_for_label }}" class="form-label">Company</label>
{{ form.company }}
{% if form.company.errors %}
<div class="invalid-feedback d-block">
{{ form.company.errors }}
</div>
<div class="invalid-feedback d-block">
{{ form.company.errors }}
</div>
{% endif %}
</div>
@ -48,9 +60,9 @@
<label for="{{ form.email.id_for_label }}" class="form-label">Email</label>
{{ form.email }}
{% if form.email.errors %}
<div class="invalid-feedback d-block">
{{ form.email.errors }}
</div>
<div class="invalid-feedback d-block">
{{ form.email.errors }}
</div>
{% endif %}
</div>
@ -58,9 +70,9 @@
<label for="{{ form.phone.id_for_label }}" class="form-label">Phone</label>
{{ form.phone }}
{% if form.phone.errors %}
<div class="invalid-feedback d-block">
{{ form.phone.errors }}
</div>
<div class="invalid-feedback d-block">
{{ form.phone.errors }}
</div>
{% endif %}
</div>

View file

@ -0,0 +1,87 @@
{% extends 'services/base.html' %}
{% block content %}
<div class="card mb-4">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-4">
<div class="d-flex align-items-start">
{% if offering.service.logo %}
<img src="{{ offering.service.logo.url }}" alt="{{ offering.service.name }} logo" class="me-4"
style="max-height: 120px; max-width: 240px; object-fit: contain;">
{% endif %}
<div>
<h2 class="card-title mb-2">{{ offering.service.name }}</h2>
<h4 class="text-muted">
on
<a href="{{ offering.cloud_provider.get_absolute_url }}" class="text-decoration-none">
{{ offering.cloud_provider.name }}
</a>
</h4>
</div>
</div>
{% if offering.cloud_provider.logo %}
<img src="{{ offering.cloud_provider.logo.url }}"
alt="{{ offering.cloud_provider.name }} logo"
style="max-height: 80px; max-width: 160px; object-fit: contain;">
{% endif %}
</div>
<div class="rich-text-content mb-4">
{{ offering.description|safe }}
</div>
</div>
</div>
<!-- Plans -->
<div class="card mb-4">
<div class="card-body">
<h3 class="mb-4">Available Plans</h3>
<div class="row row-cols-1 row-cols-md-3 g-4">
{% for plan in offering.plans.all %}
<div class="col">
<div class="card h-100 {% if plan.is_default %}border-primary{% endif %}">
{% if plan.is_default %}
<div class="card-header text-primary">
Recommended Plan
</div>
{% endif %}
<div class="card-body">
<h4 class="card-title mb-3">{{ plan.name }}</h4>
<div class="rich-text-content mb-3">
{{ plan.description|safe }}
</div>
{% if plan.features %}
<div class="rich-text-content mb-3">
{{ plan.features|safe }}
</div>
{% endif %}
<div class="mb-3">
{% for price in plan.prices.all %}
<div class="mb-2">
<strong>{{ price.currency.symbol }}{{ price.price }}</strong>
{{ price.currency.code }} per {{ price.term.name }}
</div>
{% endfor %}
</div>
<a href="{% url 'services:create_lead' offering.service.slug %}?offering={{ offering.id }}&plan={{ plan.id }}"
class="btn btn-success">Select This Plan</a>
</div>
</div>
</div>
{% empty %}
<div class="col-12">
<div class="alert alert-info">
No plans available yet.
<a href="{% url 'services:create_lead' offering.service.slug %}?offering={{ offering.id }}"
class="btn btn-success ms-3">Show Interest</a>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,151 @@
{% extends 'services/base.html' %}
{% block content %}
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">Filters</h5>
<form method="get">
<div class="mb-3">
<label for="search" class="form-label">Search</label>
<input type="text" class="form-control" id="search" name="search" value="{{ request.GET.search }}">
</div>
<div class="mb-3">
<label for="cloud_provider" class="form-label">Cloud Provider</label>
<select class="form-select" id="cloud_provider" name="cloud_provider">
<option value="">All Providers</option>
{% for provider in cloud_providers %}
<option value="{{ provider.id }}" {% if request.GET.cloud_provider == provider.id|stringformat:'i' %}selected{% endif %}>
{{ provider.name }}
</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="category" class="form-label">Category</label>
<select class="form-select" id="category" name="category">
<option value="">All Categories</option>
{% for category in categories %}
<option value="{{ category.id }}" {% if request.GET.category == category.id|stringformat:'i' %}selected{% endif %}>
{{ category.name }}
</option>
{% for subcategory in category.children.all %}
<option value="{{ subcategory.id }}" {% if request.GET.category == subcategory.id|stringformat:'i' %}selected{% endif %}>
&nbsp;&nbsp;&nbsp;{{ subcategory.name }}
</option>
{% endfor %}
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">Apply Filters</button>
<a href="{% url 'services:offering_list' %}" class="btn btn-secondary">Clear</a>
</form>
</div>
</div>
</div>
<div class="col-md-9">
<div class="row row-cols-1 row-cols-md-2 g-4">
{% for offering in offerings %}
<div class="col">
<div class="card h-100">
<div class="card-body">
<div class="d-flex align-items-start mb-3">
<div class="me-3">
{% if offering.service.logo %}
<img src="{{ offering.service.logo.url }}"
alt="{{ offering.service.name }}"
style="max-height: 50px; max-width: 100px; object-fit: contain;">
{% endif %}
</div>
<div>
<h5 class="card-title mb-1">
<a href="{{ offering.service.get_absolute_url }}" class="text-decoration-none">
{{ offering.service.name }}
</a>
</h5>
<div class="d-flex align-items-center">
{% if offering.cloud_provider.logo %}
<a href="{{ offering.cloud_provider.get_absolute_url }}" class="me-2">
<img src="{{ offering.cloud_provider.logo.url }}"
alt="{{ offering.cloud_provider.name }}"
style="max-height: 25px; max-width: 50px; object-fit: contain;">
</a>
{% endif %}
<small class="text-muted">
{{ offering.cloud_provider.name }}
</small>
</div>
</div>
</div>
<div class="mb-2">
{% for category in offering.service.categories.all %}
<span class="badge bg-secondary me-1">{{ category.full_path }}</span>
{% endfor %}
</div>
<div class="rich-text-content mb-3">
{{ offering.description|safe|truncatewords_html:30 }}
</div>
{% if offering.plans.exists %}
<div class="mb-3">
<strong>Available Plans:</strong>
<ul class="list-unstyled small">
{% for plan in offering.plans.all %}
<li>• {{ plan.name }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="mt-auto d-flex gap-2">
<a href="{{ offering.get_absolute_url }}" class="btn btn-primary">View Details</a>
{% if offering.plans.exists %}
{% if offering.plans.count == 1 %}
{% with plan=offering.plans.first %}
<a href="{% url 'services:create_lead' offering.service.slug %}?offering={{ offering.id }}&plan={{ plan.id }}"
class="btn btn-success">Show Interest</a>
{% endwith %}
{% else %}
<div class="dropdown">
<button class="btn btn-success dropdown-toggle" type="button" data-bs-toggle="dropdown">
Show Interest
</button>
<ul class="dropdown-menu">
{% for plan in offering.plans.all %}
<li>
<a class="dropdown-item"
href="{% url 'services:create_lead' offering.service.slug %}?offering={{ offering.id }}&plan={{ plan.id }}">
{{ plan.name }}
{% if plan.is_default %}(Recommended){% endif %}
</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% else %}
<a href="{% url 'services:create_lead' offering.service.slug %}?offering={{ offering.id }}"
class="btn btn-success">Show Interest</a>
{% endif %}
</div>
</div>
</div>
</div>
{% empty %}
<div class="col">
<div class="alert alert-info">
No service offerings found matching your criteria.
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,93 @@
{% extends 'services/base.html' %}
{% block content %}
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">Filters</h5>
<form method="get">
<div class="mb-3">
<label for="search" class="form-label">Search</label>
<input type="text" class="form-control" id="search" name="search" value="{{ request.GET.search }}">
</div>
<div class="mb-3">
<label for="cloud_provider" class="form-label">Cloud Provider</label>
<select class="form-select" id="cloud_provider" name="cloud_provider">
<option value="">All Providers</option>
{% for provider in cloud_providers %}
<option value="{{ provider.id }}" {% if request.GET.cloud_provider == provider.id|stringformat:'i' %}selected{% endif %}>
{{ provider.name }}
</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">Apply Filters</button>
<a href="{% url 'services:partner_list' %}" class="btn btn-secondary">Clear</a>
</form>
</div>
</div>
</div>
<div class="col-md-9">
<div class="row row-cols-1 row-cols-md-2 g-4">
{% for partner in partners %}
<div class="col">
<div class="card h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-3">
{% if partner.logo %}
<img src="{{ partner.logo.url }}"
alt="{{ partner.name }}"
class="me-3" style="max-height: 60px; max-width: 120px; object-fit: contain;">
{% endif %}
<h5 class="card-title mb-0">{{ partner.name }}</h5>
</div>
<div class="rich-text-content mb-3">
{{ partner.description|safe|truncatewords_html:50 }}
</div>
<div class="mb-3">
<strong>Cloud Providers:</strong>
<div class="mt-2">
{% for provider in partner.cloud_providers.all %}
<div class="d-inline-block me-2 mb-2">
{% if provider.logo %}
<img src="{{ provider.logo.url }}"
alt="{{ provider.name }}"
style="max-height: 25px; max-width: 50px; object-fit: contain;">
{% else %}
<span class="badge bg-secondary">{{ provider.name }}</span>
{% endif %}
</div>
{% endfor %}
</div>
</div>
<div class="mb-3">
<strong>Services Available:</strong> {{ partner.services.count }}
</div>
<div class="mt-auto">
<a href="{{ partner.get_absolute_url }}" class="btn btn-primary">View Details</a>
{% if partner.website %}
<a href="{{ partner.website }}" class="btn btn-outline-secondary" target="_blank">Visit Website</a>
{% endif %}
</div>
</div>
</div>
</div>
{% empty %}
<div class="col">
<div class="alert alert-info">
No consulting partners found matching your criteria.
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,68 @@
{% extends 'services/base.html' %}
{% block content %}
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">Filters</h5>
<form method="get">
<div class="mb-3">
<label for="search" class="form-label">Search</label>
<input type="text" class="form-control" id="search" name="search" value="{{ request.GET.search }}">
</div>
<button type="submit" class="btn btn-primary">Apply Filters</button>
<a href="{% url 'services:provider_list' %}" class="btn btn-secondary">Clear</a>
</form>
</div>
</div>
</div>
<div class="col-md-9">
<div class="row row-cols-1 row-cols-md-2 g-4">
{% for provider in providers %}
<div class="col">
<div class="card h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-3">
{% if provider.logo %}
<img src="{{ provider.logo.url }}"
alt="{{ provider.name }}"
class="me-3" style="max-height: 60px; max-width: 120px; object-fit: contain;">
{% endif %}
<h5 class="card-title mb-0">{{ provider.name }}</h5>
</div>
<div class="rich-text-content mb-3">
{{ provider.description|safe|truncatewords_html:50 }}
</div>
<div class="mb-3">
<strong>Services Available:</strong> {{ provider.offerings.count }}
</div>
<div class="mb-3">
<strong>Partners:</strong> {{ provider.consulting_partners.count }}
</div>
<div class="mt-auto">
<a href="{{ provider.get_absolute_url }}" class="btn btn-primary">View Details</a>
{% if provider.website %}
<a href="{{ provider.website }}" class="btn btn-outline-secondary" target="_blank">Visit Website</a>
{% endif %}
</div>
</div>
</div>
</div>
{% empty %}
<div class="col">
<div class="alert alert-info">
No cloud providers found matching your criteria.
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View file

@ -1,120 +1,132 @@
{% extends 'services/base.html' %}
{% block content %}
<div class="card">
<div class="card mb-4">
<div class="card-body">
<div class="d-flex align-items-start mb-4">
{% if service.logo %}
<img src="{{ service.logo.url }}" alt="{{ service.name }} logo" class="me-4" style="max-height: 100px; max-width: 200px; object-fit: contain;">
<img src="{{ service.logo.url }}" alt="{{ service.name }} logo" class="me-4"
style="max-height: 120px; max-width: 240px; object-fit: contain;">
{% endif %}
<div>
<h2 class="card-title">{{ service.name }}</h2>
<div class="d-flex align-items-center">
{% if service.cloud_provider.logo %}
<a href="{% url 'services:provider_detail' service.cloud_provider.slug %}">
<img src="{{ service.cloud_provider.logo.url }}" alt="{{ service.cloud_provider.name }} logo"
class="me-2" style="max-height: 25px; max-width: 200px; object-fit: contain;">
</a>
{% else %}
<h6 class="card-subtitle text-muted mb-0">
<a href="{% url 'services:provider_detail' service.cloud_provider.pk %}"
class="text-decoration-none text-muted">{{ service.cloud_provider.name }}</a>
</h6>
{% endif %}
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-md-8">
<h5>Description</h5>
<p>{{ service.description|safe }}</p>
<h5>Features</h5>
<p>{{ service.features|safe }}</p>
{% if service.external_links.exists %}
<h5>External Resources</h5>
{% for link in service.external_links.all %}
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer"
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
{{ link.description }}
<i class="bi bi-box-arrow-up-right"></i>
</a>
{% endfor %}
{% endif %}
</div>
</div>
<div class="row mb-4">
<div class="col-12">
<h3 class="mb-4">Plans</h3>
<div class="row row-cols-1 row-cols-md-3 g-4">
{% for plan in service.plans.all %}
<div class="col">
<div class="card h-100 {% if plan.is_default %}border-primary{% endif %}">
{% if plan.is_default %}
<div class="card-header text-primary">
Recommended
</div>
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ plan.name }}</h5>
<div class="card-text mb-3">{{ plan.description|safe }}</div>
<div class="mb-3">
{% for price in plan.prices.all %}
<div class="mb-1">
<strong>{{ price.currency.symbol }}</strong> {{ price.price }}
<small class="text-muted">{{ price.currency.code }}</small>
</div>
{% endfor %}
</div>
{% if plan.features %}
<div class="rich-text-content">
{{ plan.features|safe }}
</div>
{% endif %}
<a href="{% url 'services:create_lead' service.slug %}?plan={{ plan.id }}"
class="btn btn-primary mt-3">Order</a>
</div>
</div>
</div>
<h2 class="card-title mb-3">{{ service.name }}</h2>
<div class="mb-3">
{% for category in service.categories.all %}
<span class="badge bg-secondary me-1">{{ category.full_path }}</span>
{% endfor %}
</div>
</div>
</div>
<a href="{% url 'services:create_lead' service.slug %}" class="btn btn-success">Order</a>
<a href="{% url 'services:service_list' %}" class="btn btn-secondary">Back to Services</a>
<div class="rich-text-content mb-4">
{{ service.description|safe }}
</div>
{% if service.features %}
<h3>Features</h3>
<div class="rich-text-content mb-4">
{{ service.features|safe }}
</div>
{% endif %}
</div>
</div>
{% if service.consulting_partners.exists %}
<div class="card mb-3">
<!-- Cloud Provider Offerings -->
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Consulting Partners</h5>
<h3 class="mb-4">Available Offerings</h3>
<div class="row row-cols-1 row-cols-md-2 g-4">
{% for offering in service.offerings.all %}
<div class="col">
<div class="card h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-3">
{% if offering.cloud_provider.logo %}
<img src="{{ offering.cloud_provider.logo.url }}"
alt="{{ offering.cloud_provider.name }} logo"
class="me-3" style="max-height: 50px; max-width: 100px; object-fit: contain;">
{% endif %}
<div>
<h5 class="card-title mb-0">
<a href="{{ offering.cloud_provider.get_absolute_url }}" class="text-decoration-none">
{{ offering.cloud_provider.name }}
</a>
</h5>
{% if offering.cloud_provider.website %}
<a href="{{ offering.cloud_provider.website }}" class="text-muted small" target="_blank">
Visit Provider Website
</a>
{% endif %}
</div>
</div>
<div class="rich-text-content mb-3">
{{ offering.description|safe|truncatewords_html:50 }}
</div>
{% if offering.plans.exists %}
<div class="mb-3">
<h6>Plans:</h6>
{% for plan in offering.plans.all %}
<div class="card mb-2">
<div class="card-body">
<h6 class="card-title">{{ plan.name }}</h6>
{% for price in plan.prices.all %}
<div class="small text-muted">
{{ price.currency.symbol }}{{ price.price }} {{ price.currency.code }} per {{ price.term.name }}
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{% endif %}
<a href="{% url 'services:create_lead' service.slug %}?offering={{ offering.id }}"
class="btn btn-success">Show Interest</a>
</div>
</div>
</div>
{% empty %}
<div class="col-12">
<div class="alert alert-info">
No offerings available yet.
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<!-- Consulting Partners -->
{% if service.consulting_partners.exists %}
<div class="card mb-4">
<div class="card-body">
<h3 class="mb-4">Consulting Partners</h3>
<div class="row row-cols-1 row-cols-md-3 g-4">
{% for partner in service.consulting_partners.all %}
<div class="col">
<div class="d-flex align-items-center">
{% if partner.logo %}
<img src="{{ partner.logo.url }}" alt="{{ partner.name }} logo"
class="me-2" style="max-height: 40px; max-width: 80px; object-fit: contain;">
{% endif %}
<div>
<a href="{{ partner.get_absolute_url }}" class="text-decoration-none">
{{ partner.name }}
</a>
{% if partner.website %}
<br>
<a href="{{ partner.website }}" class="small text-muted" target="_blank">
Visit Website
</a>
{% endif %}
<div class="card h-100">
<div class="card-body">
<div class="d-flex align-items-center mb-3">
{% if partner.logo %}
<img src="{{ partner.logo.url }}"
alt="{{ partner.name }} logo"
class="me-3" style="max-height: 50px; max-width: 100px; object-fit: contain;">
{% endif %}
<div>
<h5 class="card-title mb-0">
<a href="{{ partner.get_absolute_url }}" class="text-decoration-none">
{{ partner.name }}
</a>
</h5>
{% if partner.website %}
<a href="{{ partner.website }}" class="text-muted small" target="_blank">
Visit Website
</a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
@ -123,4 +135,22 @@
</div>
</div>
{% endif %}
{% endblock %}
<!-- External Links -->
{% if service.external_links.exists %}
<div class="card mb-4">
<div class="card-body">
<h3>Additional Information</h3>
<div class="list-group">
{% for link in service.external_links.all %}
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer"
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
{{ link.description }}
<i class="bi bi-box-arrow-up-right"></i>
</a>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% endblock %}

View file

@ -72,18 +72,23 @@
{% endif %}
<div>
<h5 class="card-title mb-0">{{ service.name }}</h5>
<div class="d-flex align-items-center mt-2">
{% if service.cloud_provider.logo %}
<a href="{% url 'services:provider_detail' service.cloud_provider.slug %}">
<img src="{{ service.cloud_provider.logo.url }}" alt="{{ service.cloud_provider.name }} logo"
class="me-2" style="max-height: 25px; max-width: 200px; object-fit: contain;">
</a>
{% else %}
<h6 class="card-subtitle text-muted mb-0">
<a href="{% url 'services:provider_detail' service.cloud_provider.pk %}"
class="text-decoration-none text-muted">{{ service.cloud_provider.name }}</a>
</h6>
{% endif %}
<div class="mt-2">
{% for offering in service.offerings.all %}
<div class="d-inline-block me-2">
{% if offering.cloud_provider.logo %}
<a href="{% url 'services:provider_detail' offering.cloud_provider.slug %}" title="{{ offering.cloud_provider.name }}">
<img src="{{ offering.cloud_provider.logo.url }}"
alt="{{ offering.cloud_provider.name }}"
style="max-height: 25px; max-width: 50px; object-fit: contain;">
</a>
{% else %}
<a href="{% url 'services:provider_detail' offering.cloud_provider.slug %}"
class="badge bg-secondary text-decoration-none">
{{ offering.cloud_provider.name }}
</a>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
@ -94,8 +99,25 @@
</div>
<p class="card-text">{{ service.description|safe|truncatewords:30 }}</p>
<a href="{{ service.get_absolute_url }}" class="btn btn-primary">View Details</a>
<a href="{% url 'services:create_lead' service.slug %}" class="btn btn-success">Show Interest</a>
<div class="mt-3">
<a href="{{ service.get_absolute_url }}" class="btn btn-primary">View Details</a>
{% if service.offerings.exists %}
<div class="dropdown d-inline-block">
<button class="btn btn-success dropdown-toggle" type="button" data-bs-toggle="dropdown">
Show Interest
</button>
<ul class="dropdown-menu">
{% for offering in service.offerings.all %}
<li>
<a class="dropdown-item" href="{% url 'services:create_lead' service.slug %}?offering={{ offering.id }}">
via {{ offering.cloud_provider.name }}
</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</div>
</div>
</div>
@ -109,4 +131,4 @@
</div>
</div>
</div>
{% endblock %}
{% endblock %}