From 74686cece1c46b270229a3c68644e8aae134751d Mon Sep 17 00:00:00 2001 From: nmemmert Date: Mon, 19 Jan 2026 09:05:31 -0500 Subject: [PATCH] chore: remove legacy routes and email APIs --- src/app/admin/page.tsx | 33 -- src/app/api/debug-smtp/route.ts | 29 -- src/app/api/send-email/route.ts | 325 --------------- src/app/api/send-scheduled-emails/route.ts | 457 --------------------- src/app/profile/page.tsx | 31 -- src/app/testimonies/page.tsx | 160 -------- 6 files changed, 1035 deletions(-) delete mode 100644 src/app/admin/page.tsx delete mode 100644 src/app/api/debug-smtp/route.ts delete mode 100644 src/app/api/send-email/route.ts delete mode 100644 src/app/api/send-scheduled-emails/route.ts delete mode 100644 src/app/profile/page.tsx delete mode 100644 src/app/testimonies/page.tsx diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx deleted file mode 100644 index 577c32b..0000000 --- a/src/app/admin/page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -'use client'; - -import { useAuth } from '@/context/AuthContext'; -import Admin from '@/components/Admin'; -import Navbar from '@/components/Navbar'; -import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; - -export default function AdminPage() { - const { user, isAdmin } = useAuth(); - const router = useRouter(); - - useEffect(() => { - if (!user) { - router.push('/'); - } else if (!isAdmin) { - router.push('/'); - } - }, [user, isAdmin, router]); - - if (!user || !isAdmin) { - return null; - } - - return ( -
- -
- -
-
- ); -} \ No newline at end of file diff --git a/src/app/api/debug-smtp/route.ts b/src/app/api/debug-smtp/route.ts deleted file mode 100644 index 7d9393b..0000000 --- a/src/app/api/debug-smtp/route.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Debug API endpoint to check SMTP config server-side -// This will work even without client authentication - -import { db } from '@/lib/firebase'; -import { doc, getDoc } from 'firebase/firestore'; - -export async function GET() { - try { - const configDoc = await getDoc(doc(db, 'config', 'smtp')); - - if (configDoc.exists()) { - const config = configDoc.data(); - return Response.json({ - found: true, - host: config?.host, - port: config?.port, - secure: config?.secure, - user: config?.user ? 'SET' : 'MISSING', - pass: config?.pass ? 'SET' : 'MISSING', - from: config?.from, - hasAllFields: !!(config?.host && config?.port && config?.user && config?.pass && config?.from) - }); - } else { - return Response.json({ found: false, error: 'SMTP config not found' }); - } - } catch (error: any) { - return Response.json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src/app/api/send-email/route.ts b/src/app/api/send-email/route.ts deleted file mode 100644 index b184274..0000000 --- a/src/app/api/send-email/route.ts +++ /dev/null @@ -1,325 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server'; -import { doc, getDoc } from 'firebase/firestore'; -import { db } from '@/lib/firebase'; -import nodemailer from 'nodemailer'; - -function generatePrayerEmailHTML(message: string, subject: string) { - // Parse the message to extract prayer details - const lines = message.split('\n'); - let currentPrayer = null; - const prayers = []; - let summarySection = false; - - for (const line of lines) { - if (line.includes('New prayer added') || line.includes('New praise added')) { - currentPrayer = { type: '', date: '', text: '', journal: '', prayFor: '' }; - } else if (line.startsWith('Date: ')) { - if (currentPrayer) currentPrayer.date = line.replace('Date: ', ''); - } else if (line.startsWith('Praying for: ')) { - if (currentPrayer) currentPrayer.prayFor = line.replace('Praying for: ', ''); - } else if (line.startsWith('Journal: ')) { - if (currentPrayer) currentPrayer.journal = line.replace('Journal: ', ''); - } else if (line.includes('--- Active Prayers Summary ---')) { - summarySection = true; - prayers.push({ type: 'summary-header', text: 'Active Prayers Summary' }); - } else if (summarySection && line.includes(' - ')) { - // Parse summary lines like "2025-01-15 - PRAYER: prayer text" - const match = line.match(/(\d{4}-\d{2}-\d{2}) - (PRAYER|PRAISE): (.+)/); - if (match) { - prayers.push({ - type: 'summary-item', - date: match[1], - prayerType: match[2].toLowerCase(), - text: match[3] - }); - } - } else if (currentPrayer && !currentPrayer.text && line.trim()) { - currentPrayer.text = line; - prayers.push(currentPrayer); - currentPrayer = null; - } - } - - const html = ` - - - - - - ${subject} - - - -
-
-

