Fix translation issues in event creation and detail pages
- Add missing translation keys for event creation form - Replace all hardcoded strings with translation keys in CreateEventPage - Add validation error message translations - Add event types and color theme translations - Add errors and validation sections to translation files - Update German translations with corresponding keys 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,8 @@
|
||||
"refresh": "Aktualisieren",
|
||||
"preview": "Vorschau",
|
||||
"processing": "Wird verarbeitet...",
|
||||
"upload": "Hochladen"
|
||||
"upload": "Hochladen",
|
||||
"days": "Tage"
|
||||
},
|
||||
"upload": {
|
||||
"photoCategory": "Fotokategorie",
|
||||
@@ -245,6 +246,30 @@
|
||||
"days365": "1 Jahr",
|
||||
"createNewEvent": "Neue Veranstaltung erstellen",
|
||||
"setupNewGallery": "Richten Sie eine neue Fotogalerie für Ihre Veranstaltung ein",
|
||||
"createNewEventSubtitle": "Richten Sie eine neue Fotogalerie für Ihre Veranstaltung ein",
|
||||
"eventNamePlaceholder": "z.B. Max & Maria's Hochzeit",
|
||||
"welcomeMessageOptional": "Willkommensnachricht (Optional)",
|
||||
"welcomeMessagePlaceholder": "Willkommen zu unserem besonderen Tag! Laden Sie diese Erinnerungen gerne herunter und teilen Sie sie...",
|
||||
"hostEmailPlaceholder": "gastgeber@beispiel.de",
|
||||
"adminEmailPlaceholder": "admin@beispiel.de",
|
||||
"securityAndAccess": "Sicherheit & Zugriff",
|
||||
"enterPassword": "Passwort eingeben",
|
||||
"confirmPasswordPlaceholder": "Passwort bestätigen",
|
||||
"galleryExpiresOn": "Galerie läuft ab am {{date}}",
|
||||
"guestsWillReceiveWarning": "Gäste erhalten 7 Tage vor Ablauf eine Warn-E-Mail.",
|
||||
"types": {
|
||||
"wedding": "Hochzeit",
|
||||
"birthday": "Geburtstag",
|
||||
"corporate": "Geschäftlich",
|
||||
"other": "Andere"
|
||||
},
|
||||
"themes": {
|
||||
"default": "Standard",
|
||||
"oceanBlue": "Ozeanblau",
|
||||
"royalPurple": "Königliches Lila",
|
||||
"roseGold": "Roségold",
|
||||
"sunsetAmber": "Sonnenuntergang Bernstein"
|
||||
},
|
||||
"adminNotificationEmail": "Admin-Benachrichtigungs-E-Mail",
|
||||
"inactive": "Inaktiv",
|
||||
"expired": "Abgelaufen",
|
||||
@@ -602,6 +627,38 @@
|
||||
"datenschutz": "Datenschutzerklärung",
|
||||
"pageUpdated": "Seite erfolgreich aktualisiert"
|
||||
},
|
||||
"errors": {
|
||||
"notFound": "Nicht gefunden",
|
||||
"galleryNotFound": "Galerie nicht gefunden",
|
||||
"galleryNotFoundMessage": "Diese Galerie existiert nicht oder wurde entfernt.",
|
||||
"galleryArchived": "Galerie archiviert",
|
||||
"galleryArchivedMessage": "Diese Galerie wurde archiviert und ist nicht mehr zugänglich. Bitte kontaktieren Sie den Veranstalter, wenn Sie Zugriff auf diese Fotos benötigen.",
|
||||
"unauthorized": "Nicht autorisiert",
|
||||
"forbidden": "Verboten",
|
||||
"serverError": "Serverfehler",
|
||||
"somethingWentWrong": "Etwas ist schiefgelaufen",
|
||||
"tryAgainLater": "Bitte versuchen Sie es später erneut",
|
||||
"refreshPage": "Seite aktualisieren",
|
||||
"oopsSomethingWentWrong": "Hoppla! Etwas ist schiefgelaufen",
|
||||
"unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Keine Sorge, Ihre Daten sind sicher.",
|
||||
"goToHomepage": "Zur Startseite",
|
||||
"errorDetails": "Fehlerdetails",
|
||||
"requiredFields": "Bitte füllen Sie alle Pflichtfelder aus",
|
||||
"enterTestEmail": "Bitte geben Sie eine Test-E-Mail-Adresse ein",
|
||||
"failedToCreateEvent": "Veranstaltung konnte nicht erstellt werden",
|
||||
"networkError": "Netzwerkfehler. Bitte überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.",
|
||||
"sessionExpired": "Sitzung abgelaufen. Bitte melden Sie sich erneut an."
|
||||
},
|
||||
"validation": {
|
||||
"eventNameRequired": "Veranstaltungsname ist erforderlich",
|
||||
"hostEmailRequired": "Gastgeber-E-Mail ist erforderlich",
|
||||
"adminEmailRequired": "Admin-E-Mail ist erforderlich",
|
||||
"invalidEmailFormat": "Ungültiges E-Mail-Format",
|
||||
"passwordRequired": "Passwort ist erforderlich",
|
||||
"passwordMinLength": "Passwort muss mindestens 6 Zeichen lang sein",
|
||||
"passwordsDoNotMatch": "Passwörter stimmen nicht überein",
|
||||
"expirationRange": "Ablauf muss zwischen 1 und 365 Tagen liegen"
|
||||
},
|
||||
"maintenance": {
|
||||
"title": "Systemwartung",
|
||||
"message": "Wir führen derzeit geplante Wartungsarbeiten durch, um unseren Service zu verbessern. Wir sind in Kürze wieder online.",
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
"refresh": "Refresh",
|
||||
"preview": "Preview",
|
||||
"processing": "Processing...",
|
||||
"upload": "Upload"
|
||||
"upload": "Upload",
|
||||
"days": "days"
|
||||
},
|
||||
"upload": {
|
||||
"photoCategory": "Photo Category",
|
||||
@@ -165,6 +166,30 @@
|
||||
"createEvent": "Create Event",
|
||||
"createNewEvent": "Create New Event",
|
||||
"setupNewGallery": "Set up a new photo gallery for your event",
|
||||
"createNewEventSubtitle": "Set up a new photo gallery for your event",
|
||||
"eventNamePlaceholder": "e.g., John & Jane's Wedding",
|
||||
"welcomeMessageOptional": "Welcome Message (Optional)",
|
||||
"welcomeMessagePlaceholder": "Welcome to our special day! Feel free to download and share these memories...",
|
||||
"hostEmailPlaceholder": "host@example.com",
|
||||
"adminEmailPlaceholder": "admin@example.com",
|
||||
"securityAndAccess": "Security & Access",
|
||||
"enterPassword": "Enter password",
|
||||
"confirmPasswordPlaceholder": "Confirm password",
|
||||
"galleryExpiresOn": "Gallery will expire on {{date}}",
|
||||
"guestsWillReceiveWarning": "Guests will receive a warning email 7 days before expiration.",
|
||||
"types": {
|
||||
"wedding": "Wedding",
|
||||
"birthday": "Birthday",
|
||||
"corporate": "Corporate",
|
||||
"other": "Other"
|
||||
},
|
||||
"themes": {
|
||||
"default": "Default",
|
||||
"oceanBlue": "Ocean Blue",
|
||||
"royalPurple": "Royal Purple",
|
||||
"roseGold": "Rose Gold",
|
||||
"sunsetAmber": "Sunset Amber"
|
||||
},
|
||||
"eventDetails": "Event Details",
|
||||
"eventName": "Event Name",
|
||||
"eventType": "Event Type",
|
||||
@@ -548,7 +573,20 @@
|
||||
"goToHomepage": "Go to Homepage",
|
||||
"errorDetails": "Error Details",
|
||||
"requiredFields": "Please fill in all required fields",
|
||||
"enterTestEmail": "Please enter a test email address"
|
||||
"enterTestEmail": "Please enter a test email address",
|
||||
"failedToCreateEvent": "Failed to create event",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"sessionExpired": "Session expired. Please login again."
|
||||
},
|
||||
"validation": {
|
||||
"eventNameRequired": "Event name is required",
|
||||
"hostEmailRequired": "Host email is required",
|
||||
"adminEmailRequired": "Admin email is required",
|
||||
"invalidEmailFormat": "Invalid email format",
|
||||
"passwordRequired": "Password is required",
|
||||
"passwordMinLength": "Password must be at least 6 characters",
|
||||
"passwordsDoNotMatch": "Passwords do not match",
|
||||
"expirationRange": "Expiration must be between 1 and 365 days"
|
||||
},
|
||||
"legal": {
|
||||
"impressum": "Legal Notice",
|
||||
|
||||
@@ -34,16 +34,16 @@ interface FormData {
|
||||
}
|
||||
|
||||
const EVENT_TYPES = [
|
||||
{ value: 'wedding', label: 'Wedding', emoji: '💒' },
|
||||
{ value: 'birthday', label: 'Birthday', emoji: '🎂' },
|
||||
{ value: 'corporate', label: 'Corporate', emoji: '🏢' },
|
||||
{ value: 'other', label: 'Other', emoji: '📸' },
|
||||
{ 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: '📸' },
|
||||
];
|
||||
|
||||
const COLOR_THEMES = [
|
||||
{
|
||||
value: 'default',
|
||||
label: 'Default (Green)',
|
||||
labelKey: 'events.themes.default',
|
||||
color: 'bg-primary-600',
|
||||
theme: {
|
||||
primaryColor: '#5C8762',
|
||||
@@ -55,7 +55,7 @@ const COLOR_THEMES = [
|
||||
},
|
||||
{
|
||||
value: 'blue',
|
||||
label: 'Ocean Blue',
|
||||
labelKey: 'events.themes.oceanBlue',
|
||||
color: 'bg-blue-600',
|
||||
theme: {
|
||||
primaryColor: '#2563eb',
|
||||
@@ -67,7 +67,7 @@ const COLOR_THEMES = [
|
||||
},
|
||||
{
|
||||
value: 'purple',
|
||||
label: 'Royal Purple',
|
||||
labelKey: 'events.themes.royalPurple',
|
||||
color: 'bg-purple-600',
|
||||
theme: {
|
||||
primaryColor: '#9333ea',
|
||||
@@ -79,7 +79,7 @@ const COLOR_THEMES = [
|
||||
},
|
||||
{
|
||||
value: 'rose',
|
||||
label: 'Rose Gold',
|
||||
labelKey: 'events.themes.roseGold',
|
||||
color: 'bg-rose-600',
|
||||
theme: {
|
||||
primaryColor: '#e11d48',
|
||||
@@ -91,7 +91,7 @@ const COLOR_THEMES = [
|
||||
},
|
||||
{
|
||||
value: 'amber',
|
||||
label: 'Sunset Amber',
|
||||
labelKey: 'events.themes.sunsetAmber',
|
||||
color: 'bg-amber-600',
|
||||
theme: {
|
||||
primaryColor: '#d97706',
|
||||
@@ -142,7 +142,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
mutationFn: eventsService.createEvent,
|
||||
onSuccess: (data) => {
|
||||
if (isMountedRef.current) {
|
||||
toast.success('Event created successfully!');
|
||||
toast.success(t('toast.eventCreated'));
|
||||
// Add a small delay to ensure navigation works properly
|
||||
setTimeout(() => {
|
||||
if (isMountedRef.current && data?.id) {
|
||||
@@ -157,7 +157,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
if (!isMountedRef.current) return;
|
||||
|
||||
if (error.code === 'ERR_NETWORK' || error.code === 'ERR_CONNECTION_RESET') {
|
||||
toast.error('Network error. Please check your connection and try again.');
|
||||
toast.error(t('errors.networkError'));
|
||||
} else if (error.response?.data?.errors) {
|
||||
const newErrors: Record<string, string> = {};
|
||||
error.response.data.errors.forEach((err: any) => {
|
||||
@@ -165,10 +165,10 @@ export const CreateEventPage: React.FC = () => {
|
||||
});
|
||||
setErrors(newErrors);
|
||||
} else if (error.response?.status === 401) {
|
||||
toast.error('Session expired. Please login again.');
|
||||
toast.error(t('errors.sessionExpired'));
|
||||
navigate('/admin/login');
|
||||
} else {
|
||||
toast.error(error.response?.data?.error || 'Failed to create event');
|
||||
toast.error(error.response?.data?.error || t('errors.failedToCreateEvent'));
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -177,33 +177,33 @@ export const CreateEventPage: React.FC = () => {
|
||||
const newErrors: Partial<Record<keyof FormData, string>> = {};
|
||||
|
||||
if (!formData.event_name.trim()) {
|
||||
newErrors.event_name = 'Event name is required';
|
||||
newErrors.event_name = t('validation.eventNameRequired');
|
||||
}
|
||||
|
||||
if (!formData.host_email) {
|
||||
newErrors.host_email = 'Host email is required';
|
||||
newErrors.host_email = t('validation.hostEmailRequired');
|
||||
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.host_email)) {
|
||||
newErrors.host_email = 'Invalid email format';
|
||||
newErrors.host_email = t('validation.invalidEmailFormat');
|
||||
}
|
||||
|
||||
if (!formData.admin_email) {
|
||||
newErrors.admin_email = 'Admin email is required';
|
||||
newErrors.admin_email = t('validation.adminEmailRequired');
|
||||
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.admin_email)) {
|
||||
newErrors.admin_email = 'Invalid email format';
|
||||
newErrors.admin_email = t('validation.invalidEmailFormat');
|
||||
}
|
||||
|
||||
if (!formData.password) {
|
||||
newErrors.password = 'Password is required';
|
||||
newErrors.password = t('validation.passwordRequired');
|
||||
} else if (formData.password.length < 6) {
|
||||
newErrors.password = 'Password must be at least 6 characters';
|
||||
newErrors.password = t('validation.passwordMinLength');
|
||||
}
|
||||
|
||||
if (formData.password !== formData.confirm_password) {
|
||||
newErrors.confirm_password = 'Passwords do not match';
|
||||
newErrors.confirm_password = t('validation.passwordsDoNotMatch');
|
||||
}
|
||||
|
||||
if (formData.expires_in_days < 1 || formData.expires_in_days > 365) {
|
||||
newErrors.expires_in_days = 'Expiration must be between 1 and 365 days';
|
||||
newErrors.expires_in_days = t('validation.expirationRange');
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
@@ -257,23 +257,23 @@ export const CreateEventPage: React.FC = () => {
|
||||
onClick={() => navigate('/admin/events')}
|
||||
className="mb-4"
|
||||
>
|
||||
Back to Events
|
||||
{t('events.backToEvents')}
|
||||
</Button>
|
||||
|
||||
<h1 className="text-2xl font-bold text-neutral-900">Create New Event</h1>
|
||||
<p className="text-neutral-600 mt-1">Set up a new photo gallery for your event</p>
|
||||
<h1 className="text-2xl font-bold text-neutral-900">{t('events.createNewEvent')}</h1>
|
||||
<p className="text-neutral-600 mt-1">{t('events.createNewEventSubtitle')}</p>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
{/* Event Details */}
|
||||
<Card padding="md" className="mb-6">
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">Event Details</h2>
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">{t('events.eventDetails')}</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
{/* Event Type */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Event Type
|
||||
{t('events.eventType')}
|
||||
</label>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3">
|
||||
{EVENT_TYPES.map(type => (
|
||||
@@ -288,7 +288,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
}`}
|
||||
>
|
||||
<div className="text-2xl mb-1">{type.emoji}</div>
|
||||
<div className="text-sm font-medium">{type.label}</div>
|
||||
<div className="text-sm font-medium">{t(type.labelKey)}</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -297,7 +297,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
{/* Event Name */}
|
||||
<div>
|
||||
<label htmlFor="event_name" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Event Name
|
||||
{t('events.eventName')}
|
||||
</label>
|
||||
<Input
|
||||
id="event_name"
|
||||
@@ -305,7 +305,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
value={formData.event_name}
|
||||
onChange={handleInputChange('event_name')}
|
||||
error={errors.event_name}
|
||||
placeholder="e.g., Smith-Jones Wedding"
|
||||
placeholder={t('events.eventNamePlaceholder')}
|
||||
leftIcon={<Calendar className="w-5 h-5 text-neutral-400" />}
|
||||
/>
|
||||
</div>
|
||||
@@ -313,7 +313,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
{/* Event Date */}
|
||||
<div>
|
||||
<label htmlFor="event_date" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Event Date
|
||||
{t('events.eventDate')}
|
||||
</label>
|
||||
<Input
|
||||
id="event_date"
|
||||
@@ -327,13 +327,13 @@ export const CreateEventPage: React.FC = () => {
|
||||
{/* Welcome Message */}
|
||||
<div>
|
||||
<label htmlFor="welcome_message" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Welcome Message (Optional)
|
||||
{t('events.welcomeMessageOptional')}
|
||||
</label>
|
||||
<textarea
|
||||
id="welcome_message"
|
||||
value={formData.welcome_message}
|
||||
onChange={handleInputChange('welcome_message')}
|
||||
placeholder="A personalized message for your guests..."
|
||||
placeholder={t('events.welcomeMessagePlaceholder')}
|
||||
className="w-full px-3 py-2 border border-neutral-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
|
||||
rows={3}
|
||||
/>
|
||||
@@ -343,13 +343,13 @@ export const CreateEventPage: React.FC = () => {
|
||||
|
||||
{/* Contact Information */}
|
||||
<Card padding="md" className="mb-6">
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">Contact Information</h2>
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">{t('events.contactInformation')}</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Host Email */}
|
||||
<div>
|
||||
<label htmlFor="host_email" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Host Email
|
||||
{t('events.hostEmail')}
|
||||
</label>
|
||||
<Input
|
||||
id="host_email"
|
||||
@@ -357,18 +357,18 @@ export const CreateEventPage: React.FC = () => {
|
||||
value={formData.host_email}
|
||||
onChange={handleInputChange('host_email')}
|
||||
error={errors.host_email}
|
||||
placeholder="host@example.com"
|
||||
placeholder={t('events.hostEmailPlaceholder')}
|
||||
leftIcon={<Mail className="w-5 h-5 text-neutral-400" />}
|
||||
/>
|
||||
<p className="text-xs text-neutral-500 mt-1">
|
||||
Will receive gallery creation and expiration notifications
|
||||
{t('events.hostEmailHelp')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Admin Email */}
|
||||
<div>
|
||||
<label htmlFor="admin_email" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Admin Notification Email
|
||||
{t('events.adminNotificationEmail')}
|
||||
</label>
|
||||
<Input
|
||||
id="admin_email"
|
||||
@@ -376,11 +376,11 @@ export const CreateEventPage: React.FC = () => {
|
||||
value={formData.admin_email}
|
||||
onChange={handleInputChange('admin_email')}
|
||||
error={errors.admin_email}
|
||||
placeholder="admin@example.com"
|
||||
placeholder={t('events.adminEmailPlaceholder')}
|
||||
leftIcon={<Mail className="w-5 h-5 text-neutral-400" />}
|
||||
/>
|
||||
<p className="text-xs text-neutral-500 mt-1">
|
||||
Will receive system notifications and archive confirmations
|
||||
{t('events.adminEmailHelp')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -388,13 +388,13 @@ export const CreateEventPage: React.FC = () => {
|
||||
|
||||
{/* Security & Access */}
|
||||
<Card padding="md" className="mb-6">
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">Security & Access</h2>
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">{t('events.securityAndAccess')}</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Password */}
|
||||
<div>
|
||||
<label htmlFor="password" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Gallery Password
|
||||
{t('events.galleryPassword')}
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Input
|
||||
@@ -403,7 +403,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
value={formData.password}
|
||||
onChange={handleInputChange('password')}
|
||||
error={errors.password}
|
||||
placeholder="Enter password"
|
||||
placeholder={t('events.enterPassword')}
|
||||
leftIcon={<Lock className="w-5 h-5 text-neutral-400" />}
|
||||
/>
|
||||
</div>
|
||||
@@ -412,7 +412,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
{/* Confirm Password */}
|
||||
<div>
|
||||
<label htmlFor="confirm_password" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Confirm Password
|
||||
{t('events.confirmPassword')}
|
||||
</label>
|
||||
<Input
|
||||
id="confirm_password"
|
||||
@@ -420,7 +420,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
value={formData.confirm_password}
|
||||
onChange={handleInputChange('confirm_password')}
|
||||
error={errors.confirm_password}
|
||||
placeholder="Confirm password"
|
||||
placeholder={t('events.confirmPasswordPlaceholder')}
|
||||
leftIcon={<Lock className="w-5 h-5 text-neutral-400" />}
|
||||
/>
|
||||
</div>
|
||||
@@ -434,20 +434,20 @@ export const CreateEventPage: React.FC = () => {
|
||||
onChange={(e) => setShowPassword(e.target.checked)}
|
||||
className="w-4 h-4 text-primary-600 border-neutral-300 rounded focus:ring-primary-500"
|
||||
/>
|
||||
<span className="ml-2 text-sm text-neutral-700">Show passwords</span>
|
||||
<span className="ml-2 text-sm text-neutral-700">{t('events.showPasswords')}</span>
|
||||
</label>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Gallery Settings */}
|
||||
<Card padding="md" className="mb-6">
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">Gallery Settings</h2>
|
||||
<h2 className="text-lg font-semibold text-neutral-900 mb-4">{t('events.gallerySettings')}</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
{/* Color Theme */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Color Theme
|
||||
{t('events.colorTheme')}
|
||||
</label>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3">
|
||||
{COLOR_THEMES.map(theme => (
|
||||
@@ -462,7 +462,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
}`}
|
||||
>
|
||||
<div className={`w-full h-8 ${theme.color} rounded mb-2`} />
|
||||
<div className="text-xs font-medium">{theme.label}</div>
|
||||
<div className="text-xs font-medium">{t(theme.labelKey)}</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -471,7 +471,7 @@ export const CreateEventPage: React.FC = () => {
|
||||
{/* Expiration */}
|
||||
<div>
|
||||
<label htmlFor="expires_in_days" className="block text-sm font-medium text-neutral-700 mb-1">
|
||||
Gallery Expires In
|
||||
{t('events.galleryExpiresIn')}
|
||||
</label>
|
||||
<div className="flex items-center gap-4">
|
||||
<Input
|
||||
@@ -485,13 +485,13 @@ export const CreateEventPage: React.FC = () => {
|
||||
className="w-32"
|
||||
leftIcon={<Clock className="w-5 h-5 text-neutral-400" />}
|
||||
/>
|
||||
<span className="text-sm text-neutral-700">days</span>
|
||||
<span className="text-sm text-neutral-700">{t('common.days')}</span>
|
||||
</div>
|
||||
<div className="mt-2 p-3 bg-blue-50 rounded-lg flex items-start gap-2">
|
||||
<Info className="w-5 h-5 text-blue-600 flex-shrink-0" />
|
||||
<div className="text-sm text-blue-800">
|
||||
<p>Gallery will expire on {format(addDays(new Date(), formData.expires_in_days), 'MMMM d, yyyy')}</p>
|
||||
<p className="mt-1">Guests will receive a warning email 7 days before expiration.</p>
|
||||
<p>{t('events.galleryExpiresOn', { date: format(addDays(new Date(), formData.expires_in_days), 'MMMM d, yyyy') })}</p>
|
||||
<p className="mt-1">{t('events.guestsWillReceiveWarning')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -565,14 +565,14 @@ export const CreateEventPage: React.FC = () => {
|
||||
variant="outline"
|
||||
onClick={() => navigate('/admin/events')}
|
||||
>
|
||||
Cancel
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
isLoading={createMutation.isPending}
|
||||
>
|
||||
Create Event
|
||||
{t('events.createEvent')}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user