duzo zmian ux w panelu

This commit is contained in:
Mateusz Gruszczyński
2025-08-14 23:55:58 +02:00
parent 97cebbdd49
commit 4f40bb06b3
8 changed files with 301 additions and 159 deletions

64
app.py
View File

@@ -2834,21 +2834,53 @@ def edit_list(list_id):
@login_required
@admin_required
def list_products():
items = Item.query.order_by(Item.id.desc()).all()
users = db.session.query(User).all()
items = Item.query.options(
joinedload(Item.shopping_list),
joinedload(Item.added_by_user),
).order_by(Item.id.desc()).all()
users = User.query.all()
users_dict = {user.id: user.username for user in users}
suggestions = SuggestedProduct.query.order_by(SuggestedProduct.name.asc()).all()
suggestions_dict = {s.name.lower(): s for s in suggestions}
all_suggestions_dict = {
(s.name or "").strip().lower(): s for s in suggestions if s.name and s.name.strip()
}
seen_names = set()
unique_items = []
used_suggestion_names = set()
for item in items:
normalized_name = (item.name or "").strip().lower()
if not normalized_name:
continue
if normalized_name not in seen_names:
seen_names.add(normalized_name)
unique_items.append(item)
used_suggestion_names.add(normalized_name)
orphan_suggestions = [
s for s in suggestions
if (s.name or "").strip().lower() not in used_suggestion_names and (s.name or "").strip()
]
suggestions_dict = {
name: all_suggestions_dict[name]
for name in used_suggestion_names
if name in all_suggestions_dict
}
return render_template(
"admin/list_products.html",
items=items,
items=unique_items,
users_dict=users_dict,
suggestions_dict=suggestions_dict,
orphan_suggestions=orphan_suggestions,
)
@app.route("/admin/sync_suggestion/<int:item_id>", methods=["POST"])
@login_required
def sync_suggestion_ajax(item_id):
@@ -2954,25 +2986,37 @@ def recalculate_filesizes_all():
@admin_required
def admin_mass_edit_categories():
lists = (
ShoppingList.query.options(joinedload(ShoppingList.categories))
ShoppingList.query.options(
joinedload(ShoppingList.categories),
joinedload(ShoppingList.items),
joinedload(ShoppingList.owner),
)
.order_by(ShoppingList.created_at.desc())
.all()
)
categories = Category.query.order_by(Category.name.asc()).all()
for l in lists:
l.total_count = len(l.items)
l.owner_name = l.owner.username if l.owner else "?"
l.category_count = len(l.categories)
if request.method == "POST":
for lst in lists:
selected_ids = request.form.getlist(f"categories_{lst.id}")
lst.categories.clear()
for l in lists:
selected_ids = request.form.getlist(f"categories_{l.id}")
l.categories.clear()
if selected_ids:
cats = Category.query.filter(Category.id.in_(selected_ids)).all()
lst.categories.extend(cats)
l.categories.extend(cats)
db.session.commit()
flash("Zaktualizowano kategorie dla wybranych list", "success")
return redirect(url_for("admin_mass_edit_categories"))
return render_template(
"admin/mass_edit_categories.html", lists=lists, categories=categories
"admin/mass_edit_categories.html",
lists=lists,
categories=categories
)

View File

@@ -352,12 +352,10 @@ input.form-control {
background-color: #212529 !important;
color: #fff !important;
border: 1px solid #495057 !important;
}
.ts-dropdown {
background-color: #212529 !important;
color: #fff !important;
z-index: 9999 !important;
border-radius: 0.375rem;
min-height: 38px;
padding: 0.25rem 0.5rem;
box-sizing: border-box;
}
.tom-dark .ts-control .item {
@@ -365,4 +363,54 @@ input.form-control {
color: #fff !important;
border-radius: 0.25rem;
padding: 2px 8px;
margin-right: 4px;
}
.ts-dropdown {
background-color: #212529 !important;
color: #fff !important;
border: 1px solid #495057;
border-radius: 0.375rem;
z-index: 9999 !important;
max-height: 300px;
overflow-y: auto;
}
.ts-dropdown .active {
background-color: #495057 !important;
color: #fff !important;
}
td select.tom-dark {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
.table-dark.table-striped tbody tr:nth-of-type(odd) {
background-color: rgba(255, 255, 255, 0.025);
}
.table-dark tbody tr:hover {
background-color: rgba(255, 255, 255, 0.04);
}
.table-dark thead th {
background-color: #1c1f22;
color: #e1e1e1;
font-weight: 500;
border-bottom: 1px solid #3a3f44;
}
.table-dark td,
.table-dark th {
padding: 0.6rem 0.75rem;
vertical-align: middle;
border-top: 1px solid #3a3f44;
}
.card .table {
border-radius: 0 !important;
overflow: hidden;
margin-bottom: 0;
}

View File

@@ -0,0 +1,11 @@
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll("select.tom-dark").forEach(function (el) {
new TomSelect(el, {
plugins: ['remove_button'],
persist: false,
create: false,
hidePlaceholder: true,
dropdownParent: 'body'
});
});
});

