Compare commits

...

3 commits

Author SHA1 Message Date
65fc303b72 Merge pull request 'Make card layout / lists consistent' (#192) from 178-card-layout into main
Some checks failed
Build and Deploy Staging / build (push) Failing after 1s
Build and Deploy Staging / deploy (push) Has been skipped
Tests / test (push) Failing after 1s
Reviewed-on: #192
2025-09-11 14:29:15 +00:00
8aa42db71f Extract card layout into reusable CSS classes
All checks were successful
Tests / test (push) Successful in 25s
2025-09-11 13:20:13 +02:00
869d1cec85 Make card list layout consistent 2025-09-11 13:16:12 +02:00
4 changed files with 81 additions and 37 deletions

View file

@ -46,28 +46,27 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="row"> <div class="row match-height card-grid">
{% for offering in service.offerings.all %} {% for offering in service.offerings.all %}
<div class="col-6 col-lg-3 col-md-4"> <div class="col-6 col-lg-3 col-md-4">
<div class="card"> <div class="card">
<div class="card-header d-flex align-items-center"> <div class="card-header card-header-with-logo">
{% if offering.provider.logo %} {% if offering.provider.logo %}
<img src="{{ offering.provider.logo.url }}" <img src="{{ offering.provider.logo.url }}"
alt="{{ offering.provider.name }}" alt="{{ offering.provider.name }}">
class="me-3"
style="max-width: 48px;
max-height: 48px">
{% endif %} {% endif %}
<div class="d-flex flex-column"> <div class="card-header-content">
<h4 class="mb-0">{{ offering.provider.name }}</h4> <h4>{{ offering.provider.name }}</h4>
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-content">
{% if offering.description %} <div class="card-body">
<p class="card-text">{{ offering.description|urlize }}</p> {% if offering.description %}
{% elif offering.provider.description %} <p class="card-text">{{ offering.description|urlize }}</p>
<p class="card-text">{{ offering.provider.description|urlize }}</p> {% elif offering.provider.description %}
{% endif %} <p class="card-text">{{ offering.provider.description|urlize }}</p>
{% endif %}
</div>
</div> </div>
<div class="card-footer d-flex justify-content-between"> <div class="card-footer d-flex justify-content-between">
<span></span> <span></span>

View file

@ -22,7 +22,7 @@
{% endblock page_title_extra %} {% endblock page_title_extra %}
{% block content %} {% block content %}
<section class="section"> <section class="section">
<div class="row"> <div class="row match-height mb-5">
<div class="col-12 col-md-5"> <div class="col-12 col-md-5">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">

View file

@ -16,25 +16,24 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row service-cards-container mb-5"> <div class="row match-height card-grid service-cards-container mb-5">
{% for service in services %} {% for service in services %}
<div class="col-6 col-lg-3 col-md-4"> <div class="col-12 col-md-6 col-lg-3">
<div class="card h-100 d-flex flex-column"> <div class="card">
<div class="card-header d-flex align-items-center"> <div class="card-header card-header-with-logo">
{% if service.logo %} {% if service.logo %}
<img src="{{ service.logo.url }}" <img src="{{ service.logo.url }}"
alt="{{ service.name }}" alt="{{ service.name }}">
class="me-3"
style="max-width: 48px;
max-height: 48px">
{% endif %} {% endif %}
<div class="d-flex flex-column"> <div class="card-header-content">
<h4 class="mb-0">{{ service.name }}</h4> <h4>{{ service.name }}</h4>
<small class="text-muted">{{ service.category }}</small> <small class="text-muted">{{ service.category }}</small>
</div> </div>
</div> </div>
<div class="card-body flex-grow-1"> <div class="card-content">
{% if service.description %}<p class="card-text">{{ service.description|urlize }}</p>{% endif %} <div class="card-body flex-grow-1">
{% if service.description %}<p class="card-text">{{ service.description|urlize }}</p>{% endif %}
</div>
</div> </div>
<div class="card-footer d-flex justify-content-between align-items-center gap-2"> <div class="card-footer d-flex justify-content-between align-items-center gap-2">
{% if service.featured_links %} {% if service.featured_links %}
@ -57,7 +56,9 @@
{% empty %} {% empty %}
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<p>{% translate "No services found." %}</p> <div class="card-content">
<p>{% translate "No services found." %}</p>
</div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View file

@ -175,22 +175,66 @@ a.btn-keycloak {
padding-right: 28px; padding-right: 28px;
} }
/* Service cards equal height styling */ /* Card layout utilities - reusable for any card grid */
.service-cards-container .card { .card-grid {
height: 100%; display: flex;
flex-wrap: wrap;
}
.card-grid > * {
display: flex;
align-items: stretch;
}
.card-grid .card {
width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.service-cards-container .card-body { .card-grid .card-content {
flex-grow: 1; flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
} }
.service-cards-container .card-footer { .card-grid .card-body {
margin-top: auto; flex-grow: 1;
}
/* Card header with logo styling */
.card-header-with-logo {
display: flex;
align-items: center;
}
.card-header-with-logo img {
max-width: 48px;
max-height: 48px;
margin-right: 1rem;
}
.card-header-with-logo .card-header-content {
display: flex;
flex-direction: column;
}
.card-header-with-logo .card-header-content h4 {
margin-bottom: 0;
}
.card-header-with-logo .card-header-content .text-muted {
font-size: 0.875rem;
}
/* Backwards compatibility - keep existing service-cards-container class */
.service-cards-container > * {
display: flex;
align-items: stretch;
}
.service-cards-container .card {
width: 100%;
}
.service-cards-container .card-content {
flex-grow: 1;
} }
/* CRD Form mandatory field styling */ /* CRD Form mandatory field styling */