Files
prayer-app/src/components/AboutPage.tsx
T

325 lines
16 KiB
TypeScript

'use client';
import React, { useState } from 'react';
import { useAuth } from '@/context/AuthContext';
interface AboutPageProps {
userEmail?: string;
}
export default function AboutPage({ userEmail }: AboutPageProps) {
const { logout, deleteAccount, sendVerificationEmail, user } = useAuth();
const [showLogoutConfirm, setShowLogoutConfirm] = useState(false);
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [deleteStep, setDeleteStep] = useState(0); // 0=initial, 1=first confirm, 2=second confirm, 3=type DELETE, 4=type email
const [deleteConfirmText, setDeleteConfirmText] = useState('');
const [deleteEmail, setDeleteEmail] = useState('');
const [deleteLoading, setDeleteLoading] = useState(false);
const [deleteError, setDeleteError] = useState('');
const [verificationMessage, setVerificationMessage] = useState('');
const [sendingVerification, setSendingVerification] = useState(false);
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 to-slate-800 p-4 pb-32 pt-8">
<div className="max-w-md mx-auto">
{/* Header */}
<div className="text-center mb-8">
<h1 className="text-4xl font-bold text-white mb-2">About</h1>
<p className="text-slate-400">Haver - Your Prayer Companion</p>
</div>
{/* About Card */}
<div className="bg-slate-800 rounded-lg shadow-sm p-4 space-y-6">
{/* Haver Meaning Section */}
<div className="border-b border-slate-700 pb-6">
<h2 className="text-lg font-semibold text-white mb-4">Haver חבר</h2>
<div className="space-y-3 text-sm text-slate-300">
<p>
<span className="font-semibold text-blue-400">Haver</span> is a Hebrew word (חבר) meaning
<span className="italic"> "friend," "companion," or "associate."</span>
</p>
<p>
Pronounced: <span className="font-mono text-slate-400">ha-VER</span> (stress on the second syllable)
</p>
<p className="text-slate-400">
In Jewish culture, Haver represents the importance of building bonds and connections among peers.
It reflects shared experiences and support within a community.
</p>
<p className="text-slate-400">
This app is your spiritual companion—a friend on your prayer journey,
helping you connect with God and track your faith walk.
</p>
</div>
</div>
{/* Account Section */}
<div className="border-b border-slate-700 pb-6">
<h2 className="text-lg font-semibold text-white mb-4">Account</h2>
<div className="space-y-3">
<div>
<p className="text-sm font-medium text-slate-400">Email</p>
<p className="text-white">{userEmail || 'Not set'}</p>
</div>
<div>
<p className="text-sm font-medium text-slate-400 mb-2">Verification Status</p>
{user?.emailVerified ? (
<div className="flex items-center gap-2 text-green-400">
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
<span className="text-sm">Verified</span>
</div>
) : (
<div className="space-y-2">
<div className="flex items-center gap-2 text-yellow-400">
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
<span className="text-sm">Not verified</span>
</div>
{verificationMessage && (
<div className={`px-3 py-2 rounded-lg text-sm ${
verificationMessage.includes('sent')
? 'bg-green-900 border border-green-700 text-green-200'
: 'bg-red-900 border border-red-700 text-red-200'
}`}>
{verificationMessage}
</div>
)}
<button
onClick={async () => {
setSendingVerification(true);
setVerificationMessage('');
try {
await sendVerificationEmail();
setVerificationMessage('✓ Verification email sent! Check your inbox.');
} catch (err: unknown) {
setVerificationMessage(err instanceof Error ? err.message : 'Failed to send email');
}
setSendingVerification(false);
}}
disabled={sendingVerification}
className="w-full px-3 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-blue-800 disabled:cursor-not-allowed text-white text-sm font-medium rounded-lg transition-colors"
>
{sendingVerification ? 'Sending...' : 'Resend Verification Email'}
</button>
</div>
)}
</div>
</div>
</div>
{/* App Info Section */}
<div className="border-b border-slate-700 pb-6">
<h2 className="text-lg font-semibold text-white mb-4">App Info</h2>
<div className="space-y-2 text-sm text-slate-400">
<p>Haver v1.0</p>
<p>A simple, private space for your daily prayers and reflections.</p>
</div>
</div>
{/* Logout and Delete Section */}
<div className="space-y-3">
<button
onClick={() => setShowLogoutConfirm(true)}
className="w-full px-4 py-3 bg-red-600 hover:bg-red-700 text-white font-medium rounded-lg transition-colors"
>
Logout
</button>
<button
onClick={() => {
setShowDeleteDialog(true);
setDeleteStep(0);
setDeleteConfirmText('');
setDeleteEmail('');
setDeleteError('');
}}
className="w-full px-4 py-3 bg-red-900 hover:bg-red-800 text-red-200 font-medium rounded-lg transition-colors border border-red-700"
>
Delete Account
</button>
</div>
</div>
{/* Logout Confirmation Modal */}
{showLogoutConfirm && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-slate-800 rounded-xl p-6 max-w-sm w-full">
<h2 className="text-xl font-bold text-white mb-2">Logout?</h2>
<p className="text-slate-400 mb-6">Are you sure you want to logout?</p>
<div className="flex gap-3">
<button
onClick={() => setShowLogoutConfirm(false)}
className="flex-1 px-4 py-2 rounded-lg bg-slate-700 text-white font-medium hover:bg-slate-600 transition-colors"
>
Cancel
</button>
<button
onClick={() => logout()}
className="flex-1 px-4 py-2 rounded-lg bg-red-600 text-white font-medium hover:bg-red-700 transition-colors"
>
Logout
</button>
</div>
</div>
</div>
)}
{/* Delete Account Multi-Step Modal */}
{showDeleteDialog && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-slate-800 rounded-xl p-6 max-w-sm w-full">
{deleteStep === 0 && (
<>
<h2 className="text-xl font-bold text-red-400 mb-2">⚠️ Delete Account?</h2>
<p className="text-slate-300 mb-2 font-semibold">This action cannot be undone.</p>
<p className="text-slate-400 mb-6 text-sm">All your prayers, reflections, and account data will be permanently deleted.</p>
<div className="flex gap-3">
<button
onClick={() => setShowDeleteDialog(false)}
className="flex-1 px-4 py-2 rounded-lg bg-slate-700 text-white font-medium hover:bg-slate-600 transition-colors"
>
Cancel
</button>
<button
onClick={() => setDeleteStep(1)}
className="flex-1 px-4 py-2 rounded-lg bg-red-600 text-white font-medium hover:bg-red-700 transition-colors"
>
Continue
</button>
</div>
</>
)}
{deleteStep === 1 && (
<>
<h2 className="text-xl font-bold text-red-400 mb-2">Are you absolutely sure?</h2>
<p className="text-slate-400 mb-6">You will lose all your prayers and data. This is permanent.</p>
<div className="flex gap-3">
<button
onClick={() => setDeleteStep(0)}
className="flex-1 px-4 py-2 rounded-lg bg-slate-700 text-white font-medium hover:bg-slate-600 transition-colors"
>
Cancel
</button>
<button
onClick={() => setDeleteStep(2)}
className="flex-1 px-4 py-2 rounded-lg bg-red-600 text-white font-medium hover:bg-red-700 transition-colors"
>
I'm Sure
</button>
</div>
</>
)}
{deleteStep === 2 && (
<>
<h2 className="text-xl font-bold text-red-400 mb-2">Type DELETE to confirm</h2>
<p className="text-slate-400 mb-4">Enter the word "DELETE" to proceed:</p>
<input
type="text"
value={deleteConfirmText}
onChange={(e) => setDeleteConfirmText(e.target.value.toUpperCase())}
placeholder="Type DELETE"
className="w-full p-2 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-500 mb-4 focus:ring-2 focus:ring-red-500 focus:border-transparent"
/>
<div className="flex gap-3">
<button
onClick={() => setDeleteStep(1)}
className="flex-1 px-4 py-2 rounded-lg bg-slate-700 text-white font-medium hover:bg-slate-600 transition-colors"
>
Back
</button>
<button
onClick={() => deleteConfirmText === 'DELETE' ? setDeleteStep(3) : setDeleteError('Please type DELETE exactly')}
disabled={deleteConfirmText !== 'DELETE'}
className="flex-1 px-4 py-2 rounded-lg bg-red-600 text-white font-medium hover:bg-red-700 disabled:bg-red-900 disabled:cursor-not-allowed transition-colors"
>
Continue
</button>
</div>
{deleteError && <p className="text-red-400 text-sm mt-2">{deleteError}</p>}
</>
)}
{deleteStep === 3 && (
<>
<h2 className="text-xl font-bold text-red-400 mb-2">Confirm your email</h2>
<p className="text-slate-400 mb-4">Enter your email to verify:</p>
<input
type="email"
value={deleteEmail}
onChange={(e) => setDeleteEmail(e.target.value)}
placeholder="Enter your email"
className="w-full p-2 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-500 mb-4 focus:ring-2 focus:ring-red-500 focus:border-transparent"
/>
<div className="flex gap-3">
<button
onClick={() => setDeleteStep(2)}
className="flex-1 px-4 py-2 rounded-lg bg-slate-700 text-white font-medium hover:bg-slate-600 transition-colors"
>
Back
</button>
<button
onClick={() => deleteEmail === userEmail ? setDeleteStep(4) : setDeleteError('Email does not match')}
disabled={!deleteEmail}
className="flex-1 px-4 py-2 rounded-lg bg-red-600 text-white font-medium hover:bg-red-700 disabled:bg-red-900 disabled:cursor-not-allowed transition-colors"
>
Continue
</button>
</div>
{deleteError && <p className="text-red-400 text-sm mt-2">{deleteError}</p>}
</>
)}
{deleteStep === 4 && (
<>
<h2 className="text-xl font-bold text-red-400 mb-2">Final confirmation</h2>
<p className="text-slate-400 mb-4">Check this box to confirm you understand your account will be permanently deleted:</p>
<div className="bg-slate-700 p-3 rounded-lg mb-4">
<label className="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
checked={deleteConfirmText === 'CONFIRM'}
onChange={(e) => setDeleteConfirmText(e.target.checked ? 'CONFIRM' : '')}
className="w-5 h-5 rounded border-slate-600 bg-slate-600 text-red-600 focus:ring-2 focus:ring-red-500 cursor-pointer"
/>
<span className="text-slate-300 text-sm">
I understand this is permanent and cannot be undone
</span>
</label>
</div>
<div className="flex gap-3">
<button
onClick={() => setDeleteStep(3)}
className="flex-1 px-4 py-2 rounded-lg bg-slate-700 text-white font-medium hover:bg-slate-600 transition-colors"
>
Back
</button>
<button
onClick={async () => {
setDeleteLoading(true);
setDeleteError('');
try {
await deleteAccount();
} catch (err: unknown) {
setDeleteError(err instanceof Error ? err.message : 'Failed to delete account');
setDeleteLoading(false);
}
}}
disabled={deleteConfirmText !== 'CONFIRM' || deleteLoading}
className="flex-1 px-4 py-2 rounded-lg bg-red-700 text-white font-bold hover:bg-red-800 disabled:bg-red-900 disabled:cursor-not-allowed transition-colors"
>
{deleteLoading ? 'Deleting...' : 'Delete Account'}
</button>
</div>
{deleteError && <p className="text-red-400 text-sm mt-2">{deleteError}</p>}
</>
)}
</div>
</div>
)}
</div>
</div>
);
}