View File

@@ -263,18 +263,14 @@
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="{{ url_for('edit_list', list_id=l.id) }}"
class="btn btn-sm btn-outline-light" title="Edytuj">✏️</a>
<button type="button"
class="btn btn-sm btn-outline-light preview-btn"
data-list-id="{{ l.id }}"
title="Podgląd produktów">
<a href="{{ url_for('edit_list', list_id=l.id) }}" class="btn btn-sm btn-outline-light"
title="Edytuj">✏️</a>
<button type="button" class="btn btn-sm btn-outline-light preview-btn" data-list-id="{{ l.id }}"
title="Podgląd produktów">
👁️
</button>
<a href="{{ url_for('delete_list', list_id=l.id) }}"
class="btn btn-sm btn-outline-light"
onclick="return confirm('Na pewno usunąć tę listę?')"
title="Usuń">🗑️</a>
<a href="{{ url_for('delete_list', list_id=l.id) }}" class="btn btn-sm btn-outline-light"
onclick="return confirm('Na pewno usunąć tę listę?')" title="Usuń">🗑️</a>
</div>
</td>
</tr>
@@ -298,18 +294,17 @@
<!-- Modal podglądu produktów -->
<div class="modal fade" id="productPreviewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content bg-dark text-white">
<div class="modal-header">
<h5 class="modal-title" id="previewModalLabel">Podgląd produktów</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"
aria-label="Zamknij"></button>
</div>
<div class="modal-body">
<ul id="product-list" class="list-group list-group-flush"></ul>
</div>
</div>
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content bg-dark text-white">
<div class="modal-header">
<h5 class="modal-title" id="previewModalLabel">Podgląd produktów</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Zamknij"></button>
</div>
<div class="modal-body">
<ul id="product-list" class="list-group list-group-flush"></ul>
</div>
</div>
</div>
</div>
{% block scripts %}

View File

