fix: restore page.tsx that was accidentally deleted
The main application page was deleted in the previous commit. Recreated with all functionality for the daily prayer journal redesign.
This commit is contained in:
1 parent
a5390e22be
commit
9c73674c84
1 file changed
+223
@@ -0,0 +1,223 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useAuth } from '@/context/AuthContext';
|
||||||
|
import Login from '@/components/Login';
|
||||||
|
import LoadingSkeleton from '@/components/LoadingSkeleton';
|
||||||
|
import BottomNav from '@/components/BottomNav';
|
||||||
|
import DailyEntry from '@/components/DailyEntry';
|
||||||
|
import CalendarView from '@/components/CalendarView';
|
||||||
|
import ReflectionsList from '@/components/ReflectionsList';
|
||||||
|
import SettingsPage from '@/components/SettingsPage';
|
||||||
|
import { db } from '@/lib/firebase';
|
||||||
|
import { collection, addDoc, getDocs, updateDoc, query, where, doc } from 'firebase/firestore';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
|
||||||
|
interface Prayer {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
date: string;
|
||||||
|
text: string;
|
||||||
|
prayFor?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
const [activeTab, setActiveTab] = useState<'home' | 'journal' | 'reflections' | 'settings'>('home');
|
||||||
|
const [prayers, setPrayers] = useState<Prayer[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [editingPrayer, setEditingPrayer] = useState<Prayer | null>(null);
|
||||||
|
|
||||||
|
// Form state
|
||||||
|
const [date, setDate] = useState(new Date().toISOString().split('T')[0]);
|
||||||
|
const [text, setText] = useState('');
|
||||||
|
const [prayFor, setPrayFor] = useState('');
|
||||||
|
|
||||||
|
const { user, loading: authLoading } = useAuth();
|
||||||
|
|
||||||
|
// Load prayers from Firestore
|
||||||
|
useEffect(() => {
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
|
const loadPrayers = async () => {
|
||||||
|
try {
|
||||||
|
const prayersRef = collection(db, 'prayers');
|
||||||
|
const q = query(prayersRef, where('userId', '==', user.uid));
|
||||||
|
const querySnapshot = await getDocs(q);
|
||||||
|
|
||||||
|
const loadedPrayers: Prayer[] = [];
|
||||||
|
querySnapshot.forEach((doc) => {
|
||||||
|
loadedPrayers.push({ id: doc.id, ...doc.data() } as Prayer);
|
||||||
|
});
|
||||||
|
|
||||||
|
setPrayers(loadedPrayers);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading prayers:', error);
|
||||||
|
toast.error('Failed to load prayers');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadPrayers();
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
|
// Load draft from localStorage
|
||||||
|
useEffect(() => {
|
||||||
|
const draft = localStorage.getItem('prayerDraft');
|
||||||
|
if (draft) {
|
||||||
|
try {
|
||||||
|
const { date: draftDate, text: draftText, prayFor: draftPrayFor } = JSON.parse(draft);
|
||||||
|
setDate(draftDate || new Date().toISOString().split('T')[0]);
|
||||||
|
setText(draftText || '');
|
||||||
|
setPrayFor(draftPrayFor || '');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error loading draft:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Save draft to localStorage
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem('prayerDraft', JSON.stringify({ date, text, prayFor }));
|
||||||
|
}, [date, text, prayFor]);
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
toast.error('Please log in to save prayers');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!text.trim()) {
|
||||||
|
toast.error('Please write something');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const prayerData = {
|
||||||
|
userId: user.uid,
|
||||||
|
date,
|
||||||
|
text,
|
||||||
|
prayFor: prayFor || undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (editingPrayer) {
|
||||||
|
// Update existing prayer
|
||||||
|
await updateDoc(doc(db, 'prayers', editingPrayer.id), prayerData);
|
||||||
|
setPrayers(prev =>
|
||||||
|
prev.map(p => (p.id === editingPrayer.id ? { ...p, ...prayerData } : p))
|
||||||
|
);
|
||||||
|
toast.success('Prayer updated! 🙏');
|
||||||
|
setEditingPrayer(null);
|
||||||
|
} else {
|
||||||
|
// Add new prayer
|
||||||
|
const docRef = await addDoc(collection(db, 'prayers'), prayerData);
|
||||||
|
const newPrayer: Prayer = { id: docRef.id, ...prayerData };
|
||||||
|
setPrayers(prev => [...prev, newPrayer]);
|
||||||
|
toast.success('Prayer saved! 🙏');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset form
|
||||||
|
setDate(new Date().toISOString().split('T')[0]);
|
||||||
|
setText('');
|
||||||
|
setPrayFor('');
|
||||||
|
localStorage.removeItem('prayerDraft');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error saving prayer:', error);
|
||||||
|
toast.error('Failed to save prayer');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectPrayer = (prayer: Prayer) => {
|
||||||
|
setEditingPrayer(prayer);
|
||||||
|
setDate(prayer.date);
|
||||||
|
setText(prayer.text);
|
||||||
|
setPrayFor(prayer.prayFor || '');
|
||||||
|
setActiveTab('home');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDateClick = (clickedDate: string) => {
|
||||||
|
const dayPrayers = prayers.filter(p => p.date === clickedDate);
|
||||||
|
if (dayPrayers.length > 0) {
|
||||||
|
handleSelectPrayer(dayPrayers[0]);
|
||||||
|
} else {
|
||||||
|
setDate(clickedDate);
|
||||||
|
setActiveTab('home');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (authLoading || loading) {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-black to-slate-800 flex items-center justify-center p-4">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="mb-8 relative">
|
||||||
|
<div className="w-24 h-24 mx-auto relative">
|
||||||
|
<div className="absolute inset-0 border-4 border-blue-500/30 rounded-full animate-spin"></div>
|
||||||
|
<div
|
||||||
|
className="absolute inset-2 border-4 border-transparent border-t-blue-400 rounded-full animate-spin"
|
||||||
|
style={{ animationDirection: 'reverse', animationDuration: '1.5s' }}
|
||||||
|
></div>
|
||||||
|
<div className="absolute inset-0 flex items-center justify-center">
|
||||||
|
<div className="text-3xl animate-pulse">🙏</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="text-2xl font-bold text-white mb-2 animate-pulse">Prayer Journal</h1>
|
||||||
|
<p className="text-gray-400 text-lg mb-4">Preparing your sacred space...</p>
|
||||||
|
|
||||||
|
<div className="max-w-xs mx-auto">
|
||||||
|
<blockquote className="text-gray-300 italic text-sm leading-relaxed">
|
||||||
|
"Be anxious for nothing, but in everything by prayer and supplication, with thanksgiving, let your requests be made known to God."
|
||||||
|
</blockquote>
|
||||||
|
<cite className="text-gray-500 text-xs mt-2 block">— Philippians 4:6</cite>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-center space-x-2 mt-8">
|
||||||
|
<div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '0s' }}></div>
|
||||||
|
<div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '0.2s' }}></div>
|
||||||
|
<div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '0.4s' }}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return <Login />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800">
|
||||||
|
<BottomNav activeTab={activeTab} onTabChange={setActiveTab} />
|
||||||
|
|
||||||
|
{activeTab === 'home' && (
|
||||||
|
<DailyEntry
|
||||||
|
date={date}
|
||||||
|
onDateChange={setDate}
|
||||||
|
text={text}
|
||||||
|
onTextChange={setText}
|
||||||
|
prayFor={prayFor}
|
||||||
|
onPrayForChange={setPrayFor}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
isEditing={!!editingPrayer}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{activeTab === 'journal' && (
|
||||||
|
<CalendarView prayers={prayers} onDayClick={handleDateClick} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{activeTab === 'reflections' && (
|
||||||
|
<ReflectionsList
|
||||||
|
prayers={prayers}
|
||||||
|
onPrayerClick={handleSelectPrayer}
|
||||||
|
onEdit={handleSelectPrayer}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{activeTab === 'settings' && <SettingsPage userEmail={user.email || undefined} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user