Files
khadhroony-solana-project/crates/ksp-app-solprices-desk/frontend/main.html
2026-08-27 14:35:18 +02:00

189 lines
13 KiB
HTML

<!-- file: crates/ksp-app-solprices-desk/frontend/main.html -->
<!-- version: 8 -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<link rel="icon" href="imgs/logo.png">
<link rel="stylesheet" href="sass/main.scss">
<title>SOL Prices Desk — Prices</title>
</head>
<body>
<header class="app-header">
<nav class="navbar h-100 py-0 bg-light text-dark">
<div class="container-fluid px-4 flex-nowrap">
<div class="navbar-brand d-flex align-items-center me-4 flex-nowrap">
<img alt="KSP" src="imgs/logo.png" class="app-logo">
<span class="ps-2 fs-4 fw-semibold text-primary text-nowrap">SOL Prices Desk</span>
<span class="mx-2 fs-5 text-body-secondary" aria-hidden="true"></span>
<span id="headerViewTitle" class="fs-5 text-body text-nowrap">Prices</span>
</div>
</div>
</nav>
</header>
<main class="app-main container-fluid p-0">
<div class="row g-0 h-100 flex-nowrap">
<aside class="col-auto app-sidebar border-end bg-body-tertiary">
<div class="app-sidebar-scroll h-100" data-simplebar>
<nav class="nav nav-pills flex-column gap-1 p-3" aria-label="Navigation SOL Prices Desk">
<button class="nav-link text-start active" type="button" data-view="prices">
<i class="fa-solid fa-dollar-sign me-2" aria-hidden="true"></i>Prices
</button>
<button class="nav-link text-start" type="button" data-view="diagnostics">
<i class="fa-solid fa-stethoscope me-2" aria-hidden="true"></i>Diagnostics
</button>
</nav>
</div>
</aside>
<section class="col app-content app-scrollable h-100" data-simplebar>
<div class="container-fluid px-4 py-4">
<div class="card app-shell-card mx-auto shadow-sm border-0">
<div class="card-body p-4">
<section data-view-panel="prices">
<div class="d-flex align-items-start justify-content-between gap-3 flex-wrap mb-3">
<div>
<h1 class="h3 mb-1">Prices</h1>
<p class="text-body-secondary mb-0">Inventaire provider-neutral SOL/USD. Les observations restent distinctes : aucune moyenne, aucun fallback automatique et aucun polling.</p>
</div>
<div class="d-flex align-items-center gap-2 flex-wrap app-market-toolbar">
<span id="selectedProviderCount" class="small text-body-secondary" aria-live="polite">0 selected</span>
<button id="clearSelectionButton" class="btn btn-sm btn-outline-secondary" type="button" disabled>
<i class="fa-solid fa-xmark me-1" aria-hidden="true"></i>Clear selection
</button>
<button id="refreshSelectedButton" class="btn btn-sm btn-outline-primary" type="button" disabled>
<i class="fa-solid fa-list-check me-1" aria-hidden="true"></i>Refresh selected
</button>
<button id="refreshAllButton" class="btn btn-sm btn-primary" type="button" disabled>
<i class="fa-solid fa-arrows-rotate me-1" aria-hidden="true"></i>Refresh all
</button>
</div>
</div>
<div id="pricesSummary" class="row g-2 mb-3" aria-label="Résumé des providers">
<div class="col-6 col-lg">
<div class="app-market-summary-card">
<span class="app-market-summary-label">Providers</span>
<strong id="pricesSummaryProviders">0</strong>
</div>
</div>
<div class="col-6 col-lg">
<div class="app-market-summary-card">
<span class="app-market-summary-label">Ready</span>
<strong id="pricesSummaryReady">0</strong>
</div>
</div>
<div class="col-6 col-lg">
<div class="app-market-summary-card">
<span class="app-market-summary-label">Observed</span>
<strong id="pricesSummaryObserved">0</strong>
</div>
</div>
<div class="col-6 col-lg">
<div class="app-market-summary-card">
<span class="app-market-summary-label">Attention</span>
<strong id="pricesSummaryAttention">0</strong>
</div>
</div>
<div class="col-12 col-lg">
<div class="app-market-summary-card">
<span class="app-market-summary-label">Refreshing</span>
<strong id="pricesSummaryLoading">0</strong>
</div>
</div>
</div>
<div id="pricesLoading" class="app-placeholder">
<div>
<i class="fa-solid fa-spinner fa-spin text-body-secondary mb-3" aria-hidden="true"></i>
<h2 class="h5">Chargement du registry</h2>
<p class="text-body-secondary mb-0">Projection de l'inventaire provider-neutral depuis le runtime backend.</p>
</div>
</div>
<div id="pricesEmpty" class="app-placeholder" hidden>
<div>
<i class="fa-solid fa-table-list text-body-secondary mb-3" aria-hidden="true"></i>
<h2 class="h5">Aucun provider configuré</h2>
<p class="text-body-secondary mb-0">Le runtime Off-chain ne contient actuellement aucune ligne provider.</p>
</div>
</div>
<div id="pricesDiagnostic" class="alert alert-warning mb-3" role="status" aria-live="polite" hidden></div>
<div id="pricesTableContainer" class="table-responsive app-market-table-container" hidden>
<table id="marketPriceTable" class="table table-hover align-middle mb-0 app-market-table">
<caption class="visually-hidden">Providers SOL/USD, disponibilité, prix exacts, fraîcheur et actions de refresh.</caption>
<thead>
<tr>
<th scope="col" class="app-market-selection-column">
<input id="selectAllProviders" class="form-check-input" type="checkbox" aria-label="Select all providers" disabled>
</th>
<th scope="col">Provider</th>
<th scope="col">Pair</th>
<th scope="col" class="d-none d-xl-table-cell">Semantics</th>
<th scope="col" class="d-none d-xl-table-cell">Auth</th>
<th scope="col">Availability</th>
<th scope="col">Exact price</th>
<th scope="col" class="app-market-time-column">Observation times</th>
<th scope="col" class="app-market-time-column">Retry</th>
<th scope="col" class="text-end">Action</th>
</tr>
</thead>
<tbody id="marketPriceRows"></tbody>
</table>
</div>
</section>
<section data-view-panel="diagnostics" hidden>
<div class="d-flex align-items-center justify-content-between mb-4">
<div>
<h1 class="h3 mb-1">Diagnostics</h1>
<p class="text-body-secondary mb-0">État sûr du bootstrap Config, Logging et runtime prix provider-neutral.</p>
</div>
</div>
<div class="card shadow-sm">
<div class="card-header fw-semibold">Runtime</div>
<div class="card-body">
<dl class="row mb-0 app-runtime-list">
<dt class="col-sm-5">Version</dt>
<dd id="runtimeVersion" class="col-sm-7"></dd>
<dt class="col-sm-5">Phase</dt>
<dd id="runtimeShellPhase" class="col-sm-7"></dd>
<dt class="col-sm-5">Documents Config</dt>
<dd id="runtimeConfigDocuments" class="col-sm-7"></dd>
<dt class="col-sm-5">Profil composite</dt>
<dd id="runtimeCompositeProfile" class="col-sm-7"></dd>
<dt class="col-sm-5">Profil Off-chain</dt>
<dd id="runtimeOffchainProfile" class="col-sm-7"></dd>
<dt class="col-sm-5">Providers</dt>
<dd id="runtimeProviderCount" class="col-sm-7"></dd>
<dt class="col-sm-5">Providers ready</dt>
<dd id="runtimeReadyProviderCount" class="col-sm-7"></dd>
<dt class="col-sm-5">Providers unavailable</dt>
<dd id="runtimeUnavailableProviderCount" class="col-sm-7"></dd>
<dt class="col-sm-5">Profil Logging</dt>
<dd id="runtimeLoggingProfile" class="col-sm-7"></dd>
<dt class="col-sm-5">Fallback Logging</dt>
<dd id="runtimeLoggingFallback" class="col-sm-7"></dd>
</dl>
<div id="runtimeDiagnostic" class="alert alert-warning mt-3 mb-0" role="status" aria-live="polite" hidden></div>
</div>
</div>
</section>
</div>
</div>
</div>
</section>
</div>
</main>
<footer class="app-footer bg-dark text-light">
<div class="container h-100 d-flex align-items-center justify-content-center">
<small>&copy; 2026 SASEDEV</small>
</div>
</footer>
<script type="module" src="ts/main.ts" defer></script>
</body>
</html>