fix w sugestiach i js

This commit is contained in:
Mateusz Gruszczyński
2025-08-15 23:29:13 +02:00
parent ea46dd43e1
commit 68f235d605
9 changed files with 115 additions and 94 deletions

View File

@@ -1,73 +1,91 @@
function bindSyncButton(button) {
button.addEventListener('click', function (e) {
e.preventDefault();
const itemId = button.getAttribute('data-item-id');
button.disabled = true;
fetch(`/admin/sync_suggestion/${itemId}`, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
showToast(data.message, data.success ? 'success' : 'danger');
if (data.success) {
button.innerText = '✅ Zsynchronizowano';
button.classList.remove('btn-outline-primary');
button.classList.add('btn-success');
} else {
button.disabled = false;
}
})
.catch(() => {
showToast('Błąd synchronizacji', 'danger');
button.disabled = false;
});
});
}
function bindDeleteButton(button) {
button.addEventListener('click', function (e) {
e.preventDefault();
const suggestionId = button.getAttribute('data-suggestion-id');
const row = button.closest('tr');
const itemId = button.getAttribute('data-item-id');
const nameBadge = row?.querySelector('.badge.bg-primary');
const itemName = nameBadge?.innerText.trim().toLowerCase();
button.disabled = true;
fetch(`/admin/delete_suggestion/${suggestionId}`, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
showToast(data.message, data.success ? 'success' : 'danger');
if (!data.success || !row) {
button.disabled = false;
return;
}
const isProductRow = typeof itemId === 'string' && itemId !== '';
const cell = row.querySelector('td:last-child');
if (!cell) return;
if (isProductRow) {
cell.innerHTML = `<button class="btn btn-sm btn-outline-light sync-btn" data-item-id="${itemId}">🔄 Synchronizuj</button>`;
const syncBtn = cell.querySelector('.sync-btn');
if (syncBtn) bindSyncButton(syncBtn);
} else {
cell.innerHTML = '<span class="badge rounded-pill bg-warning opacity-75">Usunięto synchronizacje</span>';
}
})
.catch(() => {
showToast('Błąd usuwania sugestii', 'danger');
button.disabled = false;
});
});
}
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll('.sync-btn').forEach(btn => {
btn.replaceWith(btn.cloneNode(true));
});
document.querySelectorAll('.delete-suggestion-btn').forEach(btn => {
btn.replaceWith(btn.cloneNode(true));
});
document.querySelectorAll('.sync-btn').forEach(btn => {
btn.addEventListener('click', function (e) {
e.preventDefault();
const itemId = this.getAttribute('data-item-id');
const button = this;
button.disabled = true;
fetch(`/admin/sync_suggestion/${itemId}`, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
showToast(data.message, data.success ? 'success' : 'danger');
if (data.success) {
button.innerText = '✅ Zsynchronizowano';
button.classList.remove('btn-outline-primary');
button.classList.add('btn-success');
} else {
button.disabled = false;
}
})
.catch(() => {
showToast('Błąd synchronizacji', 'danger');
button.disabled = false;
});
});
const clone = btn.cloneNode(true);
btn.replaceWith(clone);
bindSyncButton(clone);
});
document.querySelectorAll('.delete-suggestion-btn').forEach(btn => {
btn.addEventListener('click', function (e) {
e.preventDefault();
const suggestionId = this.getAttribute('data-suggestion-id');
const button = this;
button.disabled = true;
fetch(`/admin/delete_suggestion/${suggestionId}`, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
showToast(data.message, data.success ? 'success' : 'danger');
if (data.success) {
const row = button.closest('tr');
if (row) row.remove();
} else {
button.disabled = false;
}
})
.catch(() => {
showToast('Błąd usuwania sugestii', 'danger');
button.disabled = false;
});
});
const clone = btn.cloneNode(true);
btn.replaceWith(clone);
bindDeleteButton(clone);
});
});

View File