@@ -13,74 +13,90 @@
<form method="post" class="mt-3">
<input type="hidden" name="action" value="save">
<!-- Nazwa listy -->
<div class="mb-3">
<label for="title" class="form-label">Nazwa listy</label>
<label for="title" class="form-label">📝 Nazwa listy</label>
<input type="text" class="form-control bg-dark text-white border-secondary rounded" id="title" name="title"
value="{{ list.title }}" required>
</div>
<div class="mb-3">
<label for="amount" class="form-label">Całkowity wydatek (PLN)</label>
<input type="number" step="0.01" min="0" class="form-control bg-dark text-white border-secondary rounded"
id="amount" name="amount" value="{{ '%.2f'|format(total_expense) }}">
<!-- Wydatek i właściciel -->
<div class="row mb-3">
<div class="col-md-6">
<label for="amount" class="form-label">💰 Całkowity wydatek (PLN)</label>
<input type="number" step="0.01" min="0" class="form-control bg-dark text-white border-secondary rounded"
id="amount" name="amount" value="{{ '%.2f'|format(total_expense) }}">
</div>
<div class="col-md-6">
<label for="owner_id" class="form-label">👤 Właściciel</label>
<select class="form-select bg-dark text-white border-secondary" id="owner_id" name="owner_id">
{% for user in users %}
<option value="{{ user.id }}" {% if list.owner_id==user.id %}selected{% endif %}>
{{ user.username }}
</option>
{% endfor %}
</select>
</div>
</div>
<div class="mb-3">
<label for="owner_id" class="form-label">Właściciel</label>
<select class="form-select bg-dark text-white border-secondary" id="owner_id" name="owner_id">
{% for user in users %}
<option value="{{ user.id }}" {% if list.owner_id==user.id %}selected{% endif %}>{{ user.username }}</option>
{% endfor %}
</select>
<!-- Statusy -->
<div class="mb-4">
<label class="form-label">⚙️ Statusy listy</label>
<div class="d-flex flex-wrap gap-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="archived" name="archived" {% if list.is_archived
%}checked{% endif %}>
<label class="form-check-label" for="archived">📦 Archiwalna</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="public" name="public" {% if list.is_public %}checked{%
endif %}>
<label class="form-check-label" for="public">🌐 Publiczna</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="temporary" name="temporary" {% if list.is_temporary
%}checked{% endif %}>
<label class="form-check-label" for="temporary">⏳ Tymczasowa (podaj date i godzine wygasania)</label>
</div>
</div>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="archived" name="archived" {% if list.is_archived %}checked{%
endif %}>
<label class="form-check-label" for="archived">Archiwalna</label>
</div>
<div class="form-check form-switch mb-4">
<input class="form-check-input" type="checkbox" id="public" name="public" {% if list.is_public %}checked{% endif
%}>
<label class="form-check-label" for="public">Publiczna</label>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="temporary" name="temporary" {% if list.is_temporary
%}checked{% endif %}>
<label class="form-check-label" for="temporary">Tymczasowa</label>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="expires_date" class="form-label">Data wygaśnięcia</label>
<!-- Data/godzina wygaśnięcia -->
<div class="row mb-4">
<div class="col-md-6">
<label for="expires_date" class="form-label">📅 Data wygaśnięcia</label>
<input type="date" class="form-control bg-dark text-white border-secondary rounded" id="expires_date"
name="expires_date" value="{{ list.expires_at.strftime('%Y-%m-%d') if list.expires_at else '' }}">
</div>
<div class="col-md-6 mb-3">
<label for="expires_time" class="form-label">Godzina wygaśnięcia</label>
<div class="col-md-6">
<label for="expires_time" class="form-label">Godzina wygaśnięcia</label>
<input type="time" class="form-control bg-dark text-white border-secondary rounded" id="expires_time"
name="expires_time" value="{{ list.expires_at.strftime('%H:%M') if list.expires_at else '' }}">
</div>
</div>
<div class="row mb-3">
<!-- Utworzono / Zmień miesiąc -->
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label">Aktualna data utworzenia listy</label>
<label class="form-label">📆 Utworzono</label>
<p class="form-control-plaintext text-white">
{{ list.created_at.strftime('%Y-%m-%d') }}
</p>
</div>
<div class="col-md-6">
<label for="created_month" class="form-label">Przenieś listę do miesiąca</label>
<label for="created_month" class="form-label">📁 Przenieś do miesiąca</label>
<input type="month" id="created_month" name="created_month"
class="form-control bg-dark text-white border-secondary rounded">
</div>
</div>
<!-- Kategorie -->
<div class="mb-4">
<label class="form-label">Kategorie</label>
<label for="categories" class="form-label">🏷️ Kategorie</label>
<select id="categories" name="categories"
class="form-select tom-dark bg-dark text-white border-secondary rounded">
<option value=""> brak </option>
@@ -92,20 +108,23 @@
</select>
</div>
<!-- Link udostępnienia -->
<div class="mb-4">
<label class="form-label">Link do udostępnienia</label>
<label class="form-label">🔗 Link do udostępnienia</label>
<input type="text" class="form-control bg-dark text-white border-secondary rounded" readonly
value="{{ request.url_root }}share/{{ list.share_token }}">
</div>
<button type="submit" class="btn btn-success me-2">💾 Zapisz zmiany</button>
</form>
</div>
</div>
<div class="card bg-dark text-white mb-5">
<div class="card-body">
<h4 class="card-title">🛒 Produkty</h4>
<h4 class="card-title">📝 Produkty</h4>
<form method="post" class="row g-2 mb-3">
<input type="hidden" name="action" value="add_item">
<div class="col-md-8">
@@ -125,10 +144,12 @@
<table class="table table-dark table-bordered align-middle">
<thead>
<tr>
<th scope="col">Nazwa</th>
<th scope="col">Status</th>
<th scope="col">Oznaczenie</th>
<th scope="col">Usuń</th>
<th>Nazwa produktu</th>
<th>Notatka</th>
<th>Ilość</th>
<th>Aktualny stan</th>
<th>Akcja</th>
<th>Usuń</th>
</tr>
</thead>
<tbody>
@@ -136,26 +157,21 @@
<tr>
<td>
<strong>{{ item.name }}</strong>
<small class="text-small text-success">(x{{ item.quantity }})</small>
</td>
<td>
{% if item.note %}
<div class="text-info small mt-1">
<strong>Notatka:</strong> {{ item.note }}
</div>
<div class="text-info small mt-1"><strong>Notatka:</strong> {{ item.note }}</div>
{% endif %}
{% if item.not_purchased_reason %}
<div class="text-warning small mt-1">
<strong>Powód:</strong> {{ item.not_purchased_reason }}
</div>
<div class="text-warning small mt-1"><strong>Powód:</strong> {{ item.not_purchased_reason }}</div>
{% endif %}
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}" class="mt-2">
</td>
<td>
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}">
<input type="hidden" name="action" value="edit_quantity">
<input type="hidden" name="item_id" value="{{ item.id }}">
<div class="input-group input-group-sm ">
<input type="number" name="quantity"
class="form-control bg-dark text-white border-secondary rounded-left" min="1"
<div class="input-group input-group-sm w-auto">
<input type="number" name="quantity" class="form-control bg-dark text-white border-secondary" min="1"
value="{{ item.quantity }}">
<button type="submit" class="btn btn-outline-light">💾</button>
</div>
@@ -165,61 +181,45 @@
{% if item.purchased %}
<span class="badge bg-success">✔️ Kupiony</span>
{% elif item.not_purchased %}
<span class="badge bg-warning text-dark">⚠️ Nie kupione</span>
<span class="badge bg-warning text-dark">⚠️ Nie kupiony</span>
{% else %}
<span class="badge bg-secondary">Nieoznaczony</span>
{% endif %}
</td>
<td>
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}" class="d-grid gap-1">
<input type="hidden" name="action" value="toggle_purchased">
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}">
<input type="hidden" name="item_id" value="{{ item.id }}">
{% if not item.not_purchased %}
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}" class="d-grid gap-1">
<input type="hidden" name="action" value="toggle_purchased">
<input type="hidden" name="item_id" value="{{ item.id }}">
{% if item.purchased %}
<button type="submit" class="btn btn-outline-warning btn-sm">🚫 Odznacz</button>
{% else %}
<button type="submit" class="btn btn-outline-success btn-sm">✅ Oznacz</button>
<div class="btn-group btn-group-sm d-flex gap-1">
{% if not item.not_purchased %}
<button type="submit" name="action" value="toggle_purchased" class="btn btn-outline-light w-100">
{{ '🚫 Odznacz' if item.purchased else '✅ Kupiony' }}
</button>
<button type="submit" name="action" value="mark_not_purchased" class="btn btn-outline-light w-100">⚠️
Nie kupiony</button>
{% endif %}
</form>
{% endif %}
{% if item.not_purchased %}
<button type="submit" name="action" value="unmark_not_purchased" class="btn btn-outline-light w-100">
Przywróć jako nieoznaczone</button>
{% endif %}
</div>
</form>
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}" class="d-grid gap-1 mt-1">
<input type="hidden" name="action" value="mark_not_purchased">
<input type="hidden" name="item_id" value="{{ item.id }}">
<button type="submit" class="btn btn-outline-warning btn-sm">⚠️ Nie kupione</button>
</form>
{% if item.not_purchased %}
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}"
class="d-grid gap-1 mt-3 border-top pt-2">
<input type="hidden" name="action" value="unmark_not_purchased">
<input type="hidden" name="item_id" value="{{ item.id }}">
<button type="submit" class="btn btn-outline-success btn-sm">✅ Przywróć na liste</button>
</form>
{% endif %}
</td>
<td>
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}" class="d-inline">
<form method="post" action="{{ url_for('edit_list', list_id=list.id) }}">
<input type="hidden" name="action" value="delete_item">
<input type="hidden" name="item_id" value="{{ item.id }}">
<button type="submit" class="btn btn-danger btn-sm w-100">🗑️ Usuń</button>
<button type="submit" class="btn btn-outline-light btn-sm w-100">🗑️</button>
</form>
</td>
</tr>
{% else %}
<tr>
<td colspan="4" class="text-center text-muted">Brak produktów.</td>
<td colspan="5" class="text-center text-muted">Brak produktów.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>