🙏 Prayer App

-
${subject}
-
- -
- ${prayers.map(prayer => { - if (prayer.type === 'summary-header') { - return ` -
-

📚 ${prayer.text}

-

Here are all your active prayers and praises:

-
- `; - } else if (prayer.type === 'summary-item') { - return ` -
-
${prayer.date ? new Date(prayer.date).toLocaleDateString() : 'Unknown Date'}
-
${prayer.prayerType}
-
${prayer.text}
-
- `; - } else { - return ` -
-
${prayer.type}
-
${prayer.date ? new Date(prayer.date).toLocaleDateString() : 'Unknown Date'}
-
${prayer.text}
- ${prayer.prayFor ? `
🙋 Praying for: ${prayer.prayFor}
` : ''} - ${prayer.journal && prayer.journal !== 'None' ? `
📝 Journal: ${prayer.journal}
` : ''} -
- `; - } - }).join('')} - -
-
"Pray without ceasing"
- — 1 Thessalonians 5:17 -
-
- - -
- -`; - - return html; -} - -export async function POST(request: NextRequest) { - try { - const { email, subject, message } = await request.json(); - - console.log('📧 Attempting to send email to:', email); - - // Get SMTP config from Firestore - console.log('📧 Fetching SMTP config from Firestore...'); - const configDoc = await getDoc(doc(db, 'config', 'smtp')); - - if (!configDoc.exists()) { - console.error('❌ SMTP configuration not found in Firestore'); - return NextResponse.json({ - error: 'SMTP configuration not found', - details: 'Please configure SMTP settings in the Admin panel at /admin' - }, { status: 500 }); - } - - const smtpConfig = configDoc.data(); - console.log('✅ SMTP config found, host:', smtpConfig?.host); - - // Validate SMTP config - if (!smtpConfig?.host || !smtpConfig?.user || !smtpConfig?.pass || !smtpConfig?.from) { - console.error('❌ SMTP config incomplete:', { - hasHost: !!smtpConfig?.host, - hasUser: !!smtpConfig?.user, - hasPass: !!smtpConfig?.pass, - hasFrom: !!smtpConfig?.from - }); - return NextResponse.json({ - error: 'SMTP configuration incomplete', - details: 'Missing required SMTP fields. Please check Admin panel.' - }, { status: 500 }); - } - - console.log('📧 Creating email transporter...'); - - // Create transporter with dynamic config - const transporter = nodemailer.createTransport({ - host: smtpConfig.host, - port: smtpConfig.port, - secure: smtpConfig.secure, - auth: { - user: smtpConfig.user, - pass: smtpConfig.pass, - }, - }); - - console.log('📧 Sending email...'); - - // Send email - const result = await transporter.sendMail({ - from: smtpConfig.from, - to: email, - subject, - text: message, - html: generatePrayerEmailHTML(message, subject), - }); - - console.log('✅ Email sent successfully:', result.messageId); - return NextResponse.json({ success: true, messageId: result.messageId }); - - } catch (error: any) { - console.error('❌ Email send error:', error); - - // Provide more specific error messages - if (error.code === 'ECONNREFUSED') { - return NextResponse.json({ - error: 'SMTP connection failed', - details: 'Cannot connect to SMTP server. Check host and port.' - }, { status: 500 }); - } - - if (error.code === 'EAUTH') { - return NextResponse.json({ - error: 'SMTP authentication failed', - details: 'Invalid username or password. For Gmail, use App Password.' - }, { status: 500 }); - } - - if (error.code === 'ESOCKET') { - return NextResponse.json({ - error: 'SMTP socket error', - details: 'Network or firewall issue. Check internet connection.' - }, { status: 500 }); - } - - return NextResponse.json({ - error: 'Failed to send email', - details: error.message || 'Unknown error occurred' - }, { status: 500 }); - } -} \ No newline at end of file diff --git a/src/app/api/send-scheduled-emails/route.ts b/src/app/api/send-scheduled-emails/route.ts deleted file mode 100644 index c077a61..0000000 --- a/src/app/api/send-scheduled-emails/route.ts +++ /dev/null @@ -1,457 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server'; -import nodemailer from 'nodemailer'; - -function generatePrayerEmailHTML(message: string, subject: string) { - // Parse the message to extract prayer details and stats - const lines = message.split('\n'); - const stats = { total: 0, active: 0, answered: 0, archived: 0 }; - const activePrayers = []; - const answeredPrayers = []; - let inActiveSection = false; - let inAnsweredSection = false; - - for (const line of lines) { - if (line.includes('Total Prayers:')) { - stats.total = parseInt(line.split(':')[1].trim()) || 0; - } else if (line.includes('Active Prayers:')) { - stats.active = parseInt(line.split(':')[1].trim()) || 0; - } else if (line.includes('Answered Prayers:')) { - stats.answered = parseInt(line.split(':')[1].trim()) || 0; - } else if (line.includes('Archived Prayers:')) { - stats.archived = parseInt(line.split(':')[1].trim()) || 0; - } else if (line.includes('--- Your Active Prayers ---')) { - inActiveSection = true; - inAnsweredSection = false; - } else if (line.includes('--- Recently Answered Prayers ---')) { - inActiveSection = false; - inAnsweredSection = true; - } else if (inActiveSection && line.includes(' - ')) { - const match = line.match(/(\d{4}-\d{2}-\d{2}) - (PRAYER|PRAISE): (.+)/); - if (match) { - activePrayers.push({ - date: match[1], - type: match[2].toLowerCase(), - text: match[3] - }); - } - } else if (inAnsweredSection && line.includes(' - ')) { - const match = line.match(/(\d{4}-\d{2}-\d{2}) - (PRAYER|PRAISE): (.+)/); - if (match) { - answeredPrayers.push({ - date: match[1], - type: match[2].toLowerCase(), - text: match[3] - }); - } - } - } - - const html = ` - - - - - - ${subject} - - - -
-
-

