added Files JSON import
@ -9,131 +9,142 @@ if ($conn->connect_error) {
|
||||
die("Connection failed: " . $conn->connect_error);
|
||||
}
|
||||
|
||||
// Check if JSON was received via POST
|
||||
// Check if POST request was received
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Receive JSON from the laboratory
|
||||
$json_data = file_get_contents('php://input');
|
||||
// Receive JSON from the laboratory via a field in the form (e.g., 'json_data')
|
||||
if (isset($_POST['json_data'])) {
|
||||
$json_data = $_POST['json_data'];
|
||||
|
||||
// Decode JSON for optional validation
|
||||
$decoded_data = json_decode($json_data, true);
|
||||
// Decode JSON for optional validation
|
||||
$decoded_data = json_decode($json_data, true);
|
||||
|
||||
// If the JSON is valid
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
// Authenticate using key, secret_key, and reflab
|
||||
if (!isset($decoded_data['key']) || !isset($decoded_data['secret_key']) || !isset($decoded_data['reflab'])) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Missing authentication fields (key, secret_key, reflab)."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$api_key = $decoded_data['key'];
|
||||
$secret_key = $decoded_data['secret_key'];
|
||||
$reflab = $decoded_data['reflab'];
|
||||
|
||||
$query = "SELECT * FROM laboratories WHERE reflab = ? AND api_key = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param("ss", $reflab, $api_key);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Controllo se un laboratorio valido è stato trovato con `reflab` e `api_key`
|
||||
if ($result->num_rows > 0) {
|
||||
$row = $result->fetch_assoc();
|
||||
|
||||
// Verifica lo stato del laboratorio
|
||||
if ($row['status'] !== 'active') {
|
||||
// If the JSON is valid
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
// Authenticate using key, secret_key, and reflab
|
||||
if (!isset($decoded_data['key']) || !isset($decoded_data['secret_key']) || !isset($decoded_data['reflab'])) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Laboratory is inactive."
|
||||
"message" => "Missing authentication fields (key, secret_key, reflab)."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verifica la chiave segreta utilizzando `password_verify`
|
||||
if (!password_verify($secret_key, $row['api_secret'])) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid secret key."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
// Verifica se il `reflab` è valido, ma l'`api_key` non corrisponde
|
||||
$query = "SELECT * FROM laboratories WHERE reflab = ?";
|
||||
$api_key = $decoded_data['key'];
|
||||
$secret_key = $decoded_data['secret_key'];
|
||||
$reflab = $decoded_data['reflab'];
|
||||
|
||||
$query = "SELECT * FROM laboratories WHERE reflab = ? AND api_key = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param("s", $reflab);
|
||||
$stmt->bind_param("ss", $reflab, $api_key);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Check if a valid laboratory was found with `reflab` and `api_key`
|
||||
if ($result->num_rows > 0) {
|
||||
$row = $result->fetch_assoc();
|
||||
|
||||
// Verify the status of the laboratory
|
||||
if ($row['status'] !== 'active') {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Laboratory is inactive."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verify the secret key using `password_verify`
|
||||
if (!password_verify($secret_key, $row['api_secret'])) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid secret key."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
// Check if the `reflab` is valid, but the `api_key` doesn't match
|
||||
$query = "SELECT * FROM laboratories WHERE reflab = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
$stmt->bind_param("s", $reflab);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid API key."
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid reflab."
|
||||
]);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
// Generate a UUID to uniquely identify the record
|
||||
$uuid = uniqid(); // Alternatively, use UUID() in MySQL
|
||||
|
||||
// Extract some information from JSON
|
||||
if (!isset($decoded_data['product']['products_refnumber'])) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid API key."
|
||||
"message" => "Missing product reference number."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$product_refnumber = $decoded_data['product']['products_refnumber']; // Product number
|
||||
$report_number = $decoded_data['product']['reports'][0]['reportsNumberLab'] ?? null; // Report number
|
||||
$rating = $decoded_data['product']['reports'][0]['reportsRating'] ?? null; // Report rating (e.g., Pass/Fail)
|
||||
$saved_at = date("Y-m-d H:i:s"); // Save date
|
||||
|
||||
// Query to insert data into the temp_json_queue table
|
||||
$stmt = $conn->prepare("INSERT INTO temp_json_queue (uuid, lab_id, json_data) VALUES (?, ?, ?)");
|
||||
$lab_id = 1; // Set lab_id to a fixed value for testing purposes
|
||||
$stmt->bind_param("sss", $uuid, $lab_id, $json_data);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Handle file uploads if they exist
|
||||
if (!empty($_FILES)) {
|
||||
include('process_files.php'); // Include file processing logic here
|
||||
}
|
||||
|
||||
// Set a session variable to notify the report import
|
||||
$_SESSION['new_report'] = [
|
||||
'report_number' => $report_number,
|
||||
'rating' => $rating,
|
||||
'timestamp' => time() // You can use a timestamp to manage the expiration of the notification
|
||||
];
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"message" => "Data successfully saved.",
|
||||
"uuid" => $uuid,
|
||||
"product_refnumber" => $product_refnumber, // Product number
|
||||
"report_number" => $report_number, // Report number
|
||||
"rating" => $rating, // Report rating
|
||||
"saved_at" => $saved_at // Save date
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid reflab."
|
||||
"message" => "Failed to save data."
|
||||
]);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// Generate a UUID to uniquely identify the record
|
||||
$uuid = uniqid(); // Alternatively, use UUID() in MySQL
|
||||
|
||||
// Extract some information from JSON
|
||||
if (!isset($decoded_data['product']['products_refnumber'])) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Missing product reference number."
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$product_refnumber = $decoded_data['product']['products_refnumber']; // Product number
|
||||
$report_number = $decoded_data['product']['reports'][0]['reportsNumberLab'] ?? null; // Report number
|
||||
$rating = $decoded_data['product']['reports'][0]['reportsRating'] ?? null; // Report rating (e.g., Pass/Fail)
|
||||
$saved_at = date("Y-m-d H:i:s"); // Save date
|
||||
|
||||
// Query to insert data into the temp_json_queue table
|
||||
$stmt = $conn->prepare("INSERT INTO temp_json_queue (uuid, lab_id, json_data) VALUES (?, ?, ?)");
|
||||
$lab_id = 1; // Set lab_id to a fixed value for testing purposes
|
||||
$stmt->bind_param("sss", $uuid, $lab_id, $json_data);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Set a session variable to notify the report import
|
||||
$_SESSION['new_report'] = [
|
||||
'report_number' => $report_number,
|
||||
'rating' => $rating,
|
||||
'timestamp' => time() // You can use a timestamp to manage the expiration of the notification
|
||||
];
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"message" => "Data successfully saved.",
|
||||
"uuid" => $uuid,
|
||||
"product_refnumber" => $product_refnumber, // Product number
|
||||
"report_number" => $report_number, // Report number
|
||||
"rating" => $rating, // Report rating
|
||||
"saved_at" => $saved_at // Save date
|
||||
]);
|
||||
$stmt->close();
|
||||
} else {
|
||||
// If the JSON is invalid
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Failed to save data."
|
||||
"message" => "Invalid JSON format."
|
||||
]);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
} else {
|
||||
// If the JSON is invalid
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Invalid JSON format."
|
||||
"message" => "Missing JSON data."
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
|
||||
56
public/userarea/apilogic/process_files.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// Check if there are any files uploaded
|
||||
if (!empty($_FILES)) {
|
||||
// Define the directory where files will be stored
|
||||
$upload_dir = '../report_files/';
|
||||
|
||||
// Ensure the upload directory exists
|
||||
if (!is_dir($upload_dir)) {
|
||||
mkdir($upload_dir, 0755, true);
|
||||
}
|
||||
|
||||
foreach ($_FILES as $key => $file) {
|
||||
if ($file['error'] === UPLOAD_ERR_OK) {
|
||||
// Get original filename and generate a stored filename with UUID as a prefix
|
||||
$original_filename = $file['name'];
|
||||
$stored_filename = $uuid . '_' . $original_filename; // Add UUID as prefix
|
||||
|
||||
// Define the full path where the file will be saved
|
||||
$filepath = $upload_dir . $stored_filename;
|
||||
|
||||
// Move the uploaded file to the specified directory
|
||||
if (move_uploaded_file($file['tmp_name'], $filepath)) {
|
||||
// Get the associated comment for the file if it exists
|
||||
$comment_key = str_replace('file', 'comment', $key);
|
||||
$file_comment = $_POST[$comment_key] ?? null;
|
||||
|
||||
// Insert file information into the database
|
||||
$stmt = $conn->prepare("INSERT INTO report_files (uuid, original_filename, stored_filename, filepath, file_comment) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("sssss", $uuid, $original_filename, $stored_filename, $filepath, $file_comment);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Failed to save file information for $original_filename."
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"message" => "File $original_filename uploaded and information saved."
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Failed to move file $original_filename."
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Error uploading file $original_filename. Error code: " . $file['error']
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/userarea/apilogic/tempfiles/6729d6481d565_test_report.pdf
Normal file
BIN
public/userarea/apilogic/tempfiles/6729d67bb1cf1_test_report.pdf
Normal file
BIN
public/userarea/apilogic/tempfiles/6729d6dc91c6a.pdf
Normal file
BIN
public/userarea/apilogic/tempfiles/6729d6dc92908.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/userarea/apilogic/tempfiles/6729d83cbcbfc_test_report.pdf
Normal file
@ -41,6 +41,23 @@ $stmtParts = $conn->prepare($queryPartsAndResults);
|
||||
$stmtParts->bind_param("i", $idreports);
|
||||
$stmtParts->execute();
|
||||
$partsAndResults = $stmtParts->get_result();
|
||||
|
||||
// Query per ottenere i file associati al report
|
||||
$queryFiles = "
|
||||
SELECT original_filename, stored_filename, file_comment, filepath
|
||||
FROM report_files
|
||||
WHERE uuid = ?
|
||||
AND (file_comment = 'report' OR file_comment = 'main_product_image')";
|
||||
$stmtFiles = $conn->prepare($queryFiles);
|
||||
$stmtFiles->bind_param("s", $reportDetails['importcode']);
|
||||
$stmtFiles->execute();
|
||||
$filesResult = $stmtFiles->get_result();
|
||||
|
||||
$files = [];
|
||||
while ($fileRow = $filesResult->fetch_assoc()) {
|
||||
$files[$fileRow['file_comment']] = $fileRow;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
@ -176,12 +193,128 @@ $partsAndResults = $stmtParts->get_result();
|
||||
<td><strong>Color:</strong></td>
|
||||
<td><?php echo $reportDetails['products_color']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>PDF Report:</strong></td>
|
||||
<td>
|
||||
<?php if (isset($files['report'])): ?>
|
||||
<a href="<?php echo htmlspecialchars('../report_files/' . $files['report']['stored_filename']); ?>" target="_blank">
|
||||
<i class="bx bxs-file-pdf" style="font-size: 24px; color: #d9534f;"></i> View Report
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span>No PDF available</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Product Image:</strong></td>
|
||||
<td>
|
||||
<?php if (isset($files['main_product_image'])): ?>
|
||||
<a href="<?php echo htmlspecialchars('../report_files/' . $files['main_product_image']['stored_filename']); ?>"
|
||||
target="_blank" onclick="openModal(event, this); return false;">
|
||||
<img src="<?php echo htmlspecialchars('../report_files/' . $files['main_product_image']['stored_filename']); ?>"
|
||||
alt="Product Image" style="max-width: 150px; max-height: 150px;">
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span>No image available</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Modal container for enlarged image -->
|
||||
|
||||
<div id="imageModal" style="display:none; position:fixed; z-index:1000; left:0; top:0; width:100%; height:100%; background-color:rgba(0, 0, 0, 0.8); justify-content:center; align-items:center;" onclick="closeModal(event)">
|
||||
<img id="modalImage" style="max-width:90%; max-height:90%;">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function openModal(event, link) {
|
||||
event.preventDefault();
|
||||
var modal = document.getElementById('imageModal');
|
||||
var modalImage = document.getElementById('modalImage');
|
||||
modalImage.src = link.href;
|
||||
modal.style.display = 'flex';
|
||||
}
|
||||
|
||||
function closeModal(event) {
|
||||
var modal = document.getElementById('imageModal');
|
||||
// Chiudi il modal solo se il clic è al di fuori dell'immagine
|
||||
if (event.target.id === 'imageModal') {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
// Query per ottenere i file aggiuntivi non etichettati come 'report' o 'main_product_image'
|
||||
$queryAdditionalFiles = "SELECT * FROM report_files WHERE uuid = ? AND file_comment NOT IN ('report', 'main_product_image')";
|
||||
$stmtAdditionalFiles = $conn->prepare($queryAdditionalFiles);
|
||||
$stmtAdditionalFiles->bind_param("s", $reportDetails['importcode']);
|
||||
$stmtAdditionalFiles->execute();
|
||||
$additionalFiles = $stmtAdditionalFiles->get_result();
|
||||
?>
|
||||
|
||||
<?php if ($additionalFiles->num_rows > 0): ?>
|
||||
<div class="card mt-4">
|
||||
<div class="card-body">
|
||||
<h5 class="header-title pb-3 mt-0">Additional Files</h5>
|
||||
<!-- Button to toggle collapsible area -->
|
||||
<button class="btn btn-primary mb-3" type="button" data-toggle="collapse" data-target="#additionalFilesSection">
|
||||
Show/Hide Additional Files
|
||||
</button>
|
||||
<!-- Collapsible area for additional files -->
|
||||
<div id="additionalFilesSection" class="collapse">
|
||||
<table class="table table-bordered">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>File Preview</th>
|
||||
<th>Comment</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($file = $additionalFiles->fetch_assoc()): ?>
|
||||
<?php
|
||||
$filePath = "../report_files/" . $file['stored_filename'];
|
||||
$isImage = preg_match('/\.(jpg|jpeg|png|gif)$/i', $file['stored_filename']);
|
||||
$isPDF = preg_match('/\.pdf$/i', $file['stored_filename']);
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php if ($isImage): ?>
|
||||
<!-- Thumbnail with click to enlarge -->
|
||||
<a href="<?php echo htmlspecialchars($filePath); ?>" onclick="openModal(event, this)">
|
||||
<img src="<?php echo htmlspecialchars($filePath); ?>" alt="Additional File" style="width:50px; height:auto;">
|
||||
</a>
|
||||
<?php elseif ($isPDF): ?>
|
||||
<!-- PDF icon with link -->
|
||||
<a href="<?php echo htmlspecialchars($filePath); ?>" target="_blank">
|
||||
<i class="fas fa-file-pdf" style="font-size: 24px; color: #d9534f;"></i>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<!-- Generic file icon with link -->
|
||||
<a href="<?php echo htmlspecialchars($filePath); ?>" target="_blank">
|
||||
<i class="fas fa-file-alt" style="font-size: 24px; color: #5a5a5a;"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($file['file_comment'], ENT_QUOTES, 'UTF-8'); ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
|
||||
<!-- Filtri -->
|
||||
<!-- Aggiungi questo filtro sopra la tabella -->
|
||||
|
||||
BIN
public/userarea/report_files/6729eca1406ee_TEST REPORT.pdf
Normal file
BIN
public/userarea/report_files/6729eca1406ee_productjacket.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
public/userarea/report_files/6729ed2d033ac_TEST REPORT.pdf
Normal file
BIN
public/userarea/report_files/6729ed2d033ac_productjacket.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
public/userarea/report_files/6729f21460ddc_TEST REPORT.pdf
Normal file
BIN
public/userarea/report_files/6729f21460ddc_details1.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
public/userarea/report_files/6729f21460ddc_details2.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
public/userarea/report_files/6729f21460ddc_productjacket.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
public/userarea/report_files/6729f21460ddc_reportdata.pdf
Normal file
BIN
public/userarea/report_files/6729f2b86ec6a_TEST REPORT.pdf
Normal file
BIN
public/userarea/report_files/6729f2b86ec6a_details1.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
public/userarea/report_files/6729f2b86ec6a_details2.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
public/userarea/report_files/6729f2b86ec6a_productjacket.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
public/userarea/report_files/6729f2b86ec6a_reportdata.pdf
Normal file
@ -347,6 +347,8 @@ $productBySupplierQuery = "
|
||||
LIMIT 30
|
||||
";
|
||||
|
||||
|
||||
|
||||
$productBySupplierResult = $conn->query($productBySupplierQuery);
|
||||
$productBySupplier = [];
|
||||
while ($row = $productBySupplierResult->fetch_assoc()) {
|
||||
@ -355,6 +357,21 @@ while ($row = $productBySupplierResult->fetch_assoc()) {
|
||||
'totalProducts' => $row['totalProducts']
|
||||
];
|
||||
}
|
||||
|
||||
$productDropdownQuery = "
|
||||
SELECT DISTINCT p.namesupplier AS supplier
|
||||
FROM products p
|
||||
WHERE p.namesupplier IS NOT NULL
|
||||
ORDER BY p.namesupplier ASC
|
||||
";
|
||||
|
||||
$productDropdownResult = $conn->query($productDropdownQuery);
|
||||
$productDropdown = [];
|
||||
while ($row = $productDropdownResult->fetch_assoc()) {
|
||||
$productDropdown[] = [
|
||||
'supplier' => $row['supplier']
|
||||
];
|
||||
}
|
||||
// refNumbers
|
||||
$refNumbersQuery = "
|
||||
SELECT p.products_refnumber AS refNumber
|
||||
@ -514,6 +531,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
'productsSeasons' => $productsSeasons,
|
||||
'ageRange' => $ageRange,
|
||||
'labName' => $labName,
|
||||
'productDropdown' => $productDropdown,
|
||||
'tesType' => $tesType,
|
||||
'numberLabs' => $numberLabs,
|
||||
'failedAnalytes' => $failedAnalytes,
|
||||
|
||||
@ -452,11 +452,12 @@ include('parsedatachart.php');
|
||||
<div class="col-md-4">
|
||||
<label for="supplierFilter">Supplier</label>
|
||||
<select id="supplierFilter" class="form-control select2" multiple>
|
||||
<?php foreach ($productBySupplier as $supplier): ?>
|
||||
<?php foreach ($productDropdown as $supplier): ?>
|
||||
<option value="<?php echo $supplier['supplier']; ?>"><?php echo $supplier['supplier']; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<!-- Active Filters Display -->
|
||||
|
||||