{% if hasGeneralSearch %}
{% import 'blocks\\macros.html.twig' as macros %}
<section class="block-search-results" {{ macros.getBlockDataAttributes(_context) }}>
<div class="container">
{% if values|length == 0 %}
{{ 'zerorecords'|trans([],'studio') }}
{% else %}
{# ---------------------------------------------- #}
{# Prepare data: items collection & type counts #}
{# ---------------------------------------------- #}
{% set resultsMeta = results is defined ? results : {
'items': values.items is defined ? values.items : values,
'counts': {'news':0,'news_reports':0,'programs':0,'event':0,'all':0},
'currentType': app.request.query.get('type')|default('all'),
'order': app.request.query.get('order')|default('relevance'),
'page': (app.request.query.get('page')|default(1)) + 0,
'pageSize': 15,
'pageCount': 1,
'nextPage': 0,
'total': (values.items is defined ? values.items|length : values|length),
'totalAll': (values.items is defined ? values.items|length : values|length)
} %}
{% set items = resultsMeta.items %}
{% set counts = resultsMeta.counts %}
{% set currentType = resultsMeta.currentType %}
{% set order = resultsMeta.order %}
{% set route = app.request.attributes.get('_route') %}
{% set routeParams = app.request.attributes.get('_route_params')|default({}) %}
{% set currentPage = resultsMeta.page %}
{% set pageSize = resultsMeta.pageSize %}
{% set pageCount = resultsMeta.pageCount %}
{% set nextPage = resultsMeta.nextPage %}
{% set totalItems = resultsMeta.total %}
{% set pageItems = items %}
{# --- Server-side filtering (tags[]=machine, themes[]=label) --- #}
{# Backend now applies tags[] and themes[] filtering; template no longer re-filters #}
{# ---------------------------------------------- #}
{# Results header (counts + ordering) #}
{# ---------------------------------------------- #}
{% if app.request.query.get('p') %}
{% set resultString = '<h1 class="results-title">Conta lá <span>' ~ app.request.query.get('p') ~ '</span></h1>' %}
{% elseif app.request.query.get('themes') %}
{% set themes = app.request.query.get('themes') %}
{% set resultString = '<h1 class="results-title">Conta lá <span>' ~ (themes|length == 1 ? themes[0] : themes|join(', ')) ~ '</span></h1>' %}
{% endif %}
{{ resultString|default|raw }}
<div class="results-bar mb-4" data-current-page="{{ currentPage }}" data-page-count="{{ pageCount }}"
data-page-size="{{ pageSize }}"
data-total-all="{{ resultsMeta.totalAll is defined ? resultsMeta.totalAll : (total is defined ? total : totalItems) }}">
<div class="results-bar-top d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3">
<div class="results-stats">
<span class="results-found-prefix">Encontrados</span>
<span class="results-total">{{ resultsMeta.totalAll is defined ? resultsMeta.totalAll : (total is defined ? total : totalItems) }}</span>
<span class="results-found-suffix">{{ 'results'|trans ({},'geral') }}</span>
</div>
</div>
{# Tabs #}
<nav class="results-tabs mt-3">
<ul class="results-tab-list list-unstyled d-flex mb-0 p-0 gap-1">
{% set tabMap = {
'all': 'Todos',
'news': 'Notícias',
'news_reports': 'Reportagens',
'programs': 'Programas',
'event': 'Eventos'
} %}
{# Define the order we want to display tabs #}
{% set tabOrder = ['all', 'news', 'news_reports', 'programs', 'event'] %}
{# restrict by content_type[] when provided #}
{% set ctParam = app.request.query.get('content_type') %}
{% set selectedTypes = ctParam is iterable ? ctParam : (ctParam ? [ctParam] : []) %}
{% set selected = [] %}
{% for ct in selectedTypes %}
{% set selected = selected|merge([ct|lower]) %}
{% endfor %}
{# build tab objects in the specified order, showing all tabs #}
{% set tabs = [] %}
{% for tKey in tabOrder %}
{% if tabMap[tKey] is defined %}
{% set tLabel = tabMap[tKey] %}
{% set cnt = counts[tKey]|default(0) %}
{# Always add the tab, regardless of count or selection #}
{% set tabs = tabs|merge([{'key': tKey, 'label': tLabel, 'count': cnt}]) %}
{% endif %}
{% endfor %}
{# Find the first tab with count > 0 to auto-select if current type has no results #}
{% set firstTabWithResults = 'all' %}
{% for tab in tabs %}
{% if tab.count > 0 and firstTabWithResults == 'all' and tab.key != 'all' %}
{% set firstTabWithResults = tab.key %}
{% endif %}
{% endfor %}
{# Auto-select "Todos" tab by default, or first tab with results if "Todos" has no results #}
{% set currentTypeCount = counts[currentType]|default(0) %}
{# Don't override currentType if it's already set correctly by the backend #}
{% if currentTypeCount == 0 and currentType != 'all' and counts['all']|default(0) > 0 %}
{% set currentType = 'all' %}
{% elseif currentTypeCount == 0 and counts['all']|default(0) == 0 %}
{% set currentType = firstTabWithResults %}
{% endif %}
{% for tab in tabs %}
{% set tKey = tab.key %}
{% set tLabel = tab.label %}
{% set linkParams = routeParams|merge(app.request.query.all)|merge({'type': tKey, 'page': 1}) %}
{% set isDisabled = tab.count == 0 %}
<li class="results-tab-item{% if currentType == tKey %} active{% endif %}{% if isDisabled %} disabled{% endif %}">
{% if route and not isDisabled %}
<a class="results-tab-link d-inline-block p-3{% if currentType == tKey %} active{% endif %}"
href="{{ path(route, linkParams) }}">
<span class="results-tab-text">{{ tLabel }}</span>
<span class="results-tab-count">({{ tab.count }})</span>
</a>
{% else %}
<span class="results-tab-link d-inline-block p-3{% if currentType == tKey %} active{% endif %}">
<span class="results-tab-text">{{ tLabel }}</span>
<span class="results-tab-count">({{ tab.count }})</span>
</span>
{% endif %}
</li>
{% endfor %}
</ul>
</nav>
{# Ordering form #}
<form class="results-order-form d-flex align-items-center mt-4" method="get">
{# preserve all current query params except order #}
{% for key,value in app.request.query.all %}
{% if key not in ['order'] %}
{% if value is iterable %}
{% for v in value %}<input type="hidden" name="{{ key }}[]" value="{{ v }}">{% endfor %}
{% else %}
<input type="hidden" name="{{ key }}" value="{{ value }}">
{% endif %}
{% endif %}
{% endfor %}
<label for="order_select" class="mb-0 small">Ordenar por</label>
<div class="select-wrapper">
<select id="order_select" name="order" class="form-select form-select-sm" onchange="this.form.submit()">
<option value="relevance" {{ order == 'relevance' ? 'selected' }}>Relevância</option>
<option value="newest" {{ order == 'newest' ? 'selected' }}>Mais recentes</option>
<option value="popular" {{ order == 'popular' ? 'selected' }}>Populares</option>
</select>
<i class="fa-solid fa-chevron-down"></i>
</div>
</form>
</div>
{# ---------------------------------------------- #}
{# Results grid list #}
{# ---------------------------------------------- #}
{# Results list wrapper (AJAX will append <li> items) #}
<ul id="js-search-results-list" class="search-results list-search-result">
{% set delay = 0 %}
{% for item in pageItems %}
{% set pageInfotitle = item.title|default %}
{% set pageInfourl = item.url|default %}
{% set pageInfovideo = item.content.video|default %}
{% set pageInfovideo_mobile = item.content.video_mobile|default %}
{% set pageInfotext = item.content.short_text|default %}
{% set pageInfoimage = item.content.default_image|default %}
{% set pageInfoimagemobile = item.content.default_image_mobile|default %}
{% set pageInfocategories = item.categories|default %}
{% set territory = item.content.territory|default %}
{% set date = item.content.date|default %}
{% set start_date = item.content.start_date|default %}
{# Collect tag machines (fallback to id) for filtering #}
{% set tagMachines = [] %}
{% if item.tags is defined and item.tags is not empty %}
{% for tag in item.tags %}
{% set machine = tag.machineName|default(tag.machine|default(tag.slug|default(tag))) %}
{% set tagMachines = tagMachines|merge([ machine ]) %}
{% endfor %}
{% endif %}
{# Get categories (Temas) for this item #}
{% set pageId = item.pageId is defined and item.pageId ? item.pageId.id : null %}
{% set pageInfo = pageId ? get_page_info(app.request.locale, pageId, true, "Temas")|default(null) : null %}
{% set categories = (pageInfo is not null and pageInfo.categories is defined) ? pageInfo.categories : [] %}
{% set exclusiveTag = pageInfo and pageInfo.page.tags is defined ? pageInfo.page.tags|filter(t => t.domainValue.type.name == 'Exclusive')|first|default(null) : null %}
{% set maxVisible = 1 %}
<li {% if settings.is_animated|default %}data-aos="{{ settings.animation_type|default("fade") }}"
data-aos-delay="{{ delay }}"{% endif %} class="item"
data-type="{{ item.getNormalizedContentTypeKey is defined ? item.getNormalizedContentTypeKey() : (item.getNormalizedContentTypeKey() ?? '') }}"
data-tags="{{ tagMachines|join(',') }}">
<a href="{{ item.canonicalUrl|default('#') }}">
<div class="image-container event-card-carousel">
<picture>
{% set image = pageInfoimage|default(null) %}
{% if image is empty %}
{% set image = '/uploads/system/placeholder-vertical.png' %}
{% endif %}
<img src="{{ (image)|imagine_filter('poster')|urldecode }}"
loading="lazy"
alt="{{ item.title|default('') }}"
title="{{ item.image_title|default(item.title|default('')) }}">
</picture>
{# <form>
<input type="hidden" name="highlight_id">
<button type="submit" class="favorites-button js-favorites-button">
{{ file_get_contents(asset('custom/favorites-icon.svg', 'global'))|raw }}
</button>
</form> #}
{% if pageInfovideo %}
<div class="card card-blur icon">
{{ file_get_contents(asset('custom/player-icon.svg', 'global'))|raw }}
</div>
{% endif %}
</div>
<div class="caption">
<h3 class="card-title">
{{ item.title is defined and item.title is not empty
? (item.title|length <= 80
? item.title
: item.title|slice(0, 80) ~ '...')
: 'Event Title ' ~ i }}
</h3>
{% if pageInfovideo %}
<div class="category">
{{ item.category|default('') }}
</div>
{% endif %}
{# temas #}
{{ macros.renderCategoryPopover(categories, maxVisible, false, exclusiveTag, languagecode, 'categories-list') }}
{# date #}
<div class="date" title="{{ start_date ? start_date|date('d/m/Y') : date|date('d/m/Y') }}">
{% set tz = 'Europe/Lisbon' %}
{% set dateValue = start_date ? start_date : date %}
{% set fmt = app.request.locale starts with('en') ? 'MMM d yyyy' : 'd MMM Y' %}
{{ file_get_contents(asset('custom/time-icon.svg', 'global'))|raw }}
{{ dateValue|localizeddate('none', 'none', app.request.locale, tz, fmt) }}
</div>
</div>
</a>
</li>
{% set delay = delay + 150 %}
{% endfor %}
</ul>
{% if app.request.query.get('isajax') != '1' and nextPage > 0 %}
<div class="load-more-wrapper text-center mt-4">
<button id="js-load-more-results"
class="btn-primary btn-style-1 btn-load-more"
data-current-page="{{ currentPage }}"
data-total-pages="{{ pageCount }}"
data-next-page="{{ nextPage }}"
type="button">
<span class="label">{{ 'see_more'|trans({}, 'custom')|default('Ver mais') }}</span>
<span class="spinner d-none" aria-hidden="true"></span>
</button>
</div>
<script>
(function () {
const btn = document.getElementById('js-load-more-results');
const list = document.getElementById('js-search-results-list');
if (!btn || !list) return;
let loading = false;
function buildUrl(p) {
const url = new URL(window.location.href);
url.searchParams.set('page', p);
url.searchParams.set('isajax', '1');
return url.toString();
}
function show() {
btn.disabled = true;
btn.classList.add('is-loading');
const sp = btn.querySelector('.spinner');
sp && sp.classList.remove('d-none');
}
function hide() {
btn.disabled = false;
btn.classList.remove('is-loading');
const sp = btn.querySelector('.spinner');
sp && sp.classList.add('d-none');
}
async function load() {
if (loading) return;
loading = true;
show();
const next = parseInt(btn.getAttribute('data-next-page'), 10);
const total = parseInt(btn.getAttribute('data-total-pages'), 10);
try {
const r = await fetch(buildUrl(next), {headers: {'X-Requested-With': 'XMLHttpRequest'}});
if (!r.ok) throw new Error(r.status);
const html = await r.text();
const tmp = document.createElement('div');
tmp.innerHTML = html;
const fragUl = tmp.querySelector('#js-search-results-list');
const items = fragUl ? fragUl.querySelectorAll('li') : tmp.querySelectorAll('li.item');
items.forEach(li => {
const id = li.getAttribute('data-id');
if (!list.querySelector(`[data-id="${id}"]`)) {
li.classList.add('appended');
list.appendChild(li);
}
});
if (next >= total) {
btn.remove();
} else {
btn.setAttribute('data-current-page', String(next));
btn.setAttribute('data-next-page', String(next + 1));
}
} catch (e) {
console.error('Load more failed', e);
btn.classList.add('error');
} finally {
hide();
loading = false;
}
}
btn.addEventListener('click', function (e) {
e.preventDefault();
load();
});
})();
</script>
{% endif %}
{% endif %}
</div>
</section>
{% endif %}