{% extends '@SyliusAdmin/layout.html.twig' %}
{% block content %}
<div class="ui stackable two column grid">
<div class="ten wide column">
<h1 class="ui header">
<i class="circular folder open outline icon"></i>
<div class="content">
Fichiers Archive Vingeanne
</div>
</h1>
<div class="ui breadcrumb">
<a href="/admin/" class="section">Admin</a>
<i class="right chevron icon divider"></i>
<a href="/admin/vingeanne" class="section">Vingeanne</a>
<i class="right chevron icon divider"></i>
<div class="active section">Fichiers Archive</div>
</div>
</div>
<div class="six wide right aligned column">
</div>
</div>
{# Filters Section #}
<div class="ui segment" style="margin-top: 20px;">
<h3 class="ui dividing header">
<i class="filter icon"></i>
Filtres
</h3>
<form id="filter-form" class="ui form">
<div class="four fields">
<div class="field">
<label>Type de fichier</label>
<div class="ui dropdown" id="filter-type">
<input type="hidden" name="type">
<i class="dropdown icon"></i>
<div class="default text">Tous les types</div>
<div class="menu">
<div class="item active selected" data-value="TOUS">Tous les types</div>
<div class="item" data-value="REA">REA (Réassort)</div>
<div class="item" data-value="OFF">OFF (Office)</div>
<div class="item" data-value="INCONNU">Inconnu</div>
</div>
</div>
</div>
<div class="field">
<label>Nom du fichier</label>
<input type="text" id="filter-name" placeholder="Rechercher..." />
</div>
<div class="field">
<label>Date de</label>
<input type="date" id="filter-date-from" />
</div>
<div class="field">
<label>Date à</label>
<input type="date" id="filter-date-to" />
</div>
</div>
<div class="field">
<button type="submit" class="ui primary button">
<i class="search icon"></i>
Rechercher
</button>
<button type="button" id="reset-filters" class="ui button">
<i class="redo icon"></i>
Réinitialiser
</button>
</div>
</form>
</div>
{# Results Section #}
<div id="results-section" style="margin-top: 20px;">
<div class="ui segment">
<h4 class="ui dividing header">
Résultats
<span id="result-count" class="ui label"></span>
</h4>
{# Loading Indicator #}
<div id="loading-indicator" style="display: none;">
<div class="ui active centered inline loader"></div>
<p style="text-align: center; margin-top: 10px;">Chargement des fichiers...</p>
</div>
{# Table #}
<div class="ui segment spaceless sylius-grid-table-wrapper" style="overflow-x: auto;">
<table id="files-table" class="ui sortable stackable very basic celled table">
<thead>
<tr>
<th>Type</th>
<th>Nom du fichier</th>
<th>Date de création</th>
<th>Taille</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="files-table-body">
<tr>
<td colspan="5" class="center aligned">
<div class="ui icon message">
<i class="circle notched loading icon"></i>
<div class="content">
<div class="header">
Chargement des données...
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
{# Pagination #}
<div id="pagination-container" style="margin-top: 20px; text-align: center;"></div>
</div>
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>
(function() {
// Wait for jQuery to be available
function initVingeanneModule() {
if (typeof jQuery === 'undefined') {
console.error('jQuery is not loaded! Retrying in 100ms...');
setTimeout(initVingeanneModule, 100);
return;
}
jQuery(document).ready(function($) {
console.log('Vingeanne Module initialized');
let currentPage = 1;
let currentFilters = {};
// Initialize dropdowns
$('.ui.dropdown').dropdown();
// Auto-load data on page load
loadFiles(1);
// Filter form submission
$('#filter-form').on('submit', function(e) {
e.preventDefault();
currentPage = 1;
loadFiles(1);
});
// Reset filters
$('#reset-filters').on('click', function() {
$('#filter-form')[0].reset();
$('.ui.dropdown').dropdown('clear');
currentPage = 1;
currentFilters = {};
loadFiles(1);
});
// Load files function
function loadFiles(page) {
console.log('Loading files for page:', page);
currentPage = page;
$('#loading-indicator').show();
currentFilters = {
type: $('#filter-type').dropdown('get value') || 'TOUS',
name: $('#filter-name').val(),
dateFrom: $('#filter-date-from').val(),
dateTo: $('#filter-date-to').val(),
page: page,
limit: 50
};
// Remove empty values
Object.keys(currentFilters).forEach(function(key) {
if (currentFilters[key] === '' || currentFilters[key] === null) {
delete currentFilters[key];
}
});
console.log('Filters:', currentFilters);
$.ajax({
url: '/admin/vingeanne/files/load',
method: 'GET',
data: currentFilters,
dataType: 'json',
success: function(response) {
console.log('Response received:', response);
$('#loading-indicator').hide();
if (response.success) {
renderTable(response.data);
renderPagination(response.pagination);
$('#result-count').text(response.pagination.total + ' fichier(s)');
} else {
console.error('API error:', response.error);
alert('Erreur: ' + response.error);
}
},
error: function(xhr, status, error) {
console.error('AJAX error:', status, error, xhr.responseText);
$('#loading-indicator').hide();
alert('Erreur lors du chargement des fichiers: ' + error);
}
});
}
// Render table function
function renderTable(data) {
console.log('Rendering table with', data.length, 'files');
const tbody = $('#files-table-body');
tbody.empty();
if (data.length === 0) {
tbody.append(
'<tr>' +
'<td colspan="5" class="center aligned">' +
'<div class="ui icon message">' +
'<i class="inbox icon"></i>' +
'<div class="content">' +
'<div class="header">Aucun fichier trouvé</div>' +
'<p>Essayez de modifier vos critères de recherche</p>' +
'</div>' +
'</div>' +
'</td>' +
'</tr>'
);
return;
}
data.forEach(function(file) {
let typeClass = '';
let typeIcon = 'file icon';
let typeLabel = file.type;
if (file.type === 'REA') {
typeClass = 'green';
typeIcon = 'refresh icon';
} else if (file.type === 'OFF') {
typeClass = 'blue';
typeIcon = 'file alternate icon';
} else {
typeClass = 'grey';
typeIcon = 'question icon';
}
const row =
'<tr>' +
'<td><span class="ui ' + typeClass + ' label"><i class="' + typeIcon + '"></i> ' + typeLabel + '</span></td>' +
'<td><strong>' + (file.name || '') + '</strong></td>' +
'<td>' + (file.createdAt || 'N/A') + '</td>' +
'<td>' + (file.size || 'N/A') + '</td>' +
'<td>' +
'<a href="/admin/vingeanne/files/download/' + encodeURIComponent(file.name) + '" class="ui small primary labeled icon button">' +
'<i class="download icon"></i> Télécharger' +
'</a>' +
'</td>' +
'</tr>';
tbody.append(row);
});
console.log('Table rendered successfully');
}
// Render pagination function
function renderPagination(pagination) {
console.log('Rendering pagination:', pagination);
const paginationContainer = $('#pagination-container');
paginationContainer.empty();
if (pagination.pages <= 1) {
return;
}
let html = '<div class="ui pagination menu">';
if (pagination.page > 1) {
html += '<a class="icon item" data-page="' + (pagination.page - 1) + '"><i class="left chevron icon"></i></a>';
} else {
html += '<a class="icon item disabled"><i class="left chevron icon"></i></a>';
}
const maxPages = 10;
let startPage = Math.max(1, pagination.page - Math.floor(maxPages / 2));
let endPage = Math.min(pagination.pages, startPage + maxPages - 1);
if (endPage - startPage < maxPages - 1) {
startPage = Math.max(1, endPage - maxPages + 1);
}
for (let i = startPage; i <= endPage; i++) {
if (i === pagination.page) {
html += '<a class="item active">' + i + '</a>';
} else {
html += '<a class="item" data-page="' + i + '">' + i + '</a>';
}
}
if (pagination.page < pagination.pages) {
html += '<a class="icon item" data-page="' + (pagination.page + 1) + '"><i class="right chevron icon"></i></a>';
} else {
html += '<a class="icon item disabled"><i class="right chevron icon"></i></a>';
}
html += '</div>';
paginationContainer.html(html);
paginationContainer.find('a.item:not(.disabled):not(.active)').on('click', function() {
const page = $(this).data('page');
if (page) {
loadFiles(page);
$('html, body').animate({
scrollTop: $('#results-section').offset().top - 100
}, 300);
}
});
}
});
}
// Start initialization
initVingeanneModule();
})();
</script>
<style>
#files-table {
font-size: 0.9em;
}
#files-table th {
white-space: nowrap;
}
#files-table td {
white-space: normal;
}
</style>
{% endblock %}