added individual entry delete option

This commit is contained in:
2026-03-26 14:55:40 +05:30
parent 0ea8038f15
commit 625e4709d3
2 changed files with 231 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react'
import { useAuth } from '../contexts/AuthContext'
import { getUserEntries, type JournalEntry } from '../lib/api'
import { getUserEntries, deleteEntry, type JournalEntry } from '../lib/api'
import { decryptEntry } from '../lib/crypto'
import { formatIST, getISTDateComponents } from '../lib/timezone'
import BottomNav from '../components/BottomNav'
@@ -19,6 +19,8 @@ export default function HistoryPage() {
const [entries, setEntries] = useState<DecryptedEntry[]>([])
const [loadingEntries, setLoadingEntries] = useState(false)
const [selectedEntry, setSelectedEntry] = useState<DecryptedEntry | null>(null)
const [entryToDelete, setEntryToDelete] = useState<DecryptedEntry | null>(null)
const [deleting, setDeleting] = useState(false)
const { continueTourOnHistory } = useOnboardingTour()
@@ -175,6 +177,22 @@ export default function HistoryPage() {
setSelectedDate(new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day))
}
const handleDeleteConfirm = async () => {
if (!entryToDelete || !user || !userId) return
setDeleting(true)
try {
const token = await user.getIdToken()
await deleteEntry(userId, entryToDelete.id, token)
setEntries((prev) => prev.filter((e) => e.id !== entryToDelete.id))
if (selectedEntry?.id === entryToDelete.id) setSelectedEntry(null)
} catch (error) {
console.error('Failed to delete entry:', error)
} finally {
setDeleting(false)
setEntryToDelete(null)
}
}
if (loading) {
return (
<div className="history-page" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
@@ -267,21 +285,38 @@ export default function HistoryPage() {
</p>
) : (
selectedDateEntries.map((entry) => (
<button
<div
key={entry.id}
type="button"
className="entry-card"
role="button"
tabIndex={0}
onClick={() => setSelectedEntry(entry)}
onKeyDown={(e) => e.key === 'Enter' && setSelectedEntry(entry)}
>
<div className="entry-header">
<span className="entry-date">{formatDate(entry.createdAt)}</span>
<span className="entry-time">{formatTime(entry.createdAt)}</span>
<div className="entry-header-right">
<span className="entry-time">{formatTime(entry.createdAt)}</span>
<button
type="button"
className="entry-delete-btn"
title="Delete entry"
onClick={(e) => { e.stopPropagation(); setEntryToDelete(entry) }}
>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
<polyline points="3 6 5 6 21 6" />
<path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
<path d="M10 11v6M14 11v6" />
<path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
</svg>
</button>
</div>
</div>
<h4 className="entry-title">{entry.decryptedTitle || entry.title || '[Untitled]'}</h4>
{entry.decryptedContent && (
<p className="entry-preview">{entry.decryptedContent}</p>
)}
</button>
</div>
))
)}
</div>
@@ -352,6 +387,49 @@ export default function HistoryPage() {
</div>
)}
{/* Delete Confirmation Modal */}
{entryToDelete && (
<div
className="entry-modal-overlay"
onClick={(e) => {
if (e.target === e.currentTarget && !deleting) setEntryToDelete(null)
}}
>
<div className="entry-modal delete-confirm-modal">
<div className="delete-confirm-icon">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<polyline points="3 6 5 6 21 6" />
<path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
<path d="M10 11v6M14 11v6" />
<path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
</svg>
</div>
<h2 className="delete-confirm-title">Delete entry?</h2>
<p className="delete-confirm-body">
"{entryToDelete.decryptedTitle || entryToDelete.title || 'Untitled'}" will be permanently deleted and cannot be recovered.
</p>
<div className="delete-confirm-actions">
<button
type="button"
className="delete-confirm-cancel"
onClick={() => setEntryToDelete(null)}
disabled={deleting}
>
Cancel
</button>
<button
type="button"
className="delete-confirm-delete"
onClick={handleDeleteConfirm}
disabled={deleting}
>
{deleting ? 'Deleting…' : 'Delete'}
</button>
</div>
</div>
</div>
)}
<BottomNav />
</div>
)