Add edit functionality for prayers and praises
This commit is contained in:
1 parent
fdfc4f5f3d
commit
aa3f42479f
2 files changed
+114
-52
No files matched your search
+1
-1
@@ -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 f=e=>n(e,t),r={module:{uri:t},exports:c,require:f};s[t]=Promise.all(a.map(e=>r[e]||f(e))).then(e=>(i(...e),c))}}define(["./workbox-4754cb34"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/static/Y4j-pLuzIB4ZdVSRsQP3m/_buildManifest.js",revision:"a91cb247fd17096d2ba17603cfdf5fe7"},{url:"/_next/static/Y4j-pLuzIB4ZdVSRsQP3m/_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-20f1fcb41d90ea78.js",revision:"20f1fcb41d90ea78"},{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/1d32dd5f31643a1d.css",revision:"1d32dd5f31643a1d"},{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/commonLine truncated
|
||||
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/commonLine truncated
|
||||
+113
-51
@@ -46,6 +46,7 @@ export default function Home() {
|
||||
const itemsPerPage = 10;
|
||||
const { user, loading, logout, isAdmin } = useAuth();
|
||||
const [showLoadingScreen, setShowLoadingScreen] = useState(true);
|
||||
const [editingPrayer, setEditingPrayer] = useState<Prayer | null>(null);
|
||||
|
||||
// Ensure loading screen shows for at least 5 seconds
|
||||
useEffect(() => {
|
||||
@@ -187,7 +188,7 @@ export default function Home() {
|
||||
}
|
||||
|
||||
try {
|
||||
const newPrayerData = {
|
||||
const prayerData = {
|
||||
userId: user.uid,
|
||||
date: form.date,
|
||||
type: form.type,
|
||||
@@ -197,63 +198,76 @@ export default function Home() {
|
||||
prayFor: form.prayFor,
|
||||
reminderFrequency: form.reminderFrequency,
|
||||
includeActiveSummary: form.includeActiveSummary,
|
||||
archived: false,
|
||||
archived: editingPrayer ? editingPrayer.archived : false,
|
||||
};
|
||||
|
||||
// Save to Firestore
|
||||
const docRef = await addDoc(collection(db, 'prayers'), newPrayerData);
|
||||
if (editingPrayer) {
|
||||
// Update existing prayer
|
||||
await updateDoc(doc(db, 'prayers', editingPrayer.id), prayerData);
|
||||
|
||||
// Add to local state with Firestore ID
|
||||
const newPrayer: Prayer = {
|
||||
id: docRef.id,
|
||||
...newPrayerData,
|
||||
};
|
||||
setPrayers(prev => [...prev, newPrayer]);
|
||||
// Update local state
|
||||
setPrayers(prev => prev.map(p =>
|
||||
p.id === editingPrayer.id ? { ...p, ...prayerData } : p
|
||||
));
|
||||
|
||||
// Store user reminder preferences in Firestore
|
||||
if (form.reminderFrequency !== 'never') {
|
||||
await setDoc(doc(db, 'users', user.uid), {
|
||||
email: form.email,
|
||||
reminderFrequency: form.reminderFrequency,
|
||||
includeActiveSummary: form.includeActiveSummary,
|
||||
lastEmailSent: null,
|
||||
}, { merge: true });
|
||||
// Reset editing state
|
||||
setEditingPrayer(null);
|
||||
} else {
|
||||
// Add new prayer
|
||||
const docRef = await addDoc(collection(db, 'prayers'), prayerData);
|
||||
|
||||
console.log('✅ Reminder preferences saved');
|
||||
}
|
||||
// Add to local state with Firestore ID
|
||||
const newPrayer: Prayer = {
|
||||
id: docRef.id,
|
||||
...prayerData,
|
||||
};
|
||||
setPrayers(prev => [...prev, newPrayer]);
|
||||
|
||||
// Send immediate email using EmailJS if reminder frequency is set
|
||||
if (form.reminderFrequency !== 'never' && form.email) {
|
||||
try {
|
||||
// EmailJS configuration - you'll need to set these up at emailjs.com
|
||||
const serviceId = process.env.NEXT_PUBLIC_EMAILJS_SERVICE_ID || 'your_service_id';
|
||||
const templateId = process.env.NEXT_PUBLIC_EMAILJS_TEMPLATE_ID || 'your_template_id';
|
||||
const publicKey = process.env.NEXT_PUBLIC_EMAILJS_PUBLIC_KEY || 'your_public_key';
|
||||
// Store user reminder preferences in Firestore
|
||||
if (form.reminderFrequency !== 'never') {
|
||||
await setDoc(doc(db, 'users', user.uid), {
|
||||
email: form.email,
|
||||
reminderFrequency: form.reminderFrequency,
|
||||
includeActiveSummary: form.includeActiveSummary,
|
||||
lastEmailSent: null,
|
||||
}, { merge: true });
|
||||
|
||||
const templateParams = {
|
||||
to_email: form.email,
|
||||
from_name: 'Prayer App',
|
||||
to_name: user.displayName || user.email?.split('@')[0] || 'Prayer User',
|
||||
subject: `New ${form.type} added - ${form.reminderFrequency} reminders enabled`,
|
||||
message: `Date: ${form.date}\n\n${form.text}\n\nJournal: ${form.journal || 'None'}${form.prayFor ? `\n\nPraying for: ${form.prayFor}` : ''}`,
|
||||
prayer_type: form.type,
|
||||
prayer_date: form.date,
|
||||
prayer_text: form.text,
|
||||
prayer_journal: form.journal || 'None',
|
||||
praying_for: form.prayFor || 'Not specified',
|
||||
reminder_frequency: form.reminderFrequency,
|
||||
};
|
||||
console.log('✅ Reminder preferences saved');
|
||||
}
|
||||
|
||||
// Only send if EmailJS is properly configured
|
||||
if (serviceId !== 'your_service_id' && templateId !== 'your_template_id' && publicKey !== 'your_public_key') {
|
||||
await emailjs.send(serviceId, templateId, templateParams, publicKey);
|
||||
console.log('✅ Email sent via EmailJS');
|
||||
} else {
|
||||
console.log('ℹ️ EmailJS not configured - email sending skipped (this is normal)');
|
||||
// Send immediate email using EmailJS if reminder frequency is set
|
||||
if (form.reminderFrequency !== 'never' && form.email) {
|
||||
try {
|
||||
// EmailJS configuration - you'll need to set these up at emailjs.com
|
||||
const serviceId = process.env.NEXT_PUBLIC_EMAILJS_SERVICE_ID || 'your_service_id';
|
||||
const templateId = process.env.NEXT_PUBLIC_EMAILJS_TEMPLATE_ID || 'your_template_id';
|
||||
const publicKey = process.env.NEXT_PUBLIC_EMAILJS_PUBLIC_KEY || 'your_public_key';
|
||||
|
||||
const templateParams = {
|
||||
to_email: form.email,
|
||||
from_name: 'Prayer App',
|
||||
to_name: user.displayName || user.email?.split('@')[0] || 'Prayer User',
|
||||
subject: `New ${form.type} added - ${form.reminderFrequency} reminders enabled`,
|
||||
message: `Date: ${form.date}\n\n${form.text}\n\nJournal: ${form.journal || 'None'}${form.prayFor ? `\n\nPraying for: ${form.prayFor}` : ''}`,
|
||||
prayer_type: form.type,
|
||||
prayer_date: form.date,
|
||||
prayer_text: form.text,
|
||||
prayer_journal: form.journal || 'None',
|
||||
praying_for: form.prayFor || 'Not specified',
|
||||
reminder_frequency: form.reminderFrequency,
|
||||
};
|
||||
|
||||
// Only send if EmailJS is properly configured
|
||||
if (serviceId !== 'your_service_id' && templateId !== 'your_template_id' && publicKey !== 'your_public_key') {
|
||||
await emailjs.send(serviceId, templateId, templateParams, publicKey);
|
||||
console.log('✅ Email sent via EmailJS');
|
||||
} else {
|
||||
console.log('ℹ️ EmailJS not configured - email sending skipped (this is normal)');
|
||||
}
|
||||
} catch (emailError) {
|
||||
console.error('❌ EmailJS error:', emailError);
|
||||
// Don't fail the prayer submission if email fails
|
||||
}
|
||||
} catch (emailError) {
|
||||
console.error('❌ EmailJS error:', emailError);
|
||||
// Don't fail the prayer submission if email fails
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +422,37 @@ export default function Home() {
|
||||
}
|
||||
};
|
||||
|
||||
// Start editing a prayer
|
||||
const startEditing = (prayer: Prayer) => {
|
||||
setEditingPrayer(prayer);
|
||||
setForm({
|
||||
date: prayer.date,
|
||||
type: prayer.type,
|
||||
text: prayer.text,
|
||||
journal: prayer.journal || '',
|
||||
email: prayer.email,
|
||||
prayFor: prayer.prayFor || '',
|
||||
reminderFrequency: prayer.reminderFrequency || 'never',
|
||||
includeActiveSummary: prayer.includeActiveSummary || false,
|
||||
});
|
||||
setActiveTab('add'); // Switch to add tab to show form
|
||||
};
|
||||
|
||||
// Cancel editing
|
||||
const cancelEditing = () => {
|
||||
setEditingPrayer(null);
|
||||
setForm({
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
type: 'prayer',
|
||||
text: '',
|
||||
journal: '',
|
||||
email: user?.email || '',
|
||||
prayFor: '',
|
||||
reminderFrequency: 'never',
|
||||
includeActiveSummary: false,
|
||||
});
|
||||
};
|
||||
|
||||
if (loading || showLoadingScreen) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-gray-900 via-black to-gray-800 flex items-center justify-center p-4">
|
||||
@@ -469,7 +514,8 @@ export default function Home() {
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">Prayer App</h1>
|
||||
<p className="text-gray-400 text-sm mt-1">
|
||||
{activeTab === 'add' ? 'Add New Prayer or Praise' :
|
||||
{editingPrayer ? 'Edit Prayer or Praise' :
|
||||
activeTab === 'add' ? 'Add New Prayer or Praise' :
|
||||
activeTab === 'search' ? 'Search Results' :
|
||||
`${activeTab.charAt(0).toUpperCase() + activeTab.slice(1)} Prayers`}
|
||||
</p>
|
||||
@@ -623,8 +669,17 @@ export default function Home() {
|
||||
</div>
|
||||
|
||||
<button type="submit" className="w-full p-4 bg-blue-600 hover:bg-blue-700 rounded text-lg font-semibold mt-6">
|
||||
Add Entry
|
||||
{editingPrayer ? 'Update Entry' : 'Add Entry'}
|
||||
</button>
|
||||
{editingPrayer && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={cancelEditing}
|
||||
className="w-full p-4 bg-gray-600 hover:bg-gray-700 rounded text-lg font-semibold mt-2"
|
||||
>
|
||||
Cancel Editing
|
||||
</button>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
|
||||
@@ -681,6 +736,13 @@ export default function Home() {
|
||||
>
|
||||
🌍 Community
|
||||
</button>
|
||||
<button
|
||||
onClick={() => startEditing(prayer)}
|
||||
className="px-3 py-2 bg-yellow-600 hover:bg-yellow-700 text-white text-sm font-medium rounded-lg flex items-center gap-2 transition-all duration-200 shadow-md hover:shadow-lg"
|
||||
title="Edit this prayer"
|
||||
>
|
||||
✏️ Edit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mb-2">{prayer.text}</p>
|
||||
|
||||
Reference in new issue
Block a user