View File

@@ -13,7 +13,7 @@
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="m-0">📦 Produkty (z synchronizacją sugestii)</h4>
<span class="badge bg-secondary">{{ items|length }} produktów</span>
<span class="badge bg-info">{{ items|length }} produktów</span>
</div>
<div class="card-body p-0">
<table class="table table-dark table-striped align-middle m-0">
@@ -21,21 +21,21 @@
<tr>
<th>ID</th>
<th>Nazwa</th>
<th>Dodana przez</th>
<th>Dodany przez</th>
<th>Sugestia</th>
<th>Akcje</th>
<th>Lista</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td>{{ item.id }}</td>
<td class="fw-bold">{{ item.name }}</td>
<td class="fw-bold"><span class="badge bg-primary">{{ item.name }}</span></td>
<td>
{% if item.added_by %}
{{ users_dict.get(item.added_by, 'Nieznany') }}
{% if item.added_by and users_dict.get(item.added_by) %}
👤 {{ users_dict[item.added_by] }} ({{ item.added_by }})
{% else %}
Gość
-
{% endif %}
</td>
<td>
@@ -50,8 +50,20 @@
{% endif %}
</td>
<td>
<a href="/list/{{ item.list_id }}" class="btn btn-sm btn-outline-light mb-1">📄 Zobacz listę</a>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-light disabled" data-bs-toggle="tooltip"
data-bs-title="{{ item.shopping_list.title }}">
ID: {{ item.list_id }}
</button>
<a href="{{ url_for('view_list', list_id=item.list_id) }}" class="btn btn-outline-light">
📄 Otwórz
</a>
<button type="button" class="btn btn-outline-light preview-btn" data-list-id="{{ item.list_id }}">
🔍 Podgląd
</button>
</div>
</td>
</tr>
{% endfor %}
{% if items|length == 0 %}
@@ -69,7 +81,7 @@
<div class="card-body">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="m-0">💡 Wszystkie sugestie (poza powiązanymi)</h4>
<span class="badge bg-secondary">{{ suggestions_dict|length }} sugestii</span>
<span class="badge bg-info">{{ orphan_suggestions|length }} sugestii</span>
</div>
<div class="card-body p-0">
{% set item_names = items | map(attribute='name') | map('lower') | list %}
@@ -82,11 +94,11 @@
</tr>
</thead>
<tbody>
{% for suggestion in suggestions_dict.values() %}
{% for suggestion in orphan_suggestions %}
{% if suggestion.name.lower() not in item_names %}
<tr>
<td>{{ suggestion.id }}</td>
<td class="fw-bold">{{ suggestion.name }}</td>
<td class="fw-bold"><span class="badge bg-primary">{{ suggestion.name }}</span></td>
<td>
<button class="btn btn-sm btn-outline-danger delete-suggestion-btn"
data-suggestion-id="{{ suggestion.id }}">🗑️ Usuń</button>
@@ -105,8 +117,24 @@
</div>
</div>
<!-- Modal podglądu produktów -->
<div class="modal fade" id="productPreviewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content bg-dark text-white">
<div class="modal-header">
<h5 class="modal-title" id="previewModalLabel">Podgląd produktów</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Zamknij"></button>
</div>
<div class="modal-body">
<ul id="product-list" class="list-group list-group-flush"></ul>
</div>
</div>
</div>
</div>
{% block scripts %}
<script src="{{ url_for('static_bp.serve_js', filename='product_suggestion.js') }}"></script>
<script src="{{ url_for('static_bp.serve_js', filename='preview_list_modal.js') }}"></script>
{% endblock %}
{% endblock %}

