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 */} +
+ {/* Date Input */} +
+ + onDateChange(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 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all" + /> +
+ + {/* Pray For */} +
+ + onPrayForChange(e.target.value)} + placeholder="Person, situation, or concern..." + 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" + /> +
+ + {/* Prayer Text */} +
+ +