@@ -224,11 +224,11 @@
<td>
{% if l.is_archived %}
<span class="badge bg-secondary">Archiwalna</span>
<span class="badge rounded-pill bg-secondary">Archiwalna</span>
{% elif e.expired %}
<span class="badge bg-warning text-dark">Wygasła</span>
<span class="badge rounded-pill bg-warning text-dark">Wygasła</span>
{% else %}
<span class="badge bg-success">Aktywna</span>
<span class="badge rounded-pill bg-success">Aktywna</span>
{% endif %}
</td>
<td>{{ l.created_at.strftime('%Y-%m-%d %H:%M') if l.created_at else '-' }}</td>
@@ -250,8 +250,8 @@
</div>
</div>
</td>
<td><span class="badge bg-primary">{{ e.comments_count }}</span></td>
<td><span class="badge bg-secondary">{{ e.receipts_count }}</span></td>
<td><span class="badge rounded-pill bg-primary">{{ e.comments_count }}</span></td>
<td><span class="badge rounded-pill bg-secondary">{{ e.receipts_count }}</span></td>
<td class="fw-bold
{% if e.total_expense >= 500 %}text-danger
{% elif e.total_expense > 0 %}text-success{% endif %}">

View File

@@ -11,7 +11,7 @@
<div class="card-body">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="m-0">📦 Produkty (z synchronizacją sugestii o unikalnych nazwach)</h4>
<span class="badge bg-info">{{ total_items }} produktów</span>
<span class="badge rounded-pill bg-info">{{ total_items }} produktów</span>
</div>
<div class="card-body p-0">
<table class="table table-dark table-striped align-middle sortable">
@@ -28,7 +28,7 @@
{% for item in items %}
<tr>
<td>{{ item.id }}</td>
<td class="fw-bold"><span class="badge bg-primary">{{ item.name }}</span></td>
<td class="fw-bold"><span class="badge rounded-pill bg-primary">{{ item.name }}</span></td>
<td>
{% if item.added_by and users_dict.get(item.added_by) %}
👤 {{ users_dict[item.added_by] }} ({{ item.added_by }})
@@ -36,7 +36,7 @@
-
{% endif %}
</td>
<td><span class="badge bg-secondary">{{ usage_counts.get(item.name.lower(), 0) }}</span></td>
<td><span class="badge rounded-pill bg-secondary">{{ usage_counts.get(item.name.lower(), 0) }}</span></td>
<td>
{% set clean_name = item.name | replace('\xa0', ' ') | trim | lower %}
{% set suggestion = suggestions_dict.get(clean_name) %}
@@ -66,7 +66,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-info">{{ orphan_suggestions|length }} sugestii</span>
<span class="badge rounded-pill bg-info">{{ orphan_suggestions|length }} sugestii</span>
</div>
<div class="card-body p-0">
{% set item_names = items | map(attribute='name') | map('lower') | list %}
@@ -83,7 +83,7 @@
{% if suggestion.name.lower() not in item_names %}
<tr>
<td>{{ suggestion.id }}</td>
<td class="fw-bold"><span class="badge bg-primary">{{ suggestion.name }}</span></td>
<td class="fw-bold"><span class="badge rounded-pill bg-primary">{{ suggestion.name }}</span></td>
<td>
<button class="btn btn-sm btn-outline-light delete-suggestion-btn"
data-suggestion-id="{{ suggestion.id }}">🗑️ Usuń</button>

View File

