Added new codebook page
This commit is contained in:
926
client/public/index.html
Normal file
926
client/public/index.html
Normal file
@@ -0,0 +1,926 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>MRS Dashboard</title>
|
||||
<link rel="icon" href="/favicon.png">
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
|
||||
min-height: 100vh;
|
||||
color: #fff;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: rgba(15, 23, 42, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 1.5rem 2rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
grid-template-areas: "logo status clocks";
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.logo-section {
|
||||
grid-area: logo;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.logo-section img {
|
||||
height: 3rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.05rem;
|
||||
}
|
||||
|
||||
.hostname {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.header-info {
|
||||
grid-area: clocks;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.network-status-wrapper {
|
||||
grid-area: status;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.network-status {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.network-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.4rem;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.network-item:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.network-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.expand-toggle {
|
||||
cursor: pointer;
|
||||
padding: 0.4rem;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.expand-toggle:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.expand-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke: #94a3b8;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.expand-icon.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.expanded-status {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
.expanded-status.visible {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.status-tiles {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem 0;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.status-tiles::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.status-tiles::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.status-tiles::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.status-tiles::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.status-tile {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
justify-content: space-between;
|
||||
flex: 0 0 auto;
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
.tile-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.tile-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.tile-name {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05rem;
|
||||
}
|
||||
|
||||
.tile-info {
|
||||
font-size: 0.85rem;
|
||||
color: #94a3b8;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.tile-detail {
|
||||
font-size: 0.75rem;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.network-item.disconnected .network-icon,
|
||||
.status-tile.disconnected .tile-icon {
|
||||
stroke: #64748b;
|
||||
}
|
||||
|
||||
.status-tile.disconnected .tile-name {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.status-tile.connected {
|
||||
border-color: rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.network-item.connected .network-icon,
|
||||
.status-tile.connected .tile-icon {
|
||||
stroke: #10b981;
|
||||
}
|
||||
|
||||
.status-tile.connected .tile-name {
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.time-display {
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.time-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.time-label {
|
||||
color: #94a3b8;
|
||||
font-size: 0.7rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.time-value {
|
||||
font-weight: 600;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.time-date {
|
||||
color: #64748b;
|
||||
font-size: 0.75rem;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 1rem 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.search-bar:focus-within {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke: #64748b;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
background: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.apps-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.app-item {
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.second-action {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: -10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
border-radius: 50%;
|
||||
background: #5a6b63;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.second-action:hover {
|
||||
background: #6a7b73;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.second-action:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.second-action img {
|
||||
stroke: white;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.app-badge svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
stroke: #fff;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.app-icon-wrapper {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.app-item:hover .app-icon-wrapper {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.app-item:active .app-icon-wrapper {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
#temp {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.app-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
stroke: #fff;
|
||||
stroke-width: 1.5;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.app-name {
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.tile-wide {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.system-metrics {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.system-metric {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
color: #cdd5e0;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.metric-label span {
|
||||
font-size: 0.7rem;
|
||||
color: #94a3b8;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
flex-grow: 1;
|
||||
height: 14px;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar-fill {
|
||||
height: 100%;
|
||||
background: #10b981;
|
||||
border-radius: 6px;
|
||||
transition: width 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.progress-bar-text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #fff;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Responsive breakpoints */
|
||||
@media (max-width: 800px) {
|
||||
.header-content {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-areas:
|
||||
"logo clocks"
|
||||
"status status";
|
||||
justify-items: start;
|
||||
}
|
||||
|
||||
.logo-section {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.header-info {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.network-status-wrapper {
|
||||
justify-self: center;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 550px) {
|
||||
.header-content {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"logo"
|
||||
"clocks"
|
||||
"status";
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.logo-section {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.header-info {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.time-display {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.time-block {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="header-content">
|
||||
<div class="logo-section">
|
||||
<img src="/favicon.png" alt="Logo">
|
||||
<div>
|
||||
<div class="logo">DASHBOARD</div>
|
||||
<div class="hostname">Hostname</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-info">
|
||||
<div class="time-display">
|
||||
<div class="time-block">
|
||||
<div class="time-label">Local</div>
|
||||
<div class="time-value" id="local-time">00:00:00</div>
|
||||
<div class="time-date" id="local-date">Jan 1, 2025</div>
|
||||
</div>
|
||||
<div class="time-block">
|
||||
<div class="time-label">Zulu / UTC</div>
|
||||
<div class="time-value" id="zulu-time">00:00:00</div>
|
||||
<div class="time-date" id="zulu-date">Jan 1, 2025</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="network-status-wrapper">
|
||||
<div class="network-status">
|
||||
<div class="network-item disconnected" id="gps-status">
|
||||
<svg class="network-icon" viewBox="0 0 24 24">
|
||||
<g transform="translate(2,2) rotate(-45 12 12)">
|
||||
<rect x="9.5" y="1" width="5" height="8.5" rx="1" ry="1" fill="transparent"/>
|
||||
<rect x="1" y="6" width="6" height="4"/>
|
||||
<rect x="17" y="6" width="6" height="4"/>
|
||||
<line x1="1" y1="8" x2="23" y2="8"/>
|
||||
<defs>
|
||||
<clipPath id="halfCircle">
|
||||
<rect x="0" y="5" width="100%" height="42%" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<circle cx="12" cy="17.5" r="6px" clip-path="url(#halfCircle)" fill="transparent" />
|
||||
<line x1="12" y1="12" x2="12" y2="17" stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="network-item connected" id="lora-status">
|
||||
<svg class="network-icon" viewBox="0 0 24 24">
|
||||
<line x1="0" y1="18" x2="8" y2="6"/>
|
||||
<line x1="8" y1="18" x2="16" y2="6"/>
|
||||
<line x1="16" y1="6" x2="24" y2="18"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="network-item connected" id="mesh-status">
|
||||
<svg class="network-icon" viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="5" cy="5" r="2" />
|
||||
<line x1="6" y1="6" x2="15" y2="4" />
|
||||
<line x1="6" y1="6" x2="20" y2="12" />
|
||||
<line x1="6" y1="6" x2="13.5" y2="19" />
|
||||
<line x1="6" y1="6" x2="5" y2="15" />
|
||||
<circle cx="15.5" cy="3" r="2" />
|
||||
<line x1="15" y1="4" x2="20" y2="12" />
|
||||
<line x1="15" y1="4" x2="13.5" y2="19" />
|
||||
<line x1="15" y1="4" x2="5" y2="15" />
|
||||
<circle cx="21" cy="12" r="2" />
|
||||
<line x1="20" y1="12" x2="13.5" y2="19" />
|
||||
<circle cx="14" cy="20.5" r="2" />
|
||||
<line x1="13.5" y1="19" x2="5" y2="15" />
|
||||
<circle cx="4" cy="16" r="2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="network-item connected" id="wifi-status">
|
||||
<svg class="network-icon" viewBox="0 0 24 24">
|
||||
<path d="M5 12.55a11 11 0 0 1 14.08 0"/>
|
||||
<path d="M1.42 9a16 16 0 0 1 21.16 0"/>
|
||||
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
|
||||
<line x1="12" y1="20" x2="12.01" y2="20"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="network-item disconnected" id="ethernet-status">
|
||||
<svg class="network-icon" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="5" y="9" width="14" height="10" rx="1" ry="1"/>
|
||||
<rect x="9" y="5" width="6" height="4" rx="0.5" ry="0.5"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="expand-toggle" id="expand-toggle">
|
||||
<svg class="expand-icon" id="expand-icon" viewBox="0 0 24 24">
|
||||
<polyline points="6 9 12 15 18 9"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="expanded-status" id="expanded-status">
|
||||
<div class="status-tiles">
|
||||
<div class="status-tile connected tile-wide" id="system-tile">
|
||||
<div class="tile-header">
|
||||
<svg class="tile-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect>
|
||||
<rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect>
|
||||
<line x1="6" y1="6" x2="6.01" y2="6"></line>
|
||||
<line x1="10" y1="6" x2="10.01" y2="6"></line>
|
||||
<line x1="6" y1="18" x2="6.01" y2="18"></line>
|
||||
<line x1="10" y1="18" x2="10.01" y2="18"></line>
|
||||
</svg>
|
||||
<div class="tile-name">System <span id="temp">?°C</span></div>
|
||||
</div>
|
||||
<div class="system-metrics">
|
||||
<div class="system-metric">
|
||||
<div class="metric-label">CPU <span id="load">- Load</span></div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-fill" id="cpu-usage-fill"></div>
|
||||
<div class="progress-bar-text" id="cpu-usage-text">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="system-metric">
|
||||
<div class="metric-label">Memory</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-fill" id="memory-usage-fill"></div>
|
||||
<div class="progress-bar-text" id="memory-usage-text">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="system-metric">
|
||||
<div class="metric-label">Disk</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-fill" id="disk-usage-fill"></div>
|
||||
<div class="progress-bar-text" id="disk-usage-text">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-tile disconnected" id="gps-tile">
|
||||
<div class="tile-header">
|
||||
<svg class="tile-icon" viewBox="0 0 24 24">
|
||||
<g transform="translate(2,2) rotate(-45 12 12)">
|
||||
<rect x="9.5" y="1" width="5" height="8.5" rx="1" ry="1" fill="transparent" />
|
||||
<rect x="1" y="6" width="6" height="4"/>
|
||||
<rect x="17" y="6" width="6" height="4"/>
|
||||
<line x1="1" y1="8" x2="23" y2="8"/>
|
||||
<defs>
|
||||
<clipPath id="halfCircle">
|
||||
<rect x="0" y="5" width="100%" height="42%" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<circle cx="12" cy="17.5" r="6px" clip-path="url(#halfCircle)" fill="transparent" />
|
||||
<line x1="12" y1="12" x2="12" y2="17" stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
||||
<div class="tile-name">GPS</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tile-info">39.2000, -49.0000</div>
|
||||
<div class="tile-detail">No Fix</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-tile disconnected" id="lora-tile">
|
||||
<div class="tile-header">
|
||||
<svg class="tile-icon" viewBox="0 0 24 24">
|
||||
<line x1="0" y1="18" x2="8" y2="6"/>
|
||||
<line x1="8" y1="18" x2="16" y2="6"/>
|
||||
<line x1="16" y1="6" x2="24" y2="18"/>
|
||||
</svg>
|
||||
<div class="tile-name">LoRa</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tile-info">0 / 0 Online</div>
|
||||
<div class="tile-detail">Ch 0% Air 0%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-tile connected" id="mesh-tile">
|
||||
<div class="tile-header">
|
||||
<svg class="tile-icon" viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="5" cy="5" r="2" />
|
||||
<line x1="6" y1="6" x2="15" y2="4" />
|
||||
<line x1="6" y1="6" x2="20" y2="12" />
|
||||
<line x1="6" y1="6" x2="13.5" y2="19" />
|
||||
<line x1="6" y1="6" x2="5" y2="15" />
|
||||
<circle cx="15.5" cy="3" r="2" />
|
||||
<line x1="15" y1="4" x2="20" y2="12" />
|
||||
<line x1="15" y1="4" x2="13.5" y2="19" />
|
||||
<line x1="15" y1="4" x2="5" y2="15" />
|
||||
<circle cx="21" cy="12" r="2" />
|
||||
<line x1="20" y1="12" x2="13.5" y2="19" />
|
||||
<circle cx="14" cy="20.5" r="2" />
|
||||
<line x1="13.5" y1="19" x2="5" y2="15" />
|
||||
<circle cx="4" cy="16" r="2" />
|
||||
</svg>
|
||||
<div class="tile-name">Mesh</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tile-info">Connected</div>
|
||||
<div class="tile-detail">900 Mhz -45 dBm</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-tile connected" id="wifi-tile">
|
||||
<div class="tile-header">
|
||||
<svg class="tile-icon" viewBox="0 0 24 24">
|
||||
<path d="M5 12.55a11 11 0 0 1 14.08 0"/>
|
||||
<path d="M1.42 9a16 16 0 0 1 21.16 0"/>
|
||||
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
|
||||
<line x1="12" y1="20" x2="12.01" y2="20"/>
|
||||
</svg>
|
||||
<div class="tile-name">WiFi</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tile-info">Access Point</div>
|
||||
<div class="tile-detail">SSID: Hostname</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-tile disconnected" id="ethernet-tile">
|
||||
<div class="tile-header">
|
||||
<svg class="tile-icon" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="5" y="9" width="14" height="10" rx="1" ry="1"/>
|
||||
<rect x="9" y="5" width="6" height="4" rx="0.5" ry="0.5"/>
|
||||
</svg>
|
||||
<div class="tile-name">Ethernet</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tile-info">Disconnected</div>
|
||||
<div class="tile-detail">No cable detected</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="search-bar">
|
||||
<svg class="search-icon" viewBox="0 0 24 24">
|
||||
<circle cx="11" cy="11" r="8"/>
|
||||
<path d="m21 21-4.35-4.35"/>
|
||||
</svg>
|
||||
<input type="text" class="search-input" placeholder="Search apps..." id="search-input">
|
||||
</div>
|
||||
|
||||
<div class="apps-grid" id="apps-grid">
|
||||
<a href=":1000" class="app-item" data-name="AI Assistant">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<rect x="6" y="6" width="12" height="12" rx="2" ry="2"/>
|
||||
<line x1="2" y1="9" x2="6" y2="9"/>
|
||||
<line x1="2" y1="12" x2="6" y2="12"/>
|
||||
<line x1="2" y1="15" x2="6" y2="15"/>
|
||||
<line x1="18" y1="9" x2="22" y2="9"/>
|
||||
<line x1="18" y1="12" x2="22" y2="12"/>
|
||||
<line x1="18" y1="15" x2="22" y2="15"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="app-name">AI Assistant</div>
|
||||
</a>
|
||||
|
||||
<a href=":1100" class="app-item" data-name="ATAK">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
|
||||
</svg>
|
||||
<div class="second-action">
|
||||
<img class="app-icon" src="/icons/download.svg" alt="Download" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">ATAK</div>
|
||||
</a>
|
||||
|
||||
<a href="/code-book.html" class="app-item" data-name="Code Book">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
|
||||
</svg>
|
||||
<div class="second-action">
|
||||
<img class="app-icon" src="/icons/download.svg" alt="Download" onclick="saveCodeBook(event)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">Code Book</div>
|
||||
</a>
|
||||
|
||||
<a href=":1200" class="app-item" data-name="Remote Desktop">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
|
||||
<line x1="8" y1="21" x2="16" y2="21"/>
|
||||
<line x1="12" y1="17" x2="12" y2="21"/>
|
||||
</svg>
|
||||
<div class="second-action">
|
||||
<img class="app-icon" src="/icons/download.svg" alt="Download" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">Desktop</div>
|
||||
</a>
|
||||
|
||||
<a href=":1300" class="app-item" data-name="File Browser">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="app-name">File Browser</div>
|
||||
</a>
|
||||
|
||||
<a href=":1400" class="app-item" data-name="Library">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/>
|
||||
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>
|
||||
</svg>
|
||||
<div class="second-action" onclick="openKiwixm(event)">
|
||||
<img class="app-icon" src="/icons/cog.svg" alt="Download" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">Library</div>
|
||||
</a>
|
||||
|
||||
<a href=":1500" class="app-item" data-name="Maps">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<path d="M3 7l6-3 6 3 6-3v13l-6 3-6-3-6 3z"/>
|
||||
<line x1="9" y1="4" x2="9" y2="17"/>
|
||||
<line x1="15" y1="7" x2="15" y2="20"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="app-name">Maps</div>
|
||||
</a>
|
||||
|
||||
<a href=":1600" class="app-item" data-name="Meshtastic">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<line x1="0" y1="18" x2="8" y2="6"/>
|
||||
<line x1="8" y1="18" x2="16" y2="6"/>
|
||||
<line x1="16" y1="6" x2="24" y2="18"/>
|
||||
</svg>
|
||||
<div class="second-action">
|
||||
<img class="app-icon" src="/icons/download.svg" alt="Download" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">Meshtastic</div>
|
||||
</a>
|
||||
|
||||
<a href=":1700" class="app-item" data-name="Messages">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
||||
</svg>
|
||||
<div class="second-action">
|
||||
<img class="app-icon" src="/icons/download.svg" alt="Download" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">Messages</div>
|
||||
</a>
|
||||
|
||||
<a href=":1800" class="app-item" data-name="Pentesting">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M267 48C230.6 48 209.2 106.3 198.7 160L168 160C154.7 160 144 170.7 144 184C144 197.3 154.7 208 168 208L192 208L192 240C192 257 195.3 273.2 201.3 288L192 288L192 288L171.5 288C156.3 288 144 300.3 144 315.5C144 318.5 144.5 321.4 145.4 324.2L174.3 410.8C136.2 443.6 112 492.1 112 546.3C112 562.7 125.3 576 141.7 576L498.3 576C514.7 576 528 562.7 528 546.3C528 492.1 503.8 443.6 465.7 410.9L494.6 324.3C495.5 321.5 496 318.6 496 315.6C496 300.4 483.7 288.1 468.5 288.1L448 288.1L448 288.1L438.7 288.1C444.7 273.3 448 257.1 448 240.1L448 208.1L472 208.1C485.3 208.1 496 197.4 496 184.1C496 170.8 485.3 160.1 472 160.1L441.3 160.1C430.9 106.4 409.4 48.1 373 48.1C363.4 48.1 354 52 345.5 56.3C337.3 60.4 327.1 64.1 320 64.1C312.9 64.1 302.7 60.4 294.5 56.3C286 51.9 276.6 48 267 48zM360.7 532.4L335.9 461.5L363.8 429C366.5 425.8 368 421.8 368 417.6C368 407.9 360.2 400.1 350.5 400.1L289.5 400.1C279.8 400.1 272 407.9 272 417.6C272 421.8 273.5 425.8 276.2 429L304.1 461.5L279.3 532.4L222.3 352L258 352C276.4 362.2 297.5 368 320 368C342.5 368 363.6 362.2 382 352L417.7 352L360.7 532.4zM320 320C285.3 320 255.8 297.9 244.7 267C250.4 270.2 257 272 264 272L276.4 272C292.9 272 307.5 261.4 312.7 245.8C315 238.8 324.9 238.8 327.2 245.8C332.4 261.4 347.1 272 363.5 272L375.9 272C382.9 272 389.5 270.2 395.2 267C384.1 297.9 354.6 320 319.9 320z"/></svg>
|
||||
</div>
|
||||
<div class="app-name">Pentesting</div>
|
||||
</a>
|
||||
|
||||
<a href=":1900" class="app-item" data-name="Software Defined Radio">
|
||||
<div class="app-icon-wrapper">
|
||||
<svg class="app-icon" viewBox="0 0 24 24">
|
||||
<g transform="translate(0,-2)">
|
||||
<circle cx="12" cy="12" r="1.5"/>
|
||||
<path d="M16.24 7.76a6 6 0 0 1 0 8.49"/>
|
||||
<path d="M7.76 16.24a6 6 0 0 1 0-8.49"/>
|
||||
<path d="M19.07 4.93a10 10 0 0 1 0 14.14"/>
|
||||
<path d="M4.93 19.07a10 10 0 0 1 0-14.14"/>
|
||||
<line x1="12" y1="10" x2="12" y2="24"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="second-action">
|
||||
<img class="app-icon" src="/icons/download.svg" alt="Download" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-name">SDR</div>
|
||||
</a>
|
||||
|
||||
<a href=":2000" class="app-item" data-name="Speed Test">
|
||||
<div class="app-icon-wrapper">
|
||||
<img src="/icons/open-sight.png" alt="OpenSight" style="height: 40px; width: auto;" />
|
||||
</div>
|
||||
<div class="app-name">Intelligence</div>
|
||||
</a>
|
||||
|
||||
<a href=":2100" class="app-item" data-name="Speed Test">
|
||||
<div class="app-icon-wrapper">
|
||||
<img class="app-icon" src="/icons/guage.svg" />
|
||||
</div>
|
||||
<div class="app-name">Speed Test</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user