Files
ms1readerv4/ci4app/app/Views/event_reader.php
2026-07-17 11:48:07 -04:00

446 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
$title = "Events";
$menu = "menus/men_event_reader";
$header = "headers/hea_event_reader";
$this->setVar('menu', $menu);
$this->setVar('header', $header);
$this->setVar('title', $title);
?>
<?= $this->extend('layouts/default') ?>
<?= $this->section('content') ?>
<div class="content relative lg:px-4 flex-grow">
<!--:Prelaoder:-->
<div id="preloader" class="absolute inset-0 w-full h-[75vh] flex items-center justify-center z-50">
<div class="size-12 bg-white shadow-xl rounded-full flex items-center justify-center">
<div class="animate-spin rounded-full size-10 border-b-2 border-primary"></div>
</div>
</div>
<div id="readers-container" class="px-4 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-4 mb-4">
</div>
<div id="readerstp-container" class="px-4 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-4 mb-4">
</div>
<?php
// echo "<pre>";
// print_r($config_course);
// echo "</pre>";
// $config_tp['timingpoint'] doit exister
$timingPoints = $config_tp['timingpoint'] ?? [];
// Hauteur fixe visuelle de chaque TP (en px)
$tpHeight = 80;
$tpGap = 10;
// Largeur de chaque colonne d'intervalle (en px)
$intervalColWidth = 60;
// Indexer les TP par tp_id pour les alignements verticaux
$tpIndexById = [];
foreach ($timingPoints as $index => $tp) {
$tpIndexById[$tp['tp_id']] = $index;
}
// Récupérer toutes les lignes d'intervalles (une colonne par intervalle)
$intervals = [];
foreach ($timingPoints as $tp) {
// vérifier si la clé existe
if (!isset($tp['config_tp_interval']['clef_temp_minimum_read_entre'])) {
continue;
}
// lire toutes les lignes de cet interval
foreach ($tp['config_tp_interval']['clef_temp_minimum_read_entre'] as $row) {
$intervals[] = [
'label' => 'clef_temp_minimum_read_entre',
'start_id' => isset($row['value2']) ? (int) $row['value2'] : 0, // DÉBUT (tp_id)
'end_id' => isset($row['value3']) ? (int) $row['value3'] : 0, // FIN (tp_id)
'minimum' => isset($row['value3']) ? (int) $row['value1'] : 0, // FIN (tp_id)
];
}
}
$nbTp = count($timingPoints);
// Hauteur totale = toutes les cartes + les espaces entre elles
$totalHeight = $nbTp * $tpHeight + max(0, $nbTp - 1) * $tpGap;
?>
<div class="px-4" data-collapse-root>
<!-- Header du collapse -->
<div class="flex items-center justify-between p-3 bg-white dark:bg-zinc-900 rounded-t-xl shadow-card">
<p class="text-left font-semibold">Config (<?php echo count($timingPoints); ?> timing points)</p>
<button data-collapse-btn class="text-zinc-700 dark:text-white">
<i data-lucide="chevron-down" class="w-5 h-5"></i>
</button>
</div>
<!-- Contenu collapsable -->
<div data-collapse-content class="mt-2">
<div class="lg:col-span-8">
<!--:Card:-->
<div class="rounded-xl bg-green-300 dark:bg-zinc-900 shadow-card overflow-hidden">
<div class="flex items-center justify-between p-4 pb-2">
<h1 >Config COURSE</h1>
</div>
<div class="overflow-x-auto px-2">
<table class="table-default">
<tbody>
<?php foreach ($config_course as $cle => $course):
?>
<tr>
<td class="min-w-64">
<div class="flex gap-3.5">
<div class="flex-grow">
<h6 class="mb-1.5"><?php echo $cle; ?></h6>
</div>
</div>
</td>
<td> <?php echo $course[0]['output']; ?></td>
<td class="min-w-40">
<div class="flex items-center gap-3.5">
</div>
</td>
<td>
<div class="flex items-center gap-4">
<div class="flex flex-col gap-1">
</div>
<div class="flex flex-col gap-1">
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<div class="flex gap-[0px] items-start">
<!-- COLONNE GAUCHE : TIMING POINTS (~75%) -->
<div class="w-4/5">
<?php foreach ($timingPoints as $tp):
// echo "<pre>";
// print_r($tp);
// echo "</pre>";
?>
<div
class="rounded-xl bg-blue-300 dark:bg-zinc-900 shadow-card mb-3 flex items-center px-4"
style="height: <?php echo $tpHeight; ?>px;"
>
<!-- Icone + Nom du TP -->
<div class="flex items-center gap-3.5 flex-1">
<div class="flex items-center justify-center p-4 rounded-lg shrink-0 bg-red-500/10 text-red-500">
<span class="icon-[lucide--mouse-pointer-2] text-xl"></span>
</div>
<div class="flex-grow">
<p class="mb-1 font-semibold"><?php echo $tp['tp_name']; ?></p>
<p class="mb-1 text-sm text-zinc-600">tp_id : <?php echo $tp['tp_id']; ?></p>
</div>
</div>
<!-- Temp minimum read -->
<div class="flex items-center gap-3.5 flex-1">
<div class="flex items-center justify-center p-4 rounded-lg shrink-0 bg-primary/20 text-primary">
<i data-lucide="timer" class="w-4 h-4"></i>
</div>
<div class="flex-grow">
<?php $minRead = $tp['config_tp']['clef_temp_read'][0] ?? null; ?>
<?php $bbk = $tp['config_tp']['clef_temp_bbk'][0]['value1'] ?? null; ?>
<p class="mb-1 text-sm">
mode: <?php echo $minRead['value1'] ?? ''; ?><br>
bbk:<?php echo $bbk ?? ''; ?><br>
</p>
<p class="mb-1 text-sm">
</p>
</div>
</div>
<!-- Liste des contrôleurs -->
<div class="flex items-center gap-3.5 flex-1">
<div class="flex-grow">
<?php foreach ($tp['config_tp']['clef_controleur'] ?? [] as $ctrl): ?>
<p class="mb-1 text-sm">
<?php echo $ctrl['value1']; ?>
- (<?php echo $ctrl['value2']; ?>)
- (<?php echo $ctrl['value3']; ?>)
</p>
<?php endforeach; ?>
</div>
</div>
<!-- Case vide / future config -->
<div class="flex items-center gap-3.5">
<div class="flex items-center justify-center p-4 rounded-lg shrink-0 bg-yellow-500/20 text-yellow-500">
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<!-- COLONNES DROITES : INTERVALLES (~25%) -->
<?php if (!empty($intervals)): ?>
<!-- COLONNES DROITES : INTERVALLES (~25%) -->
<div class="overflow-x-auto pt-2 shrink-0" style="width:160px;">
<div class="flex gap-0">
<?php foreach ($intervals as $interval): ?>
<?php
// Skip si start_id ou end_id n'existent pas dans la map
if (!isset($tpIndexById[$interval['start_id']], $tpIndexById[$interval['end_id']])) {
continue;
}
// Convertir tp_id → index de ligne
$startIndex = $tpIndexById[$interval['start_id']];
$endIndex = $tpIndexById[$interval['end_id']];
// S'assurer startIndex <= endIndex
if ($endIndex < $startIndex) {
$tmp = $startIndex;
$startIndex = $endIndex;
$endIndex = $tmp;
}
// Position de départ (index * (hauteur + gap))
$top = $startIndex * ($tpHeight + $tpGap);
// Hauteur du segment = toutes les cartes couvertes + les gaps entre elles
$height = ($endIndex - $startIndex + 1) * $tpHeight
+ max(0, $endIndex - $startIndex) * $tpGap;
?>
<!-- DEBUG propre -->
<pre style="font-size:12px;color:#333;">
</pre>
<!-- Colonne dun intervalle -->
<div class="relative rounded-xl bg-blue-200"
style="width:10px; height:<?= $totalHeight ?>px;">
<!-- Barre bleue -->
<div class="absolute left-1/2 -translate-x-1/2 bg-blue-200 rounded-full shadow"
style="
top: <?= $top ?>px;
height: <?= $height ?>px;
width: 20px; background-color: #2563eb;
">
<!-- TEXTE VERTICAL -->
<div style="
writing-mode: vertical-rl;
transform: rotate(180deg);
color: white;
font-size: 12px;
font-weight: bold;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(180deg);
white-space: nowrap;
">
Minumum <?= $interval['minimum'] ?> sec.
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<script>
const DEBUG = <?= (ENVIRONMENT === 'development') ? 'true' : 'false' ?>;
const conId = <?= json_encode($data['config']['con_id'] ) ?>;
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('readers-container');
const eventId = <?= json_encode($id) ?>;
let refreshRate = 1000; // 1 seconde en ms (sera mis à jour par le JSON)
async function loadReaders() {
try {
const response = await fetch('/event/reader-json/' + eventId);
const json = await response.json();
if (DEBUG) {
console.log('JSON complet reçu:', json);
console.log('json.readers = ', json.readers);
console.log('Array.isArray(json.readers) = ', Array.isArray(json.readers));
}
// MAJ du rate si tu changes plus tard dans DB
refreshRate = json.refreshRate * 1000;
// Reconstruire les cartes
let html = '';
const readersRaw = json.readers ?? [];
const readers = Array.isArray(readersRaw) ? readersRaw : Object.values(readersRaw);
readers.forEach(reader => {
// Préparer les dates
const start = new Date(reader.start_time * 1000)
.toISOString().replace('T', ' ').substring(0, 19);
const end = new Date(reader.end_time * 1000)
.toISOString().replace('T', ' ').substring(0, 19);
html += `
<div class="p-4 gap-2.5 rounded-xl shadow-card" style="background-color:${reader.bg_color};">
<div class="flex flex-col">
<div class="flex items-center justify-between mb-1">
<div class="flex items-center gap-2">
<div class="size-10 rounded-lg bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center">
<span class="icon-[${reader.icon}] text-xl"></span>
</div>
<h5 class="text-1xl m-0">${reader.location}</h5>
</div>
</div>
<div class="flex items-center justify-between mb-1">
<span class="px-3 py-1 text-sm text-black dark:text-white">Lectures</span>
<span class="badge bg-green-500/10 text-sky-950">${reader.count}</span>
</div>
<div class="flex items-center justify-between mb-1">
<span class="badge bg-green-500/10 text-amber-900">${start}</span>
</div>
<div class="flex items-center justify-between mb-1">
<span class="badge bg-green-500/10 text-blue-500">${end}</span>
</div>
</div>
</div>
`;
});
// Injecter dans le DOM
container.innerHTML = html;
} catch (err) {
console.error('Erreur AJAX Reader:', err);
}
// Relancer après X secondes
setTimeout(loadReaders, refreshRate);
}
// Premier appel
loadReaders();
loadReaderTP();
});
async function loadReaderTP() {
try {
const response = await fetch('/event/readertp-json/' + conId );
const json = await response.json();
refreshRate = json.refreshRate * 1000;
const process_status = json?.process_status ?? null;
const containerTP = document.getElementById('readerstp-container');
const listTP = json.readertimingpoint?.timingpoint ?? [];
let html = '';
listTP.forEach(tp => {
html += `
<div class="p-3 gap-2.5 rounded-xl shadow-card bg-white dark:bg-zinc-900">
<div class="flex flex-col">
<div class="flex items-center justify-between mb-1">
<h5 class="text-1xl m-0">${tp.tp_name}</h5>
</div>
<div class="flex items-center justify-between mb-1">
<span class="px-3 py-1 text-sm text-black dark:text-white">Lecture valide</span>
<span class="badge bg-green-500/10 text-sky-950">${tp.lecture_count}</span>
</div>
<div class="flex items-center justify-between mb-1">
<span class="px-3 py-1 text-sm text-black dark:text-white">Statut</span>
<span class="badge bg-green-500/10 text-amber-900">${process_status}</span>
</div>
</div>
</div>
`;
});
containerTP.innerHTML = html;
} catch (err) {
console.error('Erreur AJAX TP:', err);
}
setTimeout(loadReaderTP, refreshRate);
}
</script>
<?= $this->endSection() ?>