diff --git a/public/manifest.json b/public/manifest.json index f19d461..4437ead 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -6,6 +6,8 @@ "display": "standalone", "background_color": "#000000", "theme_color": "#000000", + "gcm_sender_id": "555011794707", + "gcm_user_visible_only": true, "icons": [ { "src": "/icon-192x192.png", diff --git a/public/sw.js b/public/sw.js index b5054ef..bdd5c1f 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1 +1 @@ -if(!self.define){let e,s={};const n=(n,a)=>(n=new URL(n+".js",a).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(a,i)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let c={};const r=e=>n(e,t),f={module:{uri:t},exports:c,require:r};s[t]=Promise.all(a.map(e=>f[e]||r(e))).then(e=>(i(...e),c))}}define(["./workbox-4754cb34"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/static/AM_vEQgIshalV3dcCH-v2/_buildManifest.js",revision:"a91cb247fd17096d2ba17603cfdf5fe7"},{url:"/_next/static/AM_vEQgIshalV3dcCH-v2/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/104.b9111a893f0ad9d9.js",revision:"b9111a893f0ad9d9"},{url:"/_next/static/chunks/136-3bb757effc059d69.js",revision:"3bb757effc059d69"},{url:"/_next/static/chunks/139.678015000317a168.js",revision:"678015000317a168"},{url:"/_next/static/chunks/164f4fb6-a2df26e501616e62.js",revision:"a2df26e501616e62"},{url:"/_next/static/chunks/199.6d8b2513760bb8a6.js",revision:"6d8b2513760bb8a6"},{url:"/_next/static/chunks/2f0b94e8-4e6d0ae97e147ff2.js",revision:"4e6d0ae97e147ff2"},{url:"/_next/static/chunks/4bd1b696-b7529f9b306ab05d.js",revision:"b7529f9b306ab05d"},{url:"/_next/static/chunks/512-8d2b9de6fda25175.js",revision:"8d2b9de6fda25175"},{url:"/_next/static/chunks/646.30443a55a43a3bfb.js",revision:"30443a55a43a3bfb"},{url:"/_next/static/chunks/745-f204172863dcffd8.js",revision:"f204172863dcffd8"},{url:"/_next/static/chunks/7508b87c-580313408902bce8.js",revision:"580313408902bce8"},{url:"/_next/static/chunks/804.7f3d4655e2446c89.js",revision:"7f3d4655e2446c89"},{url:"/_next/static/chunks/931.6ff3e03b1cc8cdf1.js",revision:"6ff3e03b1cc8cdf1"},{url:"/_next/static/chunks/995.a093d11da39e25d3.js",revision:"a093d11da39e25d3"},{url:"/_next/static/chunks/ad2866b8.f49c70da33da3b7b.js",revision:"f49c70da33da3b7b"},{url:"/_next/static/chunks/app/_global-error/page-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/app/_not-found/page-1123cfe416c748d0.js",revision:"1123cfe416c748d0"},{url:"/_next/static/chunks/app/api/send-email/route-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/app/api/send-scheduled-emails/route-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/app/layout-c9bbec85d61ab45b.js",revision:"c9bbec85d61ab45b"},{url:"/_next/static/chunks/app/page-db2e38321401f568.js",revision:"db2e38321401f568"},{url:"/_next/static/chunks/bc98253f.ac7fe72f9e73e374.js",revision:"ac7fe72f9e73e374"},{url:"/_next/static/chunks/dd8162e8-bea2cd35813297c3.js",revision:"bea2cd35813297c3"},{url:"/_next/static/chunks/framework-292291387d6b2e39.js",revision:"292291387d6b2e39"},{url:"/_next/static/chunks/main-7ddb690de3906442.js",revision:"7ddb690de3906442"},{url:"/_next/static/chunks/main-app-4f19d69ed4295336.js",revision:"4f19d69ed4295336"},{url:"/_next/static/chunks/next/dist/client/components/builtin/app-error-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/next/dist/client/components/builtin/forbidden-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/next/dist/client/components/builtin/global-error-bcba0732671665d2.js",revision:"bcba0732671665d2"},{url:"/_next/static/chunks/next/dist/client/components/builtin/not-found-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/next/dist/client/components/builtin/unauthorized-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-8c242ea63ddea351.js",revision:"8c242ea63ddea351"},{url:"/_next/static/css/ad9b900c70cc4212.css",revision:"ad9b900c70cc4212"},{url:"/_next/static/media/4cf2300e9c8272f7-s.p.woff2",revision:"18bae71b1e1b2bb25321090a3b563103"},{url:"/_next/static/media/747892c23ea88013-s.woff2",revision:"a0761690ccf4441ace5cec893b82d4ab"},{url:"/_next/static/media/8d697b304b401681-s.woff2",revision:"cc728f6c0adb04da0dfcb0fc436a8ae5"},{url:"/_next/static/media/93f479601ee12b01-s.p.woff2",revision:"da83d5f06d825c5ae65b7cca706cb312"},{url:"/_next/static/media/9610d9e46709d722-s.woff2",revision:"7b7c0ef93df188a852344fc272fc096b"},{url:"/_next/static/media/ba015fad6dcf6784-s.woff2",revision:"8ea4f719af3312a055caf09f34c89a77"},{url:"/file.svg",revision:"d09f95206c3fa0bb9bd9fefabfd0ea71"},{url:"/firebase-messaging-sw.js",revision:"04d66892653ef67e1151f1ec6c02420b"},{url:"/globe.svg",revision:"2aaafa6a49b6563925fe440891e32717"},{url:"/icon-192x192.png",revision:"bbbd7efc0e31088ae0a3aeede7608534"},{url:"/icon-512x512.png",revision:"400538d76556a3a8ee4fd3dfda7bc092"},{url:"/locales/en/common.json",revision:"54fe8b7b3b2f39e7604b236e7a480251"},{url:"/manifest.json",revision:"449f4fb79e469d905d66eb366077809a"},{url:"/next.svg",revision:"8e061864f388b47f33a1c3780831193e"},{url:"/vercel.svg",revision:"c0af2f507b369b085b35ef4bbe3bcf1e"},{url:"/window.svg",revision:"a2760511c65806022ad20adf74370ff3"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:n,state:a})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;const s=e.pathname;return!s.startsWith("/api/auth/")&&!!s.startsWith("/api/")},new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")},new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>!(self.origin===e.origin),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")}); +if(!self.define){let e,s={};const n=(n,a)=>(n=new URL(n+".js",a).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(a,i)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let c={};const r=e=>n(e,t),o={module:{uri:t},exports:c,require:r};s[t]=Promise.all(a.map(e=>o[e]||r(e))).then(e=>(i(...e),c))}}define(["./workbox-4754cb34"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/static/chunks/136-3bb757effc059d69.js",revision:"3bb757effc059d69"},{url:"/_next/static/chunks/139.678015000317a168.js",revision:"678015000317a168"},{url:"/_next/static/chunks/164f4fb6-a2df26e501616e62.js",revision:"a2df26e501616e62"},{url:"/_next/static/chunks/199.6d8b2513760bb8a6.js",revision:"6d8b2513760bb8a6"},{url:"/_next/static/chunks/2f0b94e8-4e6d0ae97e147ff2.js",revision:"4e6d0ae97e147ff2"},{url:"/_next/static/chunks/4bd1b696-b7529f9b306ab05d.js",revision:"b7529f9b306ab05d"},{url:"/_next/static/chunks/512-8d2b9de6fda25175.js",revision:"8d2b9de6fda25175"},{url:"/_next/static/chunks/646.30443a55a43a3bfb.js",revision:"30443a55a43a3bfb"},{url:"/_next/static/chunks/7508b87c-580313408902bce8.js",revision:"580313408902bce8"},{url:"/_next/static/chunks/931.6ff3e03b1cc8cdf1.js",revision:"6ff3e03b1cc8cdf1"},{url:"/_next/static/chunks/944-92743b4c3cdd31b5.js",revision:"92743b4c3cdd31b5"},{url:"/_next/static/chunks/995.a093d11da39e25d3.js",revision:"a093d11da39e25d3"},{url:"/_next/static/chunks/ad2866b8.f49c70da33da3b7b.js",revision:"f49c70da33da3b7b"},{url:"/_next/static/chunks/app/_global-error/page-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/app/_not-found/page-1123cfe416c748d0.js",revision:"1123cfe416c748d0"},{url:"/_next/static/chunks/app/api/send-email/route-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/app/api/send-scheduled-emails/route-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/app/layout-3a7f53b5adc6c74a.js",revision:"3a7f53b5adc6c74a"},{url:"/_next/static/chunks/app/page-cde09a561bebd963.js",revision:"cde09a561bebd963"},{url:"/_next/static/chunks/bc98253f.ac7fe72f9e73e374.js",revision:"ac7fe72f9e73e374"},{url:"/_next/static/chunks/dd8162e8-bea2cd35813297c3.js",revision:"bea2cd35813297c3"},{url:"/_next/static/chunks/framework-292291387d6b2e39.js",revision:"292291387d6b2e39"},{url:"/_next/static/chunks/main-7ddb690de3906442.js",revision:"7ddb690de3906442"},{url:"/_next/static/chunks/main-app-4f19d69ed4295336.js",revision:"4f19d69ed4295336"},{url:"/_next/static/chunks/next/dist/client/components/builtin/app-error-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/next/dist/client/components/builtin/forbidden-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/next/dist/client/components/builtin/global-error-bcba0732671665d2.js",revision:"bcba0732671665d2"},{url:"/_next/static/chunks/next/dist/client/components/builtin/not-found-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/next/dist/client/components/builtin/unauthorized-7ff1880bba064291.js",revision:"7ff1880bba064291"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-a837e9e033373f23.js",revision:"a837e9e033373f23"},{url:"/_next/static/css/2399cab8684792c9.css",revision:"2399cab8684792c9"},{url:"/_next/static/lz7o_GMdaM2vsk8rbh2E-/_buildManifest.js",revision:"a91cb247fd17096d2ba17603cfdf5fe7"},{url:"/_next/static/lz7o_GMdaM2vsk8rbh2E-/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/media/4cf2300e9c8272f7-s.p.woff2",revision:"18bae71b1e1b2bb25321090a3b563103"},{url:"/_next/static/media/747892c23ea88013-s.woff2",revision:"a0761690ccf4441ace5cec893b82d4ab"},{url:"/_next/static/media/8d697b304b401681-s.woff2",revision:"cc728f6c0adb04da0dfcb0fc436a8ae5"},{url:"/_next/static/media/93f479601ee12b01-s.p.woff2",revision:"da83d5f06d825c5ae65b7cca706cb312"},{url:"/_next/static/media/9610d9e46709d722-s.woff2",revision:"7b7c0ef93df188a852344fc272fc096b"},{url:"/_next/static/media/ba015fad6dcf6784-s.woff2",revision:"8ea4f719af3312a055caf09f34c89a77"},{url:"/file.svg",revision:"d09f95206c3fa0bb9bd9fefabfd0ea71"},{url:"/firebase-messaging-sw.js",revision:"04d66892653ef67e1151f1ec6c02420b"},{url:"/globe.svg",revision:"2aaafa6a49b6563925fe440891e32717"},{url:"/icon-192x192.png",revision:"bbbd7efc0e31088ae0a3aeede7608534"},{url:"/icon-512x512.png",revision:"400538d76556a3a8ee4fd3dfda7bc092"},{url:"/locales/en/common.json",revision:"54fe8b7b3b2f39e7604b236e7a480251"},{url:"/manifest.json",revision:"8f6840ae163d807596c5d5736a6300a3"},{url:"/next.svg",revision:"8e061864f388b47f33a1c3780831193e"},{url:"/vercel.svg",revision:"c0af2f507b369b085b35ef4bbe3bcf1e"},{url:"/window.svg",revision:"a2760511c65806022ad20adf74370ff3"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:n,state:a})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;const s=e.pathname;return!s.startsWith("/api/auth/")&&!!s.startsWith("/api/")},new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")},new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(({url:e})=>!(self.origin===e.origin),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")}); diff --git a/src/app/page.tsx b/src/app/page.tsx index b95d5da..83ea465 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -6,7 +6,7 @@ import Login from '@/components/Login'; import Admin from '@/components/Admin'; import Profile from '@/components/Profile'; import { db } from '@/lib/firebase'; -import { doc, setDoc, collection, addDoc, getDocs, updateDoc, query, where } from 'firebase/firestore'; +import { doc, setDoc, collection, addDoc, getDocs, updateDoc, query, where, getDoc } from 'firebase/firestore'; import emailjs from '@emailjs/browser'; import jsPDF from 'jspdf'; import { CSVLink } from 'react-csv'; @@ -23,6 +23,8 @@ interface Prayer { archived?: boolean; reminderFrequency?: 'daily' | 'weekly' | 'monthly' | 'never'; includeActiveSummary?: boolean; + answered?: boolean; + answeredDate?: string; } export default function Home() { @@ -47,6 +49,10 @@ export default function Home() { const { user, loading, logout, isAdmin } = useAuth(); const [showLoadingScreen, setShowLoadingScreen] = useState(true); const [editingPrayer, setEditingPrayer] = useState(null); + const [dateFrom, setDateFrom] = useState(''); + const [dateTo, setDateTo] = useState(''); + const [typeFilter, setTypeFilter] = useState<'all' | 'prayer' | 'praise'>('all'); + const [userProfile, setUserProfile] = useState({}); // Ensure loading screen shows for at least 5 seconds useEffect(() => { @@ -108,6 +114,23 @@ export default function Home() { loadSharedPrayers(); }, []); + // Load user profile + useEffect(() => { + const loadUserProfile = async () => { + if (!user) return; + try { + const docRef = doc(db, 'users', user.uid); + const docSnap = await getDoc(docRef); + if (docSnap.exists()) { + setUserProfile(docSnap.data()); + } + } catch (error) { + console.error('Error loading user profile:', error); + } + }; + loadUserProfile(); + }, [user]); + // Export functions const exportToPDF = (prayerList: Prayer[], title: string) => { const doc = new jsPDF(); @@ -291,26 +314,37 @@ export default function Home() { const activePrayers = prayers.filter(prayer => !prayer.archived); const archivedPrayers = prayers.filter(prayer => prayer.archived); - // Filter prayers based on search term - const filteredActivePrayers = activePrayers.filter(prayer => - prayer.text.toLowerCase().includes(searchTerm.toLowerCase()) || - prayer.journal.toLowerCase().includes(searchTerm.toLowerCase()) || - prayer.type.toLowerCase().includes(searchTerm.toLowerCase()) - ); - - const filteredArchivedPrayers = archivedPrayers.filter(prayer => - prayer.text.toLowerCase().includes(searchTerm.toLowerCase()) || - prayer.journal.toLowerCase().includes(searchTerm.toLowerCase()) || - prayer.type.toLowerCase().includes(searchTerm.toLowerCase()) - ); + // Enhanced filtering function + const applyFilters = (prayerList: Prayer[]) => { + return prayerList.filter(prayer => { + // Keyword search + const matchesSearch = !searchTerm || + prayer.text.toLowerCase().includes(searchTerm.toLowerCase()) || + prayer.journal.toLowerCase().includes(searchTerm.toLowerCase()) || + prayer.type.toLowerCase().includes(searchTerm.toLowerCase()) || + prayer.prayFor.toLowerCase().includes(searchTerm.toLowerCase()); + // Date range filter + const prayerDate = new Date(prayer.date); + const fromDate = dateFrom ? new Date(dateFrom) : null; + const toDateFilter = dateTo ? new Date(dateTo) : null; + const matchesDateFrom = !fromDate || prayerDate >= fromDate; + const matchesDateTo = !toDateFilter || prayerDate <= toDateFilter; + + // Type filter + const matchesType = typeFilter === 'all' || prayer.type === typeFilter; + + return matchesSearch && matchesDateFrom && matchesDateTo && matchesType; + }); + }; + + // Apply filters to each prayer list + const filteredActivePrayers = applyFilters(activePrayers); + const filteredArchivedPrayers = applyFilters(archivedPrayers); + // For search tab, combine all filtered prayers const allPrayers = [...activePrayers, ...archivedPrayers]; - const filteredSearchPrayers = allPrayers.filter(prayer => - prayer.text.toLowerCase().includes(searchTerm.toLowerCase()) || - prayer.journal.toLowerCase().includes(searchTerm.toLowerCase()) || - prayer.type.toLowerCase().includes(searchTerm.toLowerCase()) - ); + const filteredSearchPrayers = applyFilters(allPrayers); // Pagination logic const totalActivePages = Math.ceil(filteredActivePrayers.length / itemsPerPage); @@ -422,6 +456,34 @@ export default function Home() { } }; + // Mark prayer as answered/unanswered + const toggleAnsweredPrayer = async (prayerId: string, answered: boolean) => { + try { + const updateData: any = { answered }; + if (answered) { + updateData.answeredDate = new Date().toISOString().split('T')[0]; + } else { + updateData.answeredDate = null; + } + + await updateDoc(doc(db, 'prayers', prayerId), updateData); + + // Update local state + setPrayers(prev => prev.map(p => + p.id === prayerId ? { ...p, answered, answeredDate: answered ? new Date().toISOString().split('T')[0] : undefined } : p + )); + + // Send notification if answered and notifications are enabled + if (answered && userProfile.notificationsEnabled) { + // This would trigger a server-side notification via Firebase Functions + console.log('Prayer answered - notification would be sent'); + } + } catch (error) { + console.error('Error updating prayer answered status:', error); + alert('Failed to update prayer. Please try again.'); + } + }; + // Start editing a prayer const startEditing = (prayer: Prayer) => { setEditingPrayer(prayer); @@ -686,23 +748,75 @@ export default function Home() { {activeTab !== 'add' && (
{activeTab === 'search' && ( -
- { - setSearchTerm(e.target.value); - setCurrentPage(1); // Reset to first page when searching - }} - className="w-full p-3 bg-gray-800 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500" - autoFocus - /> - {searchTerm && ( -

- Found {filteredSearchPrayers.length} prayer{filteredSearchPrayers.length !== 1 ? 's' : ''} -

- )} +
+
+ { + setSearchTerm(e.target.value); + setCurrentPage(1); + }} + className="p-3 bg-gray-800 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + + + + { + setDateFrom(e.target.value); + setCurrentPage(1); + }} + className="p-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + + { + setDateTo(e.target.value); + setCurrentPage(1); + }} + className="p-3 bg-gray-800 border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500" + /> +
+ +
+ + + {(searchTerm || typeFilter !== 'all' || dateFrom || dateTo) && ( +

+ Found {filteredSearchPrayers.length} prayer{filteredSearchPrayers.length !== 1 ? 's' : ''} +

+ )} +
)} @@ -757,7 +871,26 @@ export default function Home() {
)} {activeTab !== 'search' && ( -
+
+
+ {prayer.answered && ( + + ✅ Answered {prayer.answeredDate && `on ${new Date(prayer.answeredDate).toLocaleDateString()}`} + + )} + +
+ {prayer.archived ? (