Add email prompt when users without email register for events

This commit is contained in:
2025-11-20 19:24:27 +00:00
parent 57b7cd2308
commit 4baa2892b9
4 changed files with 156 additions and 1 deletions

View File

@@ -0,0 +1,57 @@
interface EmailPromptModalProps {
onClose: () => void;
onAddEmail: () => void;
onContinue: () => void;
}
export function EmailPromptModal({ onClose, onAddEmail, onContinue }: EmailPromptModalProps) {
return (
<div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
{/* Background overlay */}
<div className="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onClick={onClose}></div>
{/* Modal panel */}
<div className="relative inline-block align-bottom bg-white rounded-lg text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-md sm:w-full z-10">
<div className="bg-white px-6 pt-6 pb-4">
{/* Icon */}
<div className="flex items-center justify-center w-12 h-12 mx-auto bg-amber-100 rounded-full mb-4">
<svg className="w-6 h-6 text-amber-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</div>
{/* Content */}
<div className="text-center">
<h3 className="text-lg font-semibold text-gray-900 mb-2">
Add an Email Address?
</h3>
<p className="text-sm text-gray-600 mb-4">
You don't have an email address registered. Adding one will allow you to receive notifications about event changes or cancellations.
</p>
<p className="text-xs text-gray-500">
You'll be directed to your profile page where you can manage your account settings.
</p>
</div>
</div>
{/* Actions */}
<div className="bg-gray-50 px-6 py-4 space-y-2">
<button
onClick={onAddEmail}
className="w-full bg-blue-600 text-white py-2.5 px-4 rounded-lg hover:bg-blue-700 transition-colors font-medium"
>
Add Email Address
</button>
<button
onClick={onContinue}
className="w-full bg-white text-gray-700 py-2.5 px-4 rounded-lg border border-gray-300 hover:bg-gray-50 transition-colors font-medium"
>
Continue Without Email
</button>
</div>
</div>
</div>
</div>
);
}

View File

@@ -6,4 +6,5 @@ export { EventDetailModal } from './EventDetailModal';
export { EventCompletionForm } from './EventCompletionForm';
export { AttendeeManagement } from './AttendeeManagement';
export { CompletedEventDetails } from './CompletedEventDetails';
export { EmailPromptModal } from './EmailPromptModal';
export type { EventFilterState } from './EventFilters';

View File

@@ -1,12 +1,14 @@
import { useState, useEffect } from 'react';
import { useUser } from '@clerk/clerk-react';
import { EventForm, EventList, EventFilters, EventDetailModal } from '@/components/event';
import { useNavigate } from 'react-router-dom';
import { EventForm, EventList, EventFilters, EventDetailModal, EmailPromptModal } from '@/components/event';
import type { EventFilterState } from '@/components/event';
import { eventService } from '@/services/eventService';
import type { CleanupEvent } from '@/types';
export function EventsPage() {
const { isSignedIn, user } = useUser();
const navigate = useNavigate();
const [events, setEvents] = useState<CleanupEvent[]>([]);
const [filteredEvents, setFilteredEvents] = useState<CleanupEvent[]>([]);
const [filters, setFilters] = useState<EventFilterState>({
@@ -19,6 +21,8 @@ export function EventsPage() {
const [isLoading, setIsLoading] = useState(true);
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const [showEmailPrompt, setShowEmailPrompt] = useState(false);
const [pendingEventId, setPendingEventId] = useState<string | null>(null);
// Load events
useEffect(() => {
@@ -148,6 +152,18 @@ export function EventsPage() {
return;
}
// Check if user has an email address
const hasEmail = user?.primaryEmailAddress?.emailAddress;
if (!hasEmail) {
setPendingEventId(eventId);
setShowEmailPrompt(true);
return;
}
await performRegistration(eventId);
};
const performRegistration = async (eventId: string) => {
try {
setIsSubmitting(true);
setError(null);
@@ -162,6 +178,22 @@ export function EventsPage() {
}
};
const handleAddEmail = () => {
setShowEmailPrompt(false);
// Navigate to user profile where they can manage their Clerk account
if (user?.id) {
navigate(`/profile/${user.id}`);
}
};
const handleContinueWithoutEmail = async () => {
setShowEmailPrompt(false);
if (pendingEventId) {
await performRegistration(pendingEventId);
setPendingEventId(null);
}
};
const handleUnregister = async () => {
if (!selectedEvent) return;
@@ -323,6 +355,18 @@ export function EventsPage() {
isLoading={isSubmitting}
/>
)}
{/* Email Prompt Modal */}
{showEmailPrompt && (
<EmailPromptModal
onClose={() => {
setShowEmailPrompt(false);
setPendingEventId(null);
}}
onAddEmail={handleAddEmail}
onContinue={handleContinueWithoutEmail}
/>
)}
</div>
);
}