feat(ui): add navigation between service pages
This commit is contained in:
@@ -180,6 +180,43 @@ std::string page(Request &, Response &response) {
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.page-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 40px;
|
||||
border: 1px solid var(--control-border);
|
||||
border-radius: 999px;
|
||||
background: var(--control-bg);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
padding: 9px 13px;
|
||||
text-decoration: none;
|
||||
transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
.page-link:hover {
|
||||
background: var(--control-hover);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.page-link:focus-visible {
|
||||
outline: 3px solid rgba(99, 179, 237, 0.35);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.page-link svg {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
flex: 0 0 auto;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.9;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.menu-wrap {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
@@ -681,6 +718,22 @@ std::string page(Request &, Response &response) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a class="page-link" href="/version" aria-label="Open version page">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M20.6 13.2 13.2 20.6a2 2 0 0 1-2.8 0L3.4 13.6a2 2 0 0 1-.6-1.4V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7.2 7.2a2 2 0 0 1 0 2.8Z"></path>
|
||||
<circle cx="7.5" cy="7.5" r="1.2"></circle>
|
||||
</svg>
|
||||
<span data-lang="en">Version</span><span data-lang="zh">版本信息</span>
|
||||
</a>
|
||||
<a class="page-link" href="/inspect" aria-label="Open inspector">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<circle cx="11" cy="11" r="6"></circle>
|
||||
<path d="m16 16 4 4"></path>
|
||||
<path d="M8.5 11h5"></path>
|
||||
<path d="M11 8.5v5"></path>
|
||||
</svg>
|
||||
<span data-lang="en">Inspector</span><span data-lang="zh">诊断台</span>
|
||||
</a>
|
||||
<button type="button" id="refresh-button">
|
||||
<span data-lang="en">Refresh</span><span data-lang="zh">刷新</span>
|
||||
</button>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "handler/settings.h"
|
||||
#include "utils/logger.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -14,6 +15,21 @@ std::string page(Request &request, Response &response) {
|
||||
LOG_LEVEL_INFO);
|
||||
response.headers["X-Robots-Tag"] =
|
||||
"noindex, nofollow, noarchive, nosnippet, noimageindex";
|
||||
std::string dashboard_link =
|
||||
global.statisticsEnabled
|
||||
? R"html(
|
||||
<a class="page-link" href="/dashboard" aria-label="Open dashboard">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M4 19V5"></path>
|
||||
<path d="M4 19h16"></path>
|
||||
<path d="M8 16v-5"></path>
|
||||
<path d="M13 16V8"></path>
|
||||
<path d="M18 16v-3"></path>
|
||||
</svg>
|
||||
<span data-lang="en">Dashboard</span>
|
||||
<span data-lang="zh">仪表盘</span>
|
||||
</a>)html"
|
||||
: "";
|
||||
|
||||
return R"html(<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -216,6 +232,55 @@ std::string page(Request &request, Response &response) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-links {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 40px;
|
||||
padding: 9px 14px;
|
||||
border: 1px solid var(--control-border);
|
||||
border-radius: 999px;
|
||||
background: var(--control-bg);
|
||||
box-shadow: var(--control-shadow);
|
||||
color: var(--text-primary);
|
||||
font-size: 0.86rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.page-link:hover {
|
||||
background: var(--control-hover);
|
||||
color: var(--text-primary);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.page-link:focus-visible {
|
||||
outline: 3px solid rgba(99, 179, 237, 0.35);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.page-link svg {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
flex: 0 0 auto;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.9;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: var(--container-bg);
|
||||
backdrop-filter: blur(24px);
|
||||
@@ -727,6 +792,17 @@ std::string page(Request &request, Response &response) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.page-links {
|
||||
margin-top: 16px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
min-height: 38px;
|
||||
padding: 8px 12px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.request-preview {
|
||||
max-height: 150px;
|
||||
}
|
||||
@@ -779,6 +855,17 @@ std::string page(Request &request, Response &response) {
|
||||
<span data-lang="en">Explain conversion without writing managed output</span>
|
||||
<span data-lang="zh">以只读方式解释转换结果</span>
|
||||
</p>
|
||||
<nav class="page-links" aria-label="Page navigation">
|
||||
<a class="page-link" href="/version" aria-label="Open version page">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M20.6 13.2 13.2 20.6a2 2 0 0 1-2.8 0L3.4 13.6a2 2 0 0 1-.6-1.4V5a2 2 0 0 1 2-2h7.2a2 2 0 0 1 1.4.6l7.2 7.2a2 2 0 0 1 0 2.8Z"></path>
|
||||
<circle cx="7.5" cy="7.5" r="1.2"></circle>
|
||||
</svg>
|
||||
<span data-lang="en">Version</span>
|
||||
<span data-lang="zh">版本信息</span>
|
||||
</a>)html" +
|
||||
dashboard_link + R"html(
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<section class="section">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "handler/settings.h"
|
||||
#include "version.h"
|
||||
|
||||
namespace {
|
||||
@@ -112,6 +113,21 @@ std::string page(Request &, Response &response) {
|
||||
? R"html(<span data-lang="en">unknown</span><span data-lang="zh">未知</span>)html"
|
||||
: build_date_display;
|
||||
std::string commit_link = buildCommitLink(build_id);
|
||||
std::string dashboard_link =
|
||||
global.statisticsEnabled
|
||||
? R"html(
|
||||
<a class="page-link" href="/dashboard" aria-label="Open dashboard">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M4 19V5"></path>
|
||||
<path d="M4 19h16"></path>
|
||||
<path d="M8 16v-5"></path>
|
||||
<path d="M13 16V8"></path>
|
||||
<path d="M18 16v-3"></path>
|
||||
</svg>
|
||||
<span data-lang="en">Dashboard</span>
|
||||
<span data-lang="zh">仪表盘</span>
|
||||
</a>)html"
|
||||
: "";
|
||||
|
||||
return R"html(<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -305,6 +321,59 @@ std::string page(Request &, Response &response) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-links {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 40px;
|
||||
padding: 9px 14px;
|
||||
border: 1px solid var(--control-border);
|
||||
border-radius: 999px;
|
||||
background: var(--control-bg);
|
||||
box-shadow: var(--control-shadow);
|
||||
color: var(--text-primary);
|
||||
font-size: 0.86rem;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.page-link:hover {
|
||||
background: var(--control-hover);
|
||||
color: var(--text-primary);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.page-link::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-link:focus-visible {
|
||||
outline: 3px solid rgba(99, 179, 237, 0.35);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.page-link svg {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
flex: 0 0 auto;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.9;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: var(--container-bg);
|
||||
backdrop-filter: blur(24px);
|
||||
@@ -664,6 +733,15 @@ std::string page(Request &, Response &response) {
|
||||
font-size: 0.72rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.page-links {
|
||||
margin-top: 16px;
|
||||
gap: 8px;
|
||||
}
|
||||
.page-link {
|
||||
min-height: 38px;
|
||||
padding: 8px 12px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.info-grid { grid-template-columns: 1fr; gap: 12px; }
|
||||
.info-card {
|
||||
min-height: auto;
|
||||
@@ -709,6 +787,19 @@ std::string page(Request &, Response &response) {
|
||||
<span data-lang="en">A Modern Evolution of Subconverter</span>
|
||||
<span data-lang="zh">Subconverter 的现代化演进版本</span>
|
||||
</p>
|
||||
<nav class="page-links" aria-label="Page navigation">
|
||||
<a class="page-link" href="/inspect" aria-label="Open inspector">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<circle cx="11" cy="11" r="6"></circle>
|
||||
<path d="m16 16 4 4"></path>
|
||||
<path d="M8.5 11h5"></path>
|
||||
<path d="M11 8.5v5"></path>
|
||||
</svg>
|
||||
<span data-lang="en">Inspector</span>
|
||||
<span data-lang="zh">诊断台</span>
|
||||
</a>)html" +
|
||||
dashboard_link + R"html(
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="info-grid">
|
||||
|
||||
Reference in New Issue
Block a user