diff --git a/src/components/BottomNav.tsx b/src/components/BottomNav.tsx
new file mode 100644
index 0000000..e20a7e5
--- /dev/null
+++ b/src/components/BottomNav.tsx
@@ -0,0 +1,76 @@
+'use client';
+
+import React from 'react';
+import { useAuth } from '@/context/AuthContext';
+
+interface BottomNavProps {
+ activeTab: 'home' | 'journal' | 'reflections' | 'settings';
+ onTabChange: (tab: 'home' | 'journal' | 'reflections' | 'settings') => void;
+}
+
+export default function BottomNav({ activeTab, onTabChange }: BottomNavProps) {
+ const { logout, user } = useAuth();
+
+ const navItems = [
+ { id: 'home' as const, label: 'Home', icon: '🏠' },
+ { id: 'journal' as const, label: 'Journal', icon: '📅' },
+ { id: 'reflections' as const, label: 'Reflections', icon: '📖' },
+ { id: 'settings' as const, label: 'Settings', icon: '⚙️' },
+ ];
+
+ return (
+ <>
+ {/* Mobile Bottom Navigation */}
+
+
+ {/* Desktop Top Navigation */}
+
+
+ {/* Mobile padding for bottom nav */}
+
+ >
+ );
+}
diff --git a/src/components/CalendarView.tsx b/src/components/CalendarView.tsx
new file mode 100644
index 0000000..aa59602
--- /dev/null
+++ b/src/components/CalendarView.tsx
@@ -0,0 +1,149 @@
+'use client';
+
+import React, { useState, useMemo } from 'react';
+
+interface Prayer {
+ id: string;
+ date: string;
+ text: string;
+ prayFor?: string;
+}
+
+interface CalendarViewProps {
+ prayers: Prayer[];
+ onDayClick: (date: string) => void;
+}
+
+export default function CalendarView({ prayers, onDayClick }: CalendarViewProps) {
+ const [currentMonth, setCurrentMonth] = useState(new Date());
+
+ const daysWithEntries = useMemo(() => {
+ return new Set(prayers.map(p => p.date));
+ }, [prayers]);
+
+ const getDaysInMonth = (date: Date) => {
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
+ };
+
+ const getFirstDayOfMonth = (date: Date) => {
+ return new Date(date.getFullYear(), date.getMonth(), 1).getDay();
+ };
+
+ const daysInMonth = getDaysInMonth(currentMonth);
+ const firstDay = getFirstDayOfMonth(currentMonth);
+ const prevMonth = () =>
+ setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1));
+ const nextMonth = () =>
+ setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1));
+
+ const days = [];
+ for (let i = 0; i < firstDay; i++) {
+ days.push(null);
+ }
+ for (let i = 1; i <= daysInMonth; i++) {
+ days.push(i);
+ }
+
+ return (
+
+
+ {/* Header */}
+
+
+ Prayer Journal
+
+
+ Click on days with entries to view them
+
+
+
+ {/* Calendar */}
+
+ {/* Month Navigation */}
+
+
+
+ {currentMonth.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
+
+
+
+
+ {/* Day Headers */}
+
+ {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(day => (
+
+ {day}
+
+ ))}
+
+
+ {/* Calendar Days */}
+
+ {days.map((day, index) => {
+ const dateString =
+ day !== null
+ ? `${currentMonth.getFullYear()}-${String(currentMonth.getMonth() + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`
+ : null;
+ const hasEntry = dateString ? daysWithEntries.has(dateString) : false;
+ const prayerCount = dateString
+ ? prayers.filter(p => p.date === dateString).length
+ : 0;
+
+ return (
+
+ );
+ })}
+
+
+
+ {/* Stats */}
+
+
+
Total Entries
+
{prayers.length}
+
+
+
Days with Entries
+
+ {daysWithEntries.size}
+
+
+
+
+
+ );
+}
diff --git a/src/components/DailyEntry.tsx b/src/components/DailyEntry.tsx
new file mode 100644
index 0000000..1302ea1
--- /dev/null
+++ b/src/components/DailyEntry.tsx
@@ -0,0 +1,111 @@
+'use client';
+
+import React, { useState } from 'react';
+import toast from 'react-hot-toast';
+
+interface DailyEntryProps {
+ date: string;
+ onDateChange: (date: string) => void;
+ text: string;
+ onTextChange: (text: string) => void;
+ prayFor: string;
+ onPrayForChange: (prayFor: string) => void;
+ onSubmit: (e: React.FormEvent) => void;
+ loading?: boolean;
+ isEditing?: boolean;
+}
+
+export default function DailyEntry({
+ date,
+ onDateChange,
+ text,
+ onTextChange,
+ prayFor,
+ onPrayForChange,
+ onSubmit,
+ loading = false,
+ isEditing = false,
+}: DailyEntryProps) {
+ const today = new Date().toISOString().split('T')[0];
+ const isToday = date === today;
+
+ return (
+
+
+ {/* Header */}
+
+
+ {isToday ? "Today's Prayer" : 'Prayer Entry'}
+
+
+ {new Date(date).toLocaleDateString('en-US', {
+ weekday: 'long',
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric',
+ })}
+
+
+
+ {/* Entry Form */}
+
+
+ {/* Word Count */}
+
+ {text.length > 0 && `${text.split(/\s+/).filter(w => w).length} words`}
+
+
+
+ );
+}
diff --git a/src/components/ReflectionsList.tsx b/src/components/ReflectionsList.tsx
new file mode 100644
index 0000000..78b9894
--- /dev/null
+++ b/src/components/ReflectionsList.tsx
@@ -0,0 +1,153 @@
+'use client';
+
+import React, { useState } from 'react';
+
+interface Prayer {
+ id: string;
+ date: string;
+ text: string;
+ prayFor?: string;
+}
+
+interface PrayerListProps {
+ prayers: Prayer[];
+ onPrayerClick: (prayer: Prayer) => void;
+ onEdit: (prayer: Prayer) => void;
+}
+
+export default function PrayerList({ prayers, onPrayerClick, onEdit }: PrayerListProps) {
+ const [searchTerm, setSearchTerm] = useState('');
+ const [sortOrder, setSortOrder] = useState<'newest' | 'oldest'>('newest');
+
+ 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;
+ });
+
+ const grouped = filtered.reduce((acc, prayer) => {
+ if (!acc[prayer.date]) acc[prayer.date] = [];
+ acc[prayer.date].push(prayer);
+ return acc;
+ }, {} as Record);
+
+ return (
+
+
+ {/* Header */}
+
+
+ Past Prayers
+
+
+ Browse and reflect on your prayer history
+
+
+
+ {/* Filters */}
+
+
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"
+ />
+
+
+
+
+
+
+ {/* Prayers List */}
+
+ {filtered.length === 0 ? (
+
+
+ No prayers found. {searchTerm && 'Try adjusting your search.'}
+
+
+ ) : (
+ Object.keys(grouped)
+ .sort()
+ .reverse()
+ .map(date => (
+
+
+ {new Date(date).toLocaleDateString('en-US', {
+ weekday: 'long',
+ month: 'short',
+ day: 'numeric',
+ year: grouped[date].some(
+ p => new Date(p.date).getFullYear() !== new Date().getFullYear()
+ )
+ ? 'numeric'
+ : undefined,
+ })}
+
+
+ {grouped[date].map(prayer => (
+
onPrayerClick(prayer)}
+ >
+ {prayer.prayFor && (
+
+ Praying for: {prayer.prayFor}
+
+ )}
+
+ {prayer.text}
+
+
+
+ {new Date(date).toLocaleTimeString('en-US', {
+ hour: 'numeric',
+ minute: '2-digit',
+ })}
+
+
+
+
+ ))}
+
+
+ ))
+ )}
+
+
+
+ );
+}
diff --git a/src/components/SettingsPage.tsx b/src/components/SettingsPage.tsx
new file mode 100644
index 0000000..155a5e4
--- /dev/null
+++ b/src/components/SettingsPage.tsx
@@ -0,0 +1,123 @@
+'use client';
+
+import React, { useState } from 'react';
+import { useAuth } from '@/context/AuthContext';
+import { useTheme } from 'next-themes';
+
+interface SettingsPageProps {
+ userEmail?: string;
+}
+
+export default function SettingsPage({ userEmail }: SettingsPageProps) {
+ const { logout } = useAuth();
+ const { theme, setTheme } = useTheme();
+ const [showConfirm, setShowConfirm] = useState(false);
+
+ return (
+
+
+ {/* Header */}
+
+
+ Settings
+
+
+ Manage your preferences and account
+
+
+
+ {/* Settings Card */}
+
+ {/* Account Section */}
+
+
+ Account
+
+
+
+
Email
+
{userEmail || 'Not set'}
+
+
+
+
+ {/* Appearance Section */}
+
+
+ Appearance
+
+
+
+ Theme
+
+
+ {['light', 'dark', 'system'].map(t => (
+
+ ))}
+
+
+
+
+ {/* About Section */}
+
+
+ About
+
+
+
Prayer Journal v1.0
+
A simple, private space for your daily prayers and reflections.
+
+
+
+ {/* Logout Section */}
+
+
+
+
+
+ {/* Logout Confirmation Modal */}
+ {showConfirm && (
+
+
+
+ Logout?
+
+
+ Are you sure you want to logout?
+
+
+
+
+
+
+
+ )}
+
+
+ );
+}