feat: 16.0 - Frontend - Delete habit with confirmation

This commit is contained in:
Echo
2026-02-10 13:29:29 +00:00
parent 0f9c0de1a2
commit 46dc3a5041
4 changed files with 474 additions and 5 deletions

View File

@@ -153,6 +153,36 @@
flex-shrink: 0;
}
/* Delete button */
.habit-delete-btn {
width: 32px;
height: 32px;
border-radius: var(--radius-md);
border: 1px solid var(--border);
background: var(--bg-base);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all var(--transition-fast);
flex-shrink: 0;
}
.habit-delete-btn:hover {
border-color: var(--text-danger);
background: rgba(239, 68, 68, 0.1);
}
.habit-delete-btn svg {
width: 16px;
height: 16px;
color: var(--text-muted);
}
.habit-delete-btn:hover svg {
color: var(--text-danger);
}
/* Habit checkbox */
.habit-checkbox {
width: 32px;
@@ -359,6 +389,58 @@
opacity: 1;
}
/* Delete confirmation modal */
.confirm-modal {
background: var(--bg-base);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: var(--space-5);
width: 90%;
max-width: 400px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
.confirm-modal-title {
font-size: var(--text-lg);
font-weight: 600;
margin-bottom: var(--space-3);
color: var(--text-primary);
}
.confirm-modal-message {
font-size: var(--text-sm);
color: var(--text-secondary);
margin-bottom: var(--space-5);
}
.confirm-modal-actions {
display: flex;
justify-content: flex-end;
gap: var(--space-2);
}
.btn-danger {
background: var(--text-danger);
color: white;
border: 1px solid var(--text-danger);
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-md);
font-size: var(--text-sm);
font-weight: 500;
cursor: pointer;
transition: all var(--transition-fast);
}
.btn-danger:hover {
background: #dc2626;
border-color: #dc2626;
}
.btn-danger:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Mobile responsiveness */
@media (max-width: 768px) {
.main {
@@ -522,6 +604,20 @@
</div>
</div>
<!-- Delete Confirmation Modal -->
<div class="modal-overlay" id="deleteModal">
<div class="confirm-modal">
<h2 class="confirm-modal-title">Ștergi obișnuința?</h2>
<p class="confirm-modal-message" id="deleteModalMessage">
Ștergi obișnuința <strong id="deleteHabitName"></strong>?
</p>
<div class="confirm-modal-actions">
<button class="btn btn-secondary" onclick="hideDeleteModal()">Anulează</button>
<button class="btn btn-danger" id="confirmDeleteBtn" onclick="confirmDelete()">Șterge</button>
</div>
</div>
</div>
<div class="toast" id="toast"></div>
<script>
@@ -731,6 +827,9 @@
<span id="streak-${habit.id}">${habit.streak || 0}</span>
<span>🔥</span>
</div>
<button class="habit-delete-btn" onclick="showDeleteModal('${habit.id}', '${escapeHtml(habit.name).replace(/'/g, "&#39;")}')">
<i data-lucide="trash-2"></i>
</button>
`;
return card;
@@ -807,6 +906,64 @@
}
}
// Delete habit functions
let habitToDelete = null;
function showDeleteModal(habitId, habitName) {
habitToDelete = habitId;
const modal = document.getElementById('deleteModal');
const nameElement = document.getElementById('deleteHabitName');
// Decode HTML entities for display
const tempDiv = document.createElement('div');
tempDiv.innerHTML = habitName;
nameElement.textContent = tempDiv.textContent;
modal.classList.add('active');
}
function hideDeleteModal() {
const modal = document.getElementById('deleteModal');
modal.classList.remove('active');
habitToDelete = null;
}
async function confirmDelete() {
if (!habitToDelete) {
return;
}
const deleteBtn = document.getElementById('confirmDeleteBtn');
// Disable button during deletion
deleteBtn.disabled = true;
const originalText = deleteBtn.textContent;
deleteBtn.textContent = 'Se șterge...';
try {
const response = await fetch(`/api/habits/${habitToDelete}`, {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) {
throw new Error('Failed to delete habit');
}
hideDeleteModal();
showToast('Obișnuință ștearsă cu succes');
loadHabits();
} catch (error) {
console.error('Error deleting habit:', error);
showToast('Eroare la ștergerea obișnuinței. Încearcă din nou.');
// Re-enable button on error
deleteBtn.disabled = false;
deleteBtn.textContent = originalText;
}
}
// Load habits on page load
document.addEventListener('DOMContentLoaded', () => {
loadHabits();