View File

@@ -18,35 +18,51 @@
<div class="card bg-dark text-white mb-5">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-dark table-striped table-hover align-middle mb-0 sortable">
<table class="table table-dark table-striped align-middle sortable">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Nazwa listy</th>
<th scope="col">Właściciel</th>
<th scope="col">Data utworzenia</th>
<th scope="col">Status</th>
<th scope="col">Podgląd produktów</th>
<th scope="col">Kategorie</th>
</tr>
</thead>
<tbody>
{% for lst in lists %}
{% for l in lists %}
<tr>
<td>{{ lst.id }}</td>
<td>{{ lst.title }}</td>
<td>{{ lst.owner.username if lst.owner else "?" }}</td>
<td>{{ lst.created_at.strftime('%Y-%m-%d') }}</td>
<td>{{ l.id }}</td>
<td class="fw-bold align-middle">
<a href="{{ url_for('view_list', list_id=l.id) }}" class="text-white">{{ l.title }}</a>
</td>
<td>
{% if l.owner %}
👤 {{ l.owner.username }} ({{ l.owner.id }})
{% else %}
-
{% endif %}
</td>
<td>{{ l.created_at.strftime('%Y-%m-%d %H:%M') if l.created_at else '-' }}</td>
<td>
{% if l.is_archived %}<span class="badge bg-secondary">Archiwalna</span>{% endif %}
{% if l.is_temporary %}<span class="badge bg-warning text-dark">Tymczasowa</span>{%
endif %}
{% if l.is_public %}<span class="badge bg-success">Publiczna</span>{% else %}
<span class="badge bg-dark">Prywatna</span>{% endif %}
</td>
<td>
<button type="button" class="btn btn-sm btn-outline-info preview-btn"
data-list-id="{{ lst.id }}">
data-list-id="{{ l.id }}">
🔍 Zobacz
</button>
</td>
<td style="min-width: 220px;">
<select name="categories_{{ lst.id }}" multiple
<select name="categories_{{ l.id }}" multiple
class="form-select tom-dark bg-dark text-white border-secondary rounded">
{% for cat in categories %}
<option value="{{ cat.id }}" {% if cat in lst.categories %}selected{% endif %}>
<option value="{{ cat.id }}" {% if cat in l.categories %}selected{% endif %}>
{{ cat.name }}
</option>
{% endfor %}

