import React, { useState, useRef, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { Calendar, Mail, Lock, Clock, ArrowLeft, Palette, Eye, EyeOff } from 'lucide-react'; import { addDays } from 'date-fns'; import { toast } from 'react-toastify'; import { Button, Input, Card, PasswordGenerator } from '../../components/common'; import { ThemeCustomizerEnhanced, GalleryPreview, WelcomeMessageEditor, FeedbackSettings } from '../../components/admin'; import { useMutation, useQuery } from '@tanstack/react-query'; import { eventsService } from '../../services/events.service'; import { useLocalizedDate } from '../../hooks/useLocalizedDate'; import { categoriesService } from '../../services/categories.service'; import { settingsService } from '../../services/settings.service'; import { useTranslation } from 'react-i18next'; import { ThemeConfig, GALLERY_THEME_PRESETS } from '../../types/theme.types'; interface FormData { event_type: string; event_name: string; event_date: string; host_name: string; host_email: string; admin_email: string; require_password: boolean; password: string; confirm_password: string; welcome_message: string; theme_preset: string; theme_config: ThemeConfig; expires_in_days: number; allow_user_uploads: boolean; upload_category_id: number | null; feedback_settings: { feedback_enabled: boolean; allow_ratings: boolean; allow_likes: boolean; allow_comments: boolean; allow_favorites: boolean; require_name_email: boolean; moderate_comments: boolean; show_feedback_to_guests: boolean; enable_rate_limiting: boolean; rate_limit_window_minutes?: number; rate_limit_max_requests?: number; }; } const EVENT_TYPE_PRESETS: Record = { wedding: 'elegantWedding', birthday: 'birthdayFun', corporate: 'corporateTimeline', other: 'default' }; const EVENT_TYPES = [ { value: 'wedding', labelKey: 'events.types.wedding', emoji: '💒' }, { value: 'birthday', labelKey: 'events.types.birthday', emoji: '🎂' }, { value: 'corporate', labelKey: 'events.types.corporate', emoji: '🏢' }, { value: 'other', labelKey: 'events.types.other', emoji: '📸' }, ]; export const CreateEventPageEnhanced: React.FC = () => { const navigate = useNavigate(); const { t } = useTranslation(); const { format } = useLocalizedDate(); const isMountedRef = useRef(true); const [showThemeCustomizer, setShowThemeCustomizer] = useState(false); // const [showPreview, setShowPreview] = useState(false); useEffect(() => { return () => { isMountedRef.current = false; }; }, []); const [formData, setFormData] = useState({ event_type: 'wedding', event_name: '', event_date: new Date().toISOString().split('T')[0], // Initialize with ISO date format host_name: '', host_email: '', admin_email: '', require_password: true, password: '', confirm_password: '', welcome_message: '', theme_preset: 'elegantWedding', theme_config: GALLERY_THEME_PRESETS.elegantWedding.config, expires_in_days: 30, allow_user_uploads: false, upload_category_id: null, feedback_settings: { feedback_enabled: false, allow_ratings: true, allow_likes: true, allow_comments: true, allow_favorites: true, require_name_email: false, moderate_comments: true, show_feedback_to_guests: true, enable_rate_limiting: true, rate_limit_window_minutes: 15, rate_limit_max_requests: 10, }, }); const [errors, setErrors] = useState>>({}); const [showPassword, setShowPassword] = useState(false); // Fetch categories for user upload selection const { data: categories } = useQuery({ queryKey: ['categories', 'global'], queryFn: () => categoriesService.getGlobalCategories() }); // Fetch default settings const { data: settings } = useQuery({ queryKey: ['admin-settings'], queryFn: () => settingsService.getAllSettings() }); // Update default expiration days when settings are loaded useEffect(() => { if (settings?.general_default_expiration_days) { setFormData(prev => ({ ...prev, expires_in_days: settings.general_default_expiration_days })); } }, [settings]); // Update theme when event type changes useEffect(() => { const recommendedPreset = EVENT_TYPE_PRESETS[formData.event_type]; if (recommendedPreset && GALLERY_THEME_PRESETS[recommendedPreset]) { setFormData(prev => ({ ...prev, theme_preset: recommendedPreset, theme_config: GALLERY_THEME_PRESETS[recommendedPreset].config })); } }, [formData.event_type]); const createMutation = useMutation({ mutationFn: eventsService.createEvent, onSuccess: (data) => { if (isMountedRef.current) { toast.success(t('toast.eventCreated')); navigate(`/admin/events/${data.id}`); } }, onError: (error: any) => { const errorMessage = error.response?.data?.error || error.message || t('errors.eventCreationFailed'); // If validation errors exist, show them if (error.response?.data?.errors) { const validationErrors = error.response.data.errors; validationErrors.forEach((err: any) => { toast.error(`${err.param}: ${err.msg}`); }); } else { toast.error(errorMessage); } }, }); const validateForm = (): boolean => { const newErrors: Partial> = {}; if (!formData.event_name) { newErrors.event_name = t('validation.eventNameRequired'); } if (!formData.event_date) { newErrors.event_date = t('validation.eventDateRequired'); } if (!formData.host_name) { newErrors.host_name = t('validation.hostNameRequired'); } if (!formData.host_email) { newErrors.host_email = t('validation.hostEmailRequired'); } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.host_email)) { newErrors.host_email = t('validation.invalidEmailFormat'); } if (!formData.admin_email) { newErrors.admin_email = t('validation.adminEmailRequired'); } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.admin_email)) { newErrors.admin_email = t('validation.invalidEmailFormat'); } if (formData.require_password) { if (!formData.password) { newErrors.password = t('validation.passwordRequired'); } else if (formData.password.length < 6) { newErrors.password = t('validation.passwordMinLength'); } else if (/^\d{1,6}$/.test(formData.password)) { // Prevent simple numeric passwords like "123456" newErrors.password = t('validation.passwordTooSimple', 'Password cannot be just numbers. Consider using a date format like "04.07.2025"'); } if (formData.password !== formData.confirm_password) { newErrors.confirm_password = t('validation.passwordsDoNotMatch'); } } if (formData.expires_in_days < 1 || formData.expires_in_days > 365) { newErrors.expires_in_days = t('validation.expirationRange'); } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!validateForm()) { return; } const feedbackSettings = formData.feedback_settings; const payload = { event_type: formData.event_type, event_name: formData.event_name, event_date: formData.event_date, host_name: formData.host_name, host_email: formData.host_email, admin_email: formData.admin_email, require_password: formData.require_password, password: formData.require_password ? formData.password : undefined, welcome_message: formData.welcome_message || '', color_theme: JSON.stringify(formData.theme_config), expiration_days: formData.expires_in_days, allow_user_uploads: formData.allow_user_uploads, upload_category_id: formData.upload_category_id, feedback_enabled: feedbackSettings.feedback_enabled, allow_ratings: feedbackSettings.allow_ratings, allow_likes: feedbackSettings.allow_likes, allow_comments: feedbackSettings.allow_comments, allow_favorites: feedbackSettings.allow_favorites, require_name_email: feedbackSettings.require_name_email, moderate_comments: feedbackSettings.moderate_comments, show_feedback_to_guests: feedbackSettings.show_feedback_to_guests, }; createMutation.mutate(payload); }; const handleInputChange = (field: keyof FormData) => ( e: React.ChangeEvent ) => { setFormData({ ...formData, [field]: e.target.value }); setErrors({ ...errors, [field]: undefined }); }; const handleThemeChange = (newTheme: ThemeConfig) => { setFormData(prev => ({ ...prev, theme_config: newTheme })); }; const handlePresetChange = (presetName: string) => { const preset = GALLERY_THEME_PRESETS[presetName]; if (preset) { setFormData(prev => ({ ...prev, theme_preset: presetName, theme_config: preset.config })); } }; const handlePasswordGenerated = (password: string) => { setFormData(prev => ({ ...prev, password: password, confirm_password: password })); // Clear password errors since we generated a valid one if (errors.password || errors.confirm_password) { setErrors(prev => ({ ...prev, password: undefined, confirm_password: undefined })); } }; return (

{t('events.create')}

{/* Event Details */}

{t('events.eventDetails')}

{EVENT_TYPES.map((type) => ( ))}
} /> } />
setFormData(prev => ({ ...prev, welcome_message: value }))} placeholder={t('events.welcomeMessagePlaceholder')} rows={4} />
{/* Theme Selection */}

{t('events.themeAndStyle')}

{/* Quick Theme Preview */} {!showThemeCustomizer && (

{GALLERY_THEME_PRESETS[formData.theme_preset]?.name || 'Custom Theme'}

Gallery Layout: {formData.theme_config.galleryLayout || 'grid'}

)} {/* Theme Customizer */} {showThemeCustomizer && (
{/* Theme Customizer */} {/* Gallery Preview */}
)}
{/* Access & Security */}

{t('events.accessAndSecurity')}

} /> } />
} />
{!formData.require_password && (
{t('events.publicGalleryWarning', 'Public galleries are accessible to anyone with the link. Consider enabling download watermarks and monitoring activity.')}
)}
{formData.require_password && (
} rightIcon={ } /> {/* Password Generator */}
} />
)}
} />
{t('events.daysAfterEvent')}
{formData.event_date && (

{t('events.expiresOn')}: {format(addDays(new Date(formData.event_date), formData.expires_in_days))}

)}
{/* User Upload Settings */}
{formData.allow_user_uploads && categories && categories.length > 0 && (

{t('events.uploadCategoryHelp')}

)}
{/* Feedback Settings */} setFormData(prev => ({ ...prev, feedback_settings: settings }))} /> {/* Form Actions */}
); };