diff --git a/src/components/ReflectionsList.tsx b/src/components/ReflectionsList.tsx index 78b9894..2d36010 100644 --- a/src/components/ReflectionsList.tsx +++ b/src/components/ReflectionsList.tsx @@ -1,12 +1,13 @@ 'use client'; -import React, { useState } from 'react'; +import React, { useState, useMemo } from 'react'; interface Prayer { id: string; date: string; text: string; prayFor?: string; + answered?: boolean; } interface PrayerListProps { @@ -18,34 +19,60 @@ interface PrayerListProps { export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerListProps) { const [searchTerm, setSearchTerm] = useState(''); const [sortOrder, setSortOrder] = useState<'newest' | 'oldest'>('newest'); + const [filterAnswered, setFilterAnswered] = useState<'all' | 'answered' | 'unanswered'>('all'); - const filtered = prayers - .filter( - p => - p.text.toLowerCase().includes(searchTerm.toLowerCase()) || - p.prayFor?.toLowerCase().includes(searchTerm.toLowerCase()) - ) - .sort((a, b) => { - const comparison = new Date(b.date).getTime() - new Date(a.date).getTime(); - return sortOrder === 'newest' ? comparison : -comparison; - }); + // Fuzzy search helper - finds if search term matches any part of text + const fuzzyMatch = (text: string, searchTerm: string): boolean => { + if (!searchTerm) return true; + const searchLower = searchTerm.toLowerCase().trim(); + const textLower = text.toLowerCase(); + + // Direct substring match (most relevant) + if (textLower.includes(searchLower)) return true; + + // Split search into words and check if all words are found + const words = searchLower.split(/\s+/); + return words.every(word => textLower.includes(word)); + }; - const grouped = filtered.reduce((acc, prayer) => { - if (!acc[prayer.date]) acc[prayer.date] = []; - acc[prayer.date].push(prayer); - return acc; - }, {} as Record); + const filtered = useMemo(() => { + return prayers + .filter(p => { + // Search filter + const matchesSearch = fuzzyMatch(p.text, searchTerm) || + fuzzyMatch(p.prayFor || '', searchTerm); + if (!matchesSearch) return false; + + // Answered filter + if (filterAnswered === 'answered' && !p.answered) return false; + if (filterAnswered === 'unanswered' && p.answered) return false; + + return true; + }) + .sort((a, b) => { + const comparison = new Date(b.date).getTime() - new Date(a.date).getTime(); + return sortOrder === 'newest' ? comparison : -comparison; + }); + }, [prayers, searchTerm, sortOrder, filterAnswered]); + + const grouped = useMemo(() => { + return filtered.reduce((acc, prayer) => { + if (!acc[prayer.date]) acc[prayer.date] = []; + acc[prayer.date].push(prayer); + return acc; + }, {} as Record); + }, [filtered]); + + const resultCount = filtered.length; return ( -
+
{/* Header */}
-

- Past Prayers -

-

- Browse and reflect on your prayer history +

Past Prayers

+

+ {resultCount} {resultCount === 1 ? 'prayer' : 'prayers'} found

@@ -53,31 +80,67 @@ export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerLis
setSearchTerm(e.target.value)} - className="w-full px-4 py-3 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" + className="w-full px-4 py-3 rounded-lg border border-slate-600 bg-slate-800 text-white placeholder-slate-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" /> + + {/* Sort Options */}
+
+ + {/* Answer Status Filter */} +
+ + +
@@ -86,9 +149,20 @@ export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerLis
{filtered.length === 0 ? (
-

- No prayers found. {searchTerm && 'Try adjusting your search.'} +

+ {searchTerm || filterAnswered !== 'all' ? '❌ No prayers match your filters.' : '📝 No prayers yet. Start praying!'}

+ {searchTerm && ( + + )}
) : ( Object.keys(grouped) @@ -96,7 +170,7 @@ export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerLis .reverse() .map(date => (
-

+

{new Date(date).toLocaleDateString('en-US', { weekday: 'long', month: 'short', @@ -112,19 +186,26 @@ export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerLis {grouped[date].map(prayer => (
onPrayerClick(prayer)} > - {prayer.prayFor && ( -

- Praying for: {prayer.prayFor} -

- )} -

- {prayer.text} -

+
+ {prayer.answered && ( + ✅ + )} +
+ {prayer.prayFor && ( +

+ 🙏 {prayer.prayFor} +

+ )} +

+ {prayer.text} +

+
+
- + {new Date(date).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', @@ -135,7 +216,7 @@ export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerLis e.stopPropagation(); onEdit(prayer); }} - className="text-xs px-3 py-1 bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-400 rounded hover:bg-blue-200 dark:hover:bg-blue-800 transition-colors" + className="text-xs px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors" > Edit