zkt26/index.html

316 lines
11 KiB
HTML

<!DOCTYPE html>
<!-- Declares this file as an HTML5 document -->
<html lang="en">
<head>
<!-- Sets the character encoding so text displays correctly -->
<meta charset="UTF-8">
<!-- Makes the page responsive on phones and tablets -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- The title shown in the browser tab -->
<title>MongoDB Products Manager</title>
<style>
/* Makes width and height calculations include padding and border */
* { box-sizing: border-box; }
/* Styles the whole page background, spacing, and default font */
body {
font-family: Arial, sans-serif;
background: #f4f4f4;
margin: 0;
padding: 16px;
}
/* Centers the main content and limits how wide it can grow */
.container {
max-width: 1200px;
margin: 0 auto;
}
/* Centers the page headings */
h1, h2 {
text-align: center;
}
/* Reusable white card-style section box */
.box {
background: white;
border-radius: 10px;
padding: 18px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
/* Space below the flash message area */
.messages {
margin-bottom: 16px;
}
/* Base styling for any flash message */
.message {
padding: 10px 12px;
border-radius: 8px;
margin-bottom: 10px;
}
/* Green styling for success messages */
.message.success {
background: #e8f7ec;
color: #1e6b35;
border: 1px solid #bfe5c8;
}
/* Red styling for error messages */
.message.error {
background: #ffe8e8;
color: #8a1f1f;
border: 1px solid #e6bcbc;
}
/* Two-column layout for the "Add Product" form */
.form-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
/* Common styling for text and number inputs */
input[type="text"],
input[type="number"] {
width: 100%;
padding: 8px 10px;
border: 1px solid #bbb;
border-radius: 6px;
}
/* Makes an element span the full width of the form grid */
.full-width {
grid-column: 1 / -1;
}
/* Aligns checkbox and label nicely on one line */
.checkbox-row {
display: flex;
align-items: center;
gap: 8px;
}
/* Shared button styling for real buttons and link-buttons */
button, .btn {
display: inline-block;
padding: 8px 12px;
border: none;
border-radius: 6px;
text-decoration: none;
cursor: pointer;
font-size: 14px;
}
/* Green create button */
.btn-create { background: #28a745; color: white; }
/* Blue edit button */
.btn-edit { background: #007bff; color: white; }
/* Red delete button */
.btn-delete { background: #dc3545; color: white; }
/* Allows horizontal scrolling if the table is too wide */
.table-wrap {
overflow-x: auto;
}
/* Makes the table fill the available width */
table {
width: 100%;
border-collapse: collapse;
min-width: 1000px;
}
/* Styles the table cells */
th, td {
padding: 10px;
border-bottom: 1px solid #ddd;
text-align: left;
vertical-align: middle;
}
/* Light background for table headers */
th {
background: #f0f0f0;
}
/* Places edit and delete actions next to each other */
.actions {
display: flex;
gap: 8px;
align-items: center;
}
/* Message shown when there are no products */
.empty {
text-align: center;
color: #666;
padding: 20px;
}
/* On smaller screens, change the form to one column */
@media (max-width: 800px) {
.form-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<!-- Main centered page wrapper -->
<div class="container">
<!-- Main title of the page -->
<h1>MongoDB Products Manager</h1>
<!-- First card: flash messages and add-product form -->
<div class="box">
<!-- Jinja block: gets flashed messages from Flask -->
{% with messages = get_flashed_messages(with_categories=true) %}
<!-- Only show the message area if there are messages -->
{% if messages %}
<div class="messages">
<!-- Loop through each flashed message -->
{% for category, message in messages %}
<!-- category becomes a CSS class like success or error -->
<div class="message {{ category }}">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<!-- Section heading -->
<h2>Add Product</h2>
<!-- Form for creating a new product -->
<form action="/create" method="POST" class="form-grid">
<!-- Required numeric product ID -->
<input type="number" name="product_id" placeholder="Product ID" required>
<!-- Required product name -->
<input type="text" name="name" placeholder="Name" required>
<!-- Optional category -->
<input type="text" name="category" placeholder="Category">
<!-- Optional price with decimal support -->
<input type="number" step="0.01" name="price" placeholder="Price">
<!-- Optional rating with decimal support -->
<input type="number" step="0.1" name="rating" placeholder="Rating">
<!-- Optional comma-separated tags -->
<input type="text" name="tags" placeholder="Tags (comma separated)">
<!-- Optional supplier name -->
<input type="text" name="supplier_name" placeholder="Supplier Name">
<!-- Optional supplier country -->
<input type="text" name="supplier_country" placeholder="Supplier Country">
<!-- Checkbox row spanning full width -->
<div class="checkbox-row full-width">
<!-- Checked by default -->
<input type="checkbox" name="in_stock" id="in_stock" checked>
<label for="in_stock">In Stock</label>
</div>
<!-- Submit button spanning full width -->
<div class="full-width">
<button type="submit" class="btn-create">Create Product</button>
</div>
</form>
</div>
<!-- Second card: product table -->
<div class="box">
<h2>Products</h2>
<!-- Only show the table if there are products -->
{% if products %}
<div class="table-wrap">
<table>
<thead>
<tr>
<!-- Table headers -->
<th>product_id</th>
<th>name</th>
<th>category</th>
<th>price</th>
<th>in_stock</th>
<th>rating</th>
<th>tags</th>
<th>supplier_name</th>
<th>supplier_country</th>
<th>created_at</th>
<th>actions</th>
</tr>
</thead>
<tbody>
<!-- Loop through each product passed in from Flask -->
{% for product in products %}
<tr>
<!-- Display each product field -->
<td>{{ product.product_id }}</td>
<td>{{ product.name }}</td>
<!-- Show empty string if category is missing -->
<td>{{ product.category or '' }}</td>
<!-- Show empty string if price is blank -->
<td>{{ product.price if product.price != '' else '' }}</td>
<td>{{ product.in_stock }}</td>
<!-- Show empty string if rating is blank -->
<td>{{ product.rating if product.rating != '' else '' }}</td>
<!-- tags_text is already prepared in Python as a comma-separated string -->
<td>{{ product.tags_text }}</td>
<!-- Show supplier data if present -->
<td>{{ product.supplier_name or '' }}</td>
<td>{{ product.supplier_country or '' }}</td>
<!-- Show formatted creation date -->
<td>{{ product.created_at }}</td>
<td>
<div class="actions">
<!-- Link to edit page for this specific product -->
<a href="/edit/{{ product._id }}" class="btn btn-edit">Edit</a>
<!-- Small form to delete this product -->
<form action="/delete/{{ product._id }}" method="POST" style="margin:0;">
<!-- JavaScript confirm prevents accidental deletion -->
<button type="submit" class="btn-delete" onclick="return confirm('Delete this product?')">Delete</button>
</form>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- If there are no products, show a placeholder message -->
{% else %}
<div class="empty">No products found yet.</div>
{% endif %}
</div>
</div>
</body>
</html>