feat(frontend,backend): simple navigation bar added

This commit is contained in:
2026-09-30 17:01:53 +04:00
parent e13d45401f
commit a831ec2546
5 changed files with 195 additions and 39 deletions
+47 -1
View File
@@ -4,6 +4,21 @@ from typing import Dict
web_router = APIRouter() web_router = APIRouter()
# Navigation configuration - NEW TABS GO HERE!
NAVIGATION = [
{"name": "home", "label": "Home", "url": "/", "icon": "bi-house"},
{"name": "benchmark", "label": "Benchmark", "url": "/benchmark", "icon": "bi-hdd"},
{"name": "jobs", "label": "Job Queue", "url": "/jobs", "icon": "bi-list-task"},
]
def get_active_tab(url: str) -> str:
"""Determine which navigation tab is active."""
for nav_item in NAVIGATION:
if nav_item["url"] == url:
return nav_item["name"]
return "home"
@web_router.get("/") @web_router.get("/")
async def render_home(request: Request): async def render_home(request: Request):
""" """
@@ -14,6 +29,37 @@ async def render_home(request: Request):
name="index.html", name="index.html",
request=request, request=request,
context={ context={
"tools":tools "tools":tools,
"navigation": NAVIGATION,
"active_tab": get_active_tab("/")
}
)
@web_router.get("/benchmark")
async def render_benchmark(request: Request):
"""Render the benchmark page."""
templates: Jinja2Templates = request.app.state.templates
return templates.TemplateResponse(
name="benchmark.html",
request=request,
context={
"navigation": NAVIGATION,
"active_tab": get_active_tab("/benchmark")
}
)
@web_router.get("/jobs")
async def render_jobs(request: Request):
"""Render the job queue page."""
templates: Jinja2Templates = request.app.state.templates
return templates.TemplateResponse(
name="jobs.html",
request=request,
context={
"navigation": NAVIGATION,
"active_tab": get_active_tab("/jobs")
} }
) )
+32 -5
View File
@@ -3,20 +3,47 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Disk Checker</title> <title>Disk Checker - {% block title %}Home{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
rel="stylesheet"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<script src="https://unpkg.com/htmx.org@1.9.10"></script> <script src="https://unpkg.com/htmx.org@1.9.10"></script>
<link rel="stylesheet" href="/static/css/style.css"> <link rel="stylesheet" href="/static/css/style.css">
{% block extra_css %}{% endblock %}
</head> </head>
<body> <body>
<!-- Navigation Bar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container"> <div class="container">
<a class="navbar-brand" href="/">Disk Checker</a> <!-- Logo / Brand -->
<a class="navbar-brand" href="/">
<i class="bi bi-hdd-stack"></i>
Disk Checker
</a>
<!-- Mobile toggle -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Navigation Tabs -->
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
{% for nav_item in navigation %}
<li class="nav-item">
<a class="nav-link {% if active_tab == nav_item.name %}active{% endif %}"
href="{{ nav_item.url }}">
<i class="bi {{ nav_item.icon }}"></i>
{{ nav_item.label }}
</a>
</li>
{% endfor %}
</ul>
</div>
</div> </div>
</nav> </nav>
<div class="container"> <!-- Page Content -->
<div class="container mt-4">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
+23
View File
@@ -0,0 +1,23 @@
{% extends "base.html" %}
{% block title %}Benchmark{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h2>Benchmark</h2>
<p class="text-muted">Configure and run disk benchmarks.</p>
<!-- Placeholder content - will be implemented later -->
<div class="card">
<div class="card-body">
<h5 class="card-title">Select Drive</h5>
<p class="card-text">Choose a drive to benchmark from the list below.</p>
<!-- Drive selection will go here -->
<div id="drive-selector"></div>
</div>
</div>
</div>
</div>
{% endblock %}
+9 -3
View File
@@ -1,8 +1,10 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block title %}Home{% endblock %}
<div class="container mt-4">
{% block content %}
<div class="row">
<div class="col-12">
<!--Available tools section--> <!--Available tools section-->
<h2>Available Benchmarking Tools</h2> <h2>Available Benchmarking Tools</h2>
@@ -37,9 +39,13 @@
<i class="bi bi-info-circle"></i> <i class="bi bi-info-circle"></i>
Mounted drives are grayed out and cannot be benchmarked. Mounted drives are grayed out and cannot be benchmarked.
</p> </p>
<div id="drives-list" hx-get="/api/v1/drives" hx-trigger="load" hx-target="#drives-content"></div> <div id="drives-list"
hx-get="/api/v1/drives"
hx-trigger="load"
hx-target="#drives-content"></div>
<div id="drives-content" class="row"></div> <div id="drives-content" class="row"></div>
</div> </div>
</div>
{% endblock %} {% endblock %}
{% block extra_js %} {% block extra_js %}
+54
View File
@@ -0,0 +1,54 @@
{% extends "base.html" %}
{% block title %}Job Queue{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h2>Job Queue</h2>
<p class="text-muted">Monitor and manage benchmark jobs.</p>
<!-- Jobs list -->
<div id="jobs-list"
hx-get="/api/v1/jobs"
hx-trigger="load"
hx-target="#jobs-content">
<p>Loading jobs...</p>
</div>
<div id="jobs-content"></div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Load jobs when page loads
document.addEventListener('htmx:afterRequest', function(evt) {
if (evt.detail.target.id === 'jobs-content') {
renderJobs(JSON.parse(evt.detail.xhr.response));
}
});
function renderJobs(jobIds) {
const container = document.getElementById('jobs-content');
container.innerHTML = '';
if (!jobIds || jobIds.length === 0) {
container.innerHTML = '<div class="alert alert-info">No jobs in queue.</div>';
return;
}
jobIds.forEach(jobId => {
const div = document.createElement('div');
div.className = 'card mb-2';
div.innerHTML = `
<div class="card-body">
<h5 class="card-title">${jobId}</h5>
<p class="card-text text-muted">Job details will appear here...</p>
</div>
`;
container.appendChild(div);
});
}
</script>
{% endblock %}