View File

@@ -38,14 +38,14 @@
<div class="d-none d-md-flex justify-content-end align-items-center flex-wrap gap-2 mb-3">
<label for="monthSelect" class="text-white small mb-0">📅 Wybierz miesiąc:</label>
<select id="monthSelect" class="form-select form-select-sm bg-dark text-white border-secondary"
style="min-width: 180px;">
style="min-width: 180px;">
{% for m in month_options %}
{% set year, month = m.split('-') %}
<option value="{{ m }}" {% if selected_month == m %}selected{% endif %}>
{{ month_names[month|int - 1] }} {{ year }}
</option>
{% set year, month = m.split('-') %}
<option value="{{ m }}" {% if selected_month==m %}selected{% endif %}>
{{ month_names[month|int - 1] }} {{ year }}
</option>
{% endfor %}
<option value="all" {% if selected_month == 'all' %}selected{% endif %}>
<option value="all" {% if selected_month=='all' %}selected{% endif %}>
Wyświetl wszystko
</option>
</select>
@@ -228,11 +228,11 @@
<div class="modal-body">
<div class="d-grid gap-2">
{% for m in month_options %}
{% set year, month = m.split('-') %}
<a href="{{ url_for('main_page', m=m) }}"
class="btn btn-outline-light {% if selected_month == m %}active{% endif %}">
{{ month_names[month|int - 1] }} {{ year }}
</a>
{% set year, month = m.split('-') %}
<a href="{{ url_for('main_page', m=m) }}"
class="btn btn-outline-light {% if selected_month == m %}active{% endif %}">
{{ month_names[month|int - 1] }} {{ year }}
</a>
{% endfor %}
<a href="{{ url_for('main_page', m='all') }}"
class="btn btn-outline-secondary {% if selected_month == 'all' %}active{% endif %}">