Major improvements: Firebase data migration, enhanced loading screens, multi-day prayer tracking

- Migrated all localStorage data to Firebase for cross-device sync
  - Prayer drafts now stored in users/{userId}/drafts
  - Reminder settings in users/{userId}/settings
  - Prayer statistics in users/{userId}/statistics
- Implemented persistent 'most prayed for' tracking in Firebase
- Enhanced loading screen with animated backgrounds and gradients
- Fixed auth session restoration on hard refresh
- Added prayedDates array for multi-day prayer tracking
- Calendar now accurately shows all days a prayer was prayed for
- Enabled Firestore offline persistence for offline-first experience
- Updated Firestore security rules for new data structure
- Improved clock display (removed leading zero from hours)
- Moved clock below date on homepage with appropriate sizing
- Fixed data loading race conditions between auth and Firestore
This commit is contained in:
nmemmert committed 2026-01-19 10:11:57 -05:00
1 parent 2c29fc28d6
commit 67c5ff1b35
13 files changed
+419 -138

No files matched your search

+24 -22
View File
@@ -14,6 +14,7 @@ interface Prayer {
answerDetails?: string;
prayFrequency?: number; // 1-7 times per week
lastPrayedFor?: string; // ISO date string
prayedDates?: string[]; // Array of dates when prayed for
}
interface HomePageProps {
@@ -22,9 +23,10 @@ interface HomePageProps {
onStartPraying: () => void;
onSelectPrayer: (prayer: Prayer) => void;
userName?: string;
mostPrayedFor?: string;
}
export default function HomePage({ prayers, todayCount, onStartPraying, onSelectPrayer, userName }: HomePageProps) {
export default function HomePage({ prayers, todayCount, onStartPraying, onSelectPrayer, userName, mostPrayedFor }: HomePageProps) {
const today = new Date().toISOString().split('T')[0];
const todayPrayers = prayers.filter(p => p.date === today);
const recentPrayers = prayers.slice(0, 5);
@@ -55,7 +57,12 @@ export default function HomePage({ prayers, todayCount, onStartPraying, onSelect
const activePrayerCount = prayers.filter(p => !p.answered).length;
// Count how many active prayers were prayed for today
const prayedTodayCount = prayers.filter(p => !p.answered && p.lastPrayedFor === today).length;
const prayedTodayCount = prayers.filter(p =>
!p.answered && (
p.prayedDates?.includes(today) ||
p.lastPrayedFor === today
)
).length;
// Calculate actual streak - consecutive days with prayers
const calculateStreak = () => {
@@ -65,8 +72,13 @@ export default function HomePage({ prayers, todayCount, onStartPraying, onSelect
const activityDates = new Set<string>();
prayers.forEach(p => {
activityDates.add(p.date); // Date prayer was created
if (p.lastPrayedFor) {
activityDates.add(p.lastPrayedFor); // Date marked as prayed for
// Add all prayed dates from the array
if (p.prayedDates && p.prayedDates.length > 0) {
p.prayedDates.forEach((date: string) => activityDates.add(date));
} else if (p.lastPrayedFor) {
// Backward compatibility
activityDates.add(p.lastPrayedFor);
}
});
@@ -101,15 +113,6 @@ export default function HomePage({ prayers, todayCount, onStartPraying, onSelect
? Math.round((answeredPrayers / totalPrayers) * 100)
: 0;
// Get most prayed for person/topic based on lastPrayedFor clicks
const prayerForCounts: Record<string, number> = {};
prayers.forEach(p => {
if (p.prayFor && p.lastPrayedFor) {
prayerForCounts[p.prayFor] = (prayerForCounts[p.prayFor] || 0) + 1;
}
});
const mostPrayedFor = Object.entries(prayerForCounts).sort((a, b) => b[1] - a[1])[0];
// Recent answered prayers
const recentAnswered = prayers.filter(p => p.answered).slice(0, 3);
@@ -122,15 +125,8 @@ export default function HomePage({ prayers, todayCount, onStartPraying, onSelect
<div className="absolute bottom-20 left-10 w-72 h-72 bg-purple-500/10 rounded-full blur-3xl"></div>
</div>
{/* Clock */}
<div className="max-w-md mx-auto mb-12">
<div className="text-center">
<Clock />
</div>
</div>
{/* Header with Personalized Greeting */}
<div className="max-w-md mx-auto mb-12 text-center">
<div className="max-w-md mx-auto mb-8 text-center">
<img src="/icon-192x192.png" alt="Haver icon" className="w-12 h-12 mx-auto mb-3 rounded" />
<h1 className="text-4xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent mb-3">
{getGreeting()}, {getFirstName()}!
@@ -151,9 +147,15 @@ export default function HomePage({ prayers, todayCount, onStartPraying, onSelect
All caught up! Start a new prayer to keep your journey going.
</p>
)}
<p className="text-slate-400 mt-2">
<p className="text-slate-400 mt-4 text-sm">
{new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}
</p>
{/* Clock - Below Date */}
<div className="mt-3 flex justify-center">
<div className="scale-75">
<Clock />
</div>
</div>
</div>
{/* Stats Grid */}