🙏 Prayer App

-
${subject}
-
- -
- -
-
-
${stats.total}
-
Total Prayers
-
-
-
${stats.active}
-
Active
-
-
-
${stats.answered}
-
Answered
-
-
-
${stats.archived}
-
Archived
-
-
- - ${activePrayers.length > 0 ? ` -
-

📝 Your Active Prayers

- ${activePrayers.map(prayer => ` -
-
${prayer.type}
-
${new Date(prayer.date).toLocaleDateString()}
-
${prayer.text}
-
- `).join('')} -
- ` : ` -
-

🎉 All Caught Up!

-

You have no active prayers. Great job staying on top of your prayer life!

-
- `} - - ${answeredPrayers.length > 0 ? ` -
-

🙏 Recently Answered Prayers

- ${answeredPrayers.map(prayer => ` -
-
${prayer.type}
-
${new Date(prayer.date).toLocaleDateString()}
-
${prayer.text}
-
- `).join('')} -
- ` : ''} -
- -
-
"Pray without ceasing"
- — 1 Thessalonians 5:17 -
-
- - - - -`; - return html; -} - -export async function GET() { - try { - // Dynamically import Firebase admin to avoid build-time initialization issues - const { admin } = await import('@/lib/firebase-admin'); - - console.log('🔄 Checking for scheduled emails...'); - - const configDoc = await admin.firestore().collection('config').doc('smtp').get(); - if (!configDoc.exists) { - console.log('❌ SMTP configuration not found'); - return NextResponse.json({ message: 'SMTP configuration not found' }, { status: 500 }); - } - - const smtpConfig = configDoc.data(); - if (!smtpConfig) { - console.log('❌ SMTP configuration data is empty'); - return NextResponse.json({ message: 'SMTP configuration data is empty' }, { status: 500 }); - } - - // Create transporter - const transporter = nodemailer.createTransport({ - host: smtpConfig.host, - port: smtpConfig.port, - secure: smtpConfig.secure, - auth: { - user: smtpConfig.user, - pass: smtpConfig.pass, - }, - }); - - // Get all users (send daily emails to everyone) using Firebase Admin SDK - const usersSnapshot = await admin.firestore().collection('users').get(); - - let emailsSent = 0; - - for (const userDoc of usersSnapshot.docs) { - const userData = userDoc.data(); - const userId = userDoc.id; - - // Skip users without email - if (!userData.email) { - continue; - } - - // Check last email sent time - send daily - const lastEmailSent = userData.lastEmailSent ? new Date(userData.lastEmailSent.toDate()) : new Date(0); - const now = new Date(); - - // Send if more than 24 hours have passed - const shouldSendEmail = (now.getTime() - lastEmailSent.getTime()) > (24 * 60 * 60 * 1000); - - if (!shouldSendEmail) { - continue; - } - - // Get user's prayers for stats using Firebase Admin SDK - const prayersSnapshot = await admin.firestore().collection('prayers').where('userId', '==', userId).get(); - const userPrayers = prayersSnapshot.docs.map(doc => doc.data()); - - // Calculate stats - const activePrayers = userPrayers.filter(p => !p.archived); - const archivedPrayers = userPrayers.filter(p => p.archived); - const answeredPrayers = userPrayers.filter(p => p.answered); - const totalPrayers = userPrayers.length; - - // Build email content with stats - let message = `--- Daily Prayer Summary ---\n\n`; - message += `📊 Your Prayer Statistics:\n`; - message += `• Total Prayers: ${totalPrayers}\n`; - message += `• Active Prayers: ${activePrayers.length}\n`; - message += `• Answered Prayers: ${answeredPrayers.length}\n`; - message += `• Archived Prayers: ${archivedPrayers.length}\n\n`; - - if (activePrayers.length > 0) { - message += `--- Your Active Prayers ---\n`; - activePrayers.forEach(prayer => { - message += `\n${prayer.date} - ${prayer.type.toUpperCase()}: ${prayer.text}`; - if (prayer.prayFor) { - message += ` (Praying for: ${prayer.prayFor})`; - } - if (prayer.journal) { - message += `\n Journal: ${prayer.journal}`; - } - message += `\n`; - }); - } else { - message += `🎉 Great job! You have no active prayers - all caught up!\n\n`; - } - - if (answeredPrayers.length > 0) { - message += `\n--- Recently Answered Prayers ---\n`; - // Show answered prayers from the last 7 days - const recentAnswered = answeredPrayers.filter(p => { - const answeredDate = p.answeredDate ? new Date(p.answeredDate) : new Date(p.date); - const weekAgo = new Date(); - weekAgo.setDate(weekAgo.getDate() - 7); - return answeredDate >= weekAgo; - }); - - if (recentAnswered.length > 0) { - recentAnswered.forEach(prayer => { - message += `\n${prayer.date} - ${prayer.type.toUpperCase()}: ${prayer.text}`; - if (prayer.answeredDate) { - message += ` (Answered: ${new Date(prayer.answeredDate).toLocaleDateString()})`; - } - message += `\n`; - }); - } - } - - const subject = `Daily Prayer Summary - ${activePrayers.length} active prayers`; - - try { - // Send email - await transporter.sendMail({ - from: smtpConfig.from, - to: userData.email, - subject, - text: message, - html: generatePrayerEmailHTML(message, subject), - }); - - // Update last email sent time using Firebase Admin SDK - await admin.firestore().collection('users').doc(userId).update({ - lastEmailSent: new Date(), - }); - - emailsSent++; - console.log(`✅ Sent daily summary email to ${userData.email}`); - - } catch (emailError) { - console.error(`❌ Failed to send email to ${userData.email}:`, emailError); - } - } - - console.log(`📧 Daily email summary complete. Sent ${emailsSent} emails.`); - return NextResponse.json({ - message: `Daily email summary complete. Sent ${emailsSent} emails.`, - emailsSent - }); - - } catch (error) { - console.error('❌ Scheduled email error:', error); - console.error('❌ Error details:', { - message: error instanceof Error ? error.message : 'Unknown error', - stack: error instanceof Error ? error.stack : undefined, - name: error instanceof Error ? error.name : 'Unknown' - }); - return NextResponse.json({ - error: 'Failed to process scheduled emails', - details: error instanceof Error ? error.message : 'Unknown error' - }, { status: 500 }); - } -} - -export async function POST() { - // POST handler calls the same logic as GET for testing purposes - return GET(); -} \ No newline at end of file diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx deleted file mode 100644 index 40e83b1..0000000 --- a/src/app/profile/page.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client'; - -import { useAuth } from '@/context/AuthContext'; -import Profile from '@/components/Profile'; -import Navbar from '@/components/Navbar'; -import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; - -export default function ProfilePage() { - const { user } = useAuth(); - const router = useRouter(); - - useEffect(() => { - if (!user) { - router.push('/'); - } - }, [user, router]); - - if (!user) { - return null; - } - - return ( -
- -
- -
-
- ); -} \ No newline at end of file diff --git a/src/app/testimonies/page.tsx b/src/app/testimonies/page.tsx deleted file mode 100644 index 3cd6d08..0000000 --- a/src/app/testimonies/page.tsx +++ /dev/null @@ -1,160 +0,0 @@ -'use client'; - -import { useState, useEffect } from 'react'; -import { collection, query, where, orderBy, getDocs } from 'firebase/firestore'; -import { db } from '@/lib/firebase'; -import Navbar from '@/components/Navbar'; - -interface Testimony { - id: string; - text: string; - userId: string; - answeredDate: string; - tags?: string[]; - type: 'prayer' | 'praise'; - prayFor?: string; -} - -export default function TestimoniesPage() { - const [testimonies, setTestimonies] = useState([]); - const [loading, setLoading] = useState(true); - const [filter, setFilter] = useState<'all' | 'prayer' | 'praise'>('all'); - - useEffect(() => { - const fetchTestimonies = async () => { - try { - const q = query( - collection(db, 'prayers'), - where('answered', '==', true), - orderBy('answeredDate', 'desc') - ); - const querySnapshot = await getDocs(q); - const testimoniesData = querySnapshot.docs.map(doc => ({ - id: doc.id, - ...doc.data() - })) as Testimony[]; - setTestimonies(testimoniesData); - } catch (error) { - console.error('Error fetching testimonies:', error); - } finally { - setLoading(false); - } - }; - - fetchTestimonies(); - }, []); - - const filteredTestimonies = testimonies.filter(testimony => - filter === 'all' || testimony.type === filter - ); - - if (loading) { - return ( -
- -
-
- {[...Array(5)].map((_, i) => ( -
-
-
-
- ))} -
-
-
- ); - } - - return ( -
- -
-
-

🙏 Testimony Wall

-

Celebrating answered prayers and praises

-
- - {/* Filter Buttons */} -
- - - -
- -
- {filteredTestimonies.map((testimony) => ( -
-
-
- {testimony.type === 'prayer' ? '🙏' : '🙌'} - - Answered {testimony.type === 'prayer' ? 'Prayer' : 'Praise'} - - {testimony.prayFor && ( - for {testimony.prayFor} - )} -
- - {new Date(testimony.answeredDate).toLocaleDateString()} - -
- -

{testimony.text}

- - {testimony.tags && testimony.tags.length > 0 && ( -
- {testimony.tags.map((tag, index) => ( - - #{tag} - - ))} -
- )} -
- ))} -
- - {filteredTestimonies.length === 0 && ( -
-
🙏
-

No Testimonies Yet

-

- {filter === 'all' - ? 'Answered prayers will appear here to inspire others.' - : `No answered ${filter === 'prayer' ? 'prayers' : 'praises'} yet.` - } -

-
- )} -
-
- ); -} \ No newline at end of file