454 lines
16 KiB
HTML
454 lines
16 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Редактирование материала{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container">
|
||
<div class="row justify-content-center">
|
||
<div class="col-md-8">
|
||
<!-- Хлебные крошки -->
|
||
<nav aria-label="breadcrumb" class="mb-3">
|
||
<ol class="breadcrumb">
|
||
<li class="breadcrumb-item"><a href="{{ url_for('catalog') }}">Каталог материалов</a></li>
|
||
<li class="breadcrumb-item"><a href="{{ url_for('catalog') }}?search={{ product.product_name }}">{{ product.product_name }}</a></li>
|
||
<li class="breadcrumb-item active">Редактирование</li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<div class="form-card">
|
||
<div class="form-card-header">
|
||
<h2 class="form-card-title">
|
||
<i class="fas fa-edit"></i> Редактирование материала
|
||
</h2>
|
||
</div>
|
||
|
||
<div class="form-card-body">
|
||
<!-- Flash сообщения -->
|
||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||
{% if messages %}
|
||
{% for category, message in messages %}
|
||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show">
|
||
<i class="fas fa-{{ 'exclamation-circle' if category == 'error' else 'check-circle' }} me-2"></i>
|
||
{{ message }}
|
||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||
</div>
|
||
{% endfor %}
|
||
{% endif %}
|
||
{% endwith %}
|
||
|
||
<form method="POST" id="materialForm">
|
||
<div class="row">
|
||
<!-- Левая колонка -->
|
||
<div class="col-md-6">
|
||
<h5 class="section-title">
|
||
<i class="fas fa-info-circle"></i> Основная информация
|
||
</h5>
|
||
|
||
<div class="form-group">
|
||
<label for="product_name" class="form-label">
|
||
<i class="fas fa-tag"></i>
|
||
Название материала
|
||
</label>
|
||
<input type="text" class="form-control modern-input" id="product_name" name="product_name"
|
||
value="{{ product.product_name }}" required maxlength="255">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="article" class="form-label">
|
||
<i class="fas fa-barcode"></i>
|
||
Артикул
|
||
</label>
|
||
<input type="text" class="form-control modern-input" id="article" name="article"
|
||
value="{{ product.article }}" required maxlength="100">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="category_id" class="form-label">
|
||
<i class="fas fa-folder"></i>
|
||
Категория
|
||
</label>
|
||
<div class="select-wrapper">
|
||
<select class="form-select modern-select" id="category_id" name="category_id" required>
|
||
<option value="" disabled>Выберите категорию</option>
|
||
{% for category in categories %}
|
||
<option value="{{ category.id }}" {% if category.id == product.category_id %}selected{% endif %}>
|
||
{{ category.category_name }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
<i class="fas fa-chevron-down select-arrow"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Правая колонка -->
|
||
<div class="col-md-6">
|
||
<h5 class="section-title">
|
||
<i class="fas fa-cog"></i> Характеристики
|
||
</h5>
|
||
|
||
<div class="form-group">
|
||
<label for="material_id" class="form-label">
|
||
<i class="fas fa-cube"></i>
|
||
Материал
|
||
</label>
|
||
<div class="select-wrapper">
|
||
<select class="form-select modern-select" id="material_id" name="material_id">
|
||
<option value="">Не выбран</option>
|
||
{% for material in materials %}
|
||
<option value="{{ material.id }}" {% if material.id == product.material_id %}selected{% endif %}>
|
||
{{ material.material_name }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
<i class="fas fa-chevron-down select-arrow"></i>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="min_price" class="form-label">
|
||
<i class="fas fa-ruble-sign"></i>
|
||
Цена
|
||
</label>
|
||
<input type="number" class="form-control modern-input" id="min_price" name="min_price"
|
||
min="0" step="0.01" required value="{{ product.min_price }}">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="in_stock" class="form-label">
|
||
<i class="fas fa-warehouse"></i>
|
||
Наличие на складе
|
||
</label>
|
||
<input type="number" class="form-control modern-input" id="in_stock" name="in_stock"
|
||
min="0" value="{{ product.in_stock or 0 }}">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Описание на всю ширину -->
|
||
<div class="col-12">
|
||
<div class="form-group">
|
||
<label for="description" class="form-label">
|
||
<i class="fas fa-align-left"></i>
|
||
Описание материала
|
||
</label>
|
||
<textarea class="form-control modern-input" id="description" name="description"
|
||
rows="4" maxlength="1000">{{ product.description or '' }}</textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Кнопки -->
|
||
<div class="form-actions">
|
||
<a href="{{ url_for('catalog') }}" class="btn btn-outline">
|
||
<i class="fas fa-times"></i> Отмена
|
||
</a>
|
||
<button type="submit" class="btn btn-primary">
|
||
<i class="fas fa-save"></i> Сохранить изменения
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
/* ===== ОСНОВНЫЕ ПЕРЕМЕННЫЕ ===== */
|
||
:root {
|
||
--antique-white: #FAEBD7;
|
||
--light-brown: #DEB887;
|
||
--brown: #A0522D;
|
||
--dark-brown: #8B4513;
|
||
}
|
||
|
||
/* ===== ХЛЕБНЫЕ КРОШКИ ===== */
|
||
.breadcrumb {
|
||
background: none;
|
||
padding: 0;
|
||
}
|
||
|
||
.breadcrumb-item a {
|
||
color: var(--brown);
|
||
text-decoration: none;
|
||
font-family: 'Verdana', sans-serif;
|
||
}
|
||
|
||
.breadcrumb-item a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.breadcrumb-item.active {
|
||
color: #6c757d;
|
||
font-family: 'Verdana', sans-serif;
|
||
}
|
||
|
||
.breadcrumb-item + .breadcrumb-item::before {
|
||
color: var(--light-brown);
|
||
}
|
||
|
||
/* ===== КАРТОЧКА ФОРМЫ ===== */
|
||
.form-card {
|
||
background: white;
|
||
border: 1px solid var(--light-brown);
|
||
border-radius: 16px;
|
||
box-shadow: 0 4px 20px rgba(160, 82, 45, 0.1);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.form-card-header {
|
||
background: linear-gradient(135deg, var(--brown) 0%, var(--dark-brown) 100%);
|
||
padding: 20px 25px;
|
||
color: white;
|
||
}
|
||
|
||
.form-card-title {
|
||
font-size: 1.4rem;
|
||
font-weight: 600;
|
||
font-family: 'Verdana', sans-serif;
|
||
margin: 0;
|
||
}
|
||
|
||
.form-card-title i {
|
||
margin-right: 10px;
|
||
color: white;
|
||
}
|
||
|
||
.form-card-body {
|
||
padding: 25px;
|
||
}
|
||
|
||
/* ===== ЗАГОЛОВКИ СЕКЦИЙ ===== */
|
||
.section-title {
|
||
color: var(--brown);
|
||
font-size: 1.1rem;
|
||
font-weight: 600;
|
||
margin-bottom: 20px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 2px solid var(--light-brown);
|
||
font-family: 'Verdana', sans-serif;
|
||
}
|
||
|
||
.section-title i {
|
||
color: var(--brown);
|
||
margin-right: 8px;
|
||
}
|
||
|
||
/* ===== ЭЛЕМЕНТЫ ФОРМЫ ===== */
|
||
.form-group {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.form-label {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
color: var(--brown);
|
||
font-weight: 600;
|
||
font-size: 0.95rem;
|
||
margin-bottom: 6px;
|
||
font-family: 'Verdana', sans-serif;
|
||
}
|
||
|
||
.form-label i {
|
||
color: var(--brown);
|
||
font-size: 1rem;
|
||
}
|
||
|
||
.modern-input {
|
||
width: 100%;
|
||
height: 42px;
|
||
padding: 0 12px;
|
||
border: 2px solid var(--light-brown);
|
||
border-radius: 10px;
|
||
font-size: 0.95rem;
|
||
font-family: 'Verdana', sans-serif;
|
||
transition: all 0.2s ease;
|
||
background: white;
|
||
}
|
||
|
||
.modern-input:focus {
|
||
outline: none;
|
||
border-color: var(--brown);
|
||
box-shadow: 0 0 0 3px rgba(160, 82, 45, 0.1);
|
||
}
|
||
|
||
.modern-input:hover {
|
||
border-color: var(--brown);
|
||
}
|
||
|
||
textarea.modern-input {
|
||
height: auto;
|
||
padding: 12px;
|
||
resize: vertical;
|
||
}
|
||
|
||
.select-wrapper {
|
||
position: relative;
|
||
}
|
||
|
||
.modern-select {
|
||
width: 100%;
|
||
height: 42px;
|
||
padding: 0 35px 0 12px;
|
||
border: 2px solid var(--light-brown);
|
||
border-radius: 10px;
|
||
font-size: 0.95rem;
|
||
font-family: 'Verdana', sans-serif;
|
||
background: white;
|
||
cursor: pointer;
|
||
appearance: none;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.modern-select:focus {
|
||
outline: none;
|
||
border-color: var(--brown);
|
||
box-shadow: 0 0 0 3px rgba(160, 82, 45, 0.1);
|
||
}
|
||
|
||
.modern-select:hover {
|
||
border-color: var(--brown);
|
||
}
|
||
|
||
.select-arrow {
|
||
position: absolute;
|
||
right: 15px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: var(--brown);
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* ===== КНОПКИ ===== */
|
||
.form-actions {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 25px;
|
||
padding-top: 20px;
|
||
border-top: 2px solid var(--light-brown);
|
||
}
|
||
|
||
.btn {
|
||
padding: 10px 25px;
|
||
border-radius: 10px;
|
||
font-size: 0.95rem;
|
||
font-weight: 500;
|
||
font-family: 'Verdana', sans-serif;
|
||
transition: all 0.2s ease;
|
||
border: none;
|
||
cursor: pointer;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: var(--brown);
|
||
color: white;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background: var(--dark-brown);
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 12px rgba(160, 82, 45, 0.3);
|
||
}
|
||
|
||
.btn-outline {
|
||
background: white;
|
||
border: 2px solid var(--light-brown);
|
||
color: var(--brown);
|
||
}
|
||
|
||
.btn-outline:hover {
|
||
background: var(--antique-white);
|
||
border-color: var(--brown);
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
/* ===== АЛЕРТЫ ===== */
|
||
.alert {
|
||
border-radius: 10px;
|
||
border: 1px solid var(--light-brown);
|
||
font-family: 'Verdana', sans-serif;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.alert-success {
|
||
background: var(--antique-white);
|
||
color: var(--brown);
|
||
border-left: 4px solid #28a745;
|
||
}
|
||
|
||
.alert-danger {
|
||
background: var(--antique-white);
|
||
color: #721c24;
|
||
border-left: 4px solid #dc3545;
|
||
}
|
||
|
||
/* ===== ИКОНКИ ===== */
|
||
i {
|
||
color: var(--brown);
|
||
}
|
||
|
||
.btn-primary i, .btn-outline i, .form-card-header i {
|
||
color: inherit;
|
||
}
|
||
|
||
/* ===== АДАПТИВНОСТЬ ===== */
|
||
@media (max-width: 768px) {
|
||
.form-card-body {
|
||
padding: 20px;
|
||
}
|
||
|
||
.form-actions {
|
||
flex-direction: column-reverse;
|
||
gap: 10px;
|
||
}
|
||
|
||
.form-actions .btn {
|
||
width: 100%;
|
||
justify-content: center;
|
||
}
|
||
|
||
.col-md-6 {
|
||
width: 100%;
|
||
}
|
||
|
||
.section-title {
|
||
margin-top: 15px;
|
||
}
|
||
|
||
.section-title:first-of-type {
|
||
margin-top: 0;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
document.getElementById('materialForm').addEventListener('submit', function(e) {
|
||
const price = parseFloat(document.getElementById('min_price').value);
|
||
const name = document.getElementById('product_name').value.trim();
|
||
const article = document.getElementById('article').value.trim();
|
||
|
||
if (!name) {
|
||
e.preventDefault();
|
||
alert('Введите название материала');
|
||
return false;
|
||
}
|
||
|
||
if (!article) {
|
||
e.preventDefault();
|
||
alert('Введите артикул материала');
|
||
return false;
|
||
}
|
||
|
||
if (price <= 0) {
|
||
e.preventDefault();
|
||
alert('Цена должна быть больше 0');
|
||
return false;
|
||
}
|
||
});
|
||
</script>
|
||
{% endblock %} |