@@ -46,11 +46,14 @@
</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>{%
{% if l.is_archived %}<span class="badge rounded-pill bg-secondary">Archiwalna</span>{%
endif %}
{% if l.is_public %}<span class="badge bg-success">Publiczna</span>{% else %}
<span class="badge bg-dark">Prywatna</span>{% endif %}
{% if l.is_temporary %}<span
class="badge rounded-pill bg-warning text-dark">Tymczasowa</span>{%
endif %}
{% if l.is_public %}<span class="badge rounded-pill bg-success">Publiczna</span>{% else
%}
<span class="badge rounded-pill bg-dark">Prywatna</span>{% endif %}
</td>
<td>
<button type="button" class="btn btn-sm btn-outline-info preview-btn"

View File

@@ -47,9 +47,9 @@
<td class="fw-bold">{{ user.username }}</td>
<td>
{% if user.is_admin %}
<span class="badge bg-primary">Admin</span>
<span class="badge rounded-pill bg-primary">Admin</span>
{% else %}
<span class="badge bg-secondary">Użytkownik</span>
<span class="badge rounded-pill bg-secondary">Użytkownik</span>
{% endif %}
</td>
<td>

View File

@@ -42,12 +42,12 @@
{% if current_user.is_authenticated %}
<div class="d-flex justify-content-center align-items-center text-white small flex-wrap text-center">
<span class="me-1">Zalogowany:</span>
<span class="badge bg-success">{{ current_user.username }}</span>
<span class="badge rounded-pill bg-success">{{ current_user.username }}</span>
</div>
{% else %}
<div class="d-flex justify-content-center align-items-center text-white small flex-wrap text-center">
<span class="me-1">Przeglądasz jako</span>
<span class="badge bg-info">gość</span>
<span class="badge rounded-pill bg-info">gość</span>
</div>
{% endif %}
{% endif %}

View File

@@ -60,7 +60,7 @@
<div class="col-md-6">
<label class="form-label">📆 Utworzono:</label>
<p class="form-control-plaintext text-white">
<span class="badge bg-success rounded-pill text-dark ms-1">
<span class="badge rounded-pill bg-success rounded-pill text-dark ms-1">
{{ list.created_at.strftime('%Y-%m-%d') }}
</span>
</p>

View File

@@ -6,12 +6,12 @@
<h2 class="mb-2">
Lista: <strong>{{ list.title }}</strong>
{% if list.is_archived %}
<span class="badge bg-secondary ms-2">(Archiwalna)</span>
<span class="badge rounded-pill bg-secondary ms-2">(Archiwalna)</span>
{% endif %}
{% if list.category_badges %}
{% for cat in list.category_badges %}
<span class="badge rounded-pill text-dark ms-1" style="background-color: {{ cat.color }};
<span class="badge rounded-pill rounded-pill text-dark ms-1" style="background-color: {{ cat.color }};
font-size: 0.75rem;
opacity: 0.85;">
{{ cat.name }}
@@ -41,7 +41,7 @@
🙈 Lista jest ukryta przed gośćmi
{% endif %}
</strong>
<span id="share-url" class="badge bg-secondary text-wrap"
<span id="share-url" class="badge rounded-pill bg-secondary text-wrap"
style="font-size: 0.7rem; {% if not list.is_public %}display: none;{% endif %}">
{{ request.url_root }}share/{{ list.share_token }}
</span>
@@ -120,7 +120,7 @@
<span id="name-{{ item.id }}" class="text-white">
{{ item.name }}
{% if item.quantity and item.quantity > 1 %}
<span class="badge bg-secondary">x{{ item.quantity }}</span>
<span class="badge rounded-pill bg-secondary">x{{ item.quantity }}</span>
{% endif %}
</span>

View File

@@ -6,15 +6,15 @@
🛍️ {{ list.title }}
{% if list.is_archived %}
<span class="badge bg-secondary ms-2">(Archiwalna)</span>
<span class="badge rounded-pill bg-secondary ms-2">(Archiwalna)</span>
{% endif %}
{% if total_expense > 0 %}
<span id="total-expense1" class="badge bg-success ms-2">
<span id="total-expense1" class="badge rounded-pill bg-success ms-2">
💸 {{ '%.2f'|format(total_expense) }} PLN
</span>
{% else %}
<span id="total-expense" class="badge bg-secondary ms-2" style="display: none;">
<span id="total-expense" class="badge rounded-pill bg-secondary ms-2" style="display: none;">
💸 0.00 PLN
</span>
{% endif %}
@@ -22,7 +22,7 @@
{# Kategorie - tylko wyświetlenie, bez linków #}
{% if list.category_badges %}
{% for cat in list.category_badges %}
<span class="badge rounded-pill text-dark ms-1" style="background-color: {{ cat.color }};
<span class="badge rounded-pill rounded-pill text-dark ms-1" style="background-color: {{ cat.color }};
font-size: 0.75rem;
opacity: 0.85;">
{{ cat.name }}
@@ -53,7 +53,7 @@
<span id="name-{{ item.id }}" class="text-white">
{{ item.name }}
{% if item.quantity and item.quantity > 1 %}
<span class="badge bg-secondary">x{{ item.quantity }}</span>
<span class="badge rounded-pill bg-secondary">x{{ item.quantity }}</span>
{% endif %}
</span>