feat: add CSS styles and JavaScript functionality for projects and scenarios, including filtering and layout enhancements
This commit is contained in:
@@ -9,4 +9,5 @@ jinja2
|
||||
pandas
|
||||
numpy
|
||||
passlib
|
||||
python-jose
|
||||
python-jose
|
||||
python-multipart
|
||||
109
static/css/projects.css
Normal file
109
static/css/projects.css
Normal file
@@ -0,0 +1,109 @@
|
||||
:root {
|
||||
--card-bg: rgba(21, 27, 35, 0.8);
|
||||
--card-border: rgba(255, 255, 255, 0.08);
|
||||
--hover-highlight: rgba(241, 178, 26, 0.12);
|
||||
}
|
||||
|
||||
.projects-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: var(--table-radius);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.projects-table th,
|
||||
.projects-table td {
|
||||
padding: 0.875rem 1rem;
|
||||
border-bottom: 1px solid var(--card-border);
|
||||
background: var(--card-bg);
|
||||
}
|
||||
|
||||
.projects-table tbody tr:hover {
|
||||
background: var(--hover-highlight);
|
||||
}
|
||||
|
||||
.definition-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1.25rem 2rem;
|
||||
}
|
||||
|
||||
.definition-list dt {
|
||||
font-weight: 600;
|
||||
color: var(--muted);
|
||||
margin-bottom: 0.2rem;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.definition-list dd {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--card-border);
|
||||
box-shadow: var(--shadow);
|
||||
border-radius: var(--radius);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-header h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: var(--radius-sm);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: rgba(209, 75, 75, 0.2);
|
||||
border: 1px solid rgba(209, 75, 75, 0.4);
|
||||
color: var(--color-text-invert);
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
padding: 0.75rem 0.85rem;
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--card-border);
|
||||
background: rgba(8, 12, 19, 0.75);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
78
static/css/scenarios.css
Normal file
78
static/css/scenarios.css
Normal file
@@ -0,0 +1,78 @@
|
||||
.scenario-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: var(--table-radius);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.table th,
|
||||
.table td {
|
||||
padding: 0.75rem 1rem;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
background: rgba(21, 27, 35, 0.85);
|
||||
}
|
||||
|
||||
.table tbody tr:hover {
|
||||
background: rgba(43, 165, 143, 0.12);
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted);
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
|
||||
.breadcrumb a {
|
||||
color: var(--brand-2);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.6rem 1.1rem;
|
||||
border-radius: var(--radius-sm);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(90deg, var(--brand) 0%, var(--brand-2) 100%);
|
||||
color: var(--color-text-dark);
|
||||
box-shadow: 0 8px 18px rgba(241, 178, 26, 0.25);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: rgba(148, 197, 255, 0.2);
|
||||
color: var(--color-text-invert);
|
||||
border: 1px solid rgba(148, 197, 255, 0.35);
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
padding: 0.35rem 0.5rem;
|
||||
color: var(--brand-3);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn:hover,
|
||||
.btn:focus {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
19
static/js/projects.js
Normal file
19
static/js/projects.js
Normal file
@@ -0,0 +1,19 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const table = document.querySelector("[data-project-table]");
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rows = Array.from(table.querySelectorAll("tbody tr"));
|
||||
const filterInput = document.querySelector("[data-project-filter]");
|
||||
|
||||
if (filterInput) {
|
||||
filterInput.addEventListener("input", () => {
|
||||
const query = filterInput.value.trim().toLowerCase();
|
||||
rows.forEach((row) => {
|
||||
const match = row.textContent.toLowerCase().includes(query);
|
||||
row.style.display = match ? "" : "none";
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,6 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ project.name }} · Project · CalMiner{% endblock %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/projects.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<nav class="breadcrumb">
|
||||
<a href="{{ url_for('projects.project_list_page') }}">Projects</a>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{% if project %}Edit {{ project.name }}{% else %}New Project{% endif %} · CalMiner{% endblock %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/projects.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<nav class="breadcrumb">
|
||||
<a href="{{ url_for('projects.project_list_page') }}">Projects</a>
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Projects · CalMiner{% endblock %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/projects.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="page-header">
|
||||
<div>
|
||||
<h1>Projects</h1>
|
||||
<p class="text-muted">Manage mining projects and explore their scenarios.</p>
|
||||
</div>
|
||||
<a class="btn btn-primary" href="{{ url_for('projects.create_project_form') }}">New Project</a>
|
||||
<div class="actions">
|
||||
<input
|
||||
type="search"
|
||||
class="form-control"
|
||||
placeholder="Filter projects..."
|
||||
data-project-filter
|
||||
/>
|
||||
<a class="btn btn-primary" href="{{ url_for('projects.create_project_form') }}">New Project</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% if projects %}
|
||||
<table class="table">
|
||||
<table class="projects-table" data-project-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
@@ -40,3 +52,8 @@
|
||||
<p>No projects yet. <a href="{{ url_for('projects.create_project_form') }}">Create your first project.</a></p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src="/static/js/projects.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ scenario.name }} · Scenario · CalMiner{% endblock %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/scenarios.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/scenarios.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<nav class="breadcrumb">
|
||||
<a href="{{ url_for('projects.project_list_page') }}">Projects</a>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{% if scenario %}Edit {{ scenario.name }}{% else %}New Scenario{% endif %} · CalMiner{% endblock %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/scenarios.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<nav class="breadcrumb">
|
||||
<a href="{{ url_for('projects.project_list_page') }}">Projects</a>
|
||||
|
||||
Reference in New Issue
Block a user