Fix brand theme application and add comprehensive translations
- Fixed theme not being reflected on gallery and admin login pages - Created GlobalThemeProvider to apply themes globally - Updated gallery and admin login pages to use dynamic CSS variables - Added complete translations for all admin sections in English and German: - Notifications management - Event view and creation - Photo upload functionality - Category management - Archive page view - Analytics dashboard - Branding and theme settings - System settings - CMS page management - Email configuration - Fixed admin photo management display issues - Fixed photo upload category assignment - Added password reset functionality for galleries - Improved error handling and user feedback 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Navigate, useSearchParams } from 'react-router-dom';
|
||||
import { Lock, Mail, Eye, EyeOff, AlertCircle } from 'lucide-react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { Button, Input, Card } from '../../components/common';
|
||||
import { Button, Input, Card, ReCaptcha } from '../../components/common';
|
||||
import { useAdminAuth } from '../../contexts';
|
||||
import { authService } from '../../services/auth.service';
|
||||
import { getAuthToken } from '../../config/api';
|
||||
import { getAuthToken, api } from '../../config/api';
|
||||
|
||||
export const AdminLoginPage: React.FC = () => {
|
||||
const { isAuthenticated, login } = useAdminAuth();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
email: '',
|
||||
@@ -19,6 +21,24 @@ export const AdminLoginPage: React.FC = () => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||
const [loginSuccess, setLoginSuccess] = useState(false);
|
||||
const [recaptchaToken, setRecaptchaToken] = useState<string | null>(null);
|
||||
|
||||
// Fetch branding settings
|
||||
const { data: settingsData } = useQuery({
|
||||
queryKey: ['admin-login-settings'],
|
||||
queryFn: async () => {
|
||||
const response = await api.get('/api/public/settings');
|
||||
return response.data;
|
||||
},
|
||||
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
|
||||
});
|
||||
|
||||
// Check for session expired message
|
||||
useEffect(() => {
|
||||
if (searchParams.get('session') === 'expired') {
|
||||
toast.info('Your session has expired. Please log in again.');
|
||||
}
|
||||
}, [searchParams]);
|
||||
|
||||
// Redirect if already authenticated or login successful
|
||||
if (isAuthenticated || loginSuccess) {
|
||||
@@ -55,7 +75,10 @@ export const AdminLoginPage: React.FC = () => {
|
||||
setErrors({});
|
||||
|
||||
try {
|
||||
const response = await authService.adminLogin(formData);
|
||||
const response = await authService.adminLogin({
|
||||
...formData,
|
||||
recaptchaToken
|
||||
});
|
||||
login(response.token, response.user);
|
||||
toast.success('Login successful!');
|
||||
setLoginSuccess(true);
|
||||
@@ -93,15 +116,23 @@ export const AdminLoginPage: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-primary-50 to-neutral-100 flex items-center justify-center p-4">
|
||||
<div className="min-h-screen flex items-center justify-center p-4" style={{ backgroundColor: 'var(--color-background, #fafafa)' }}>
|
||||
<div className="w-full max-w-md">
|
||||
{/* Logo/Header */}
|
||||
<div className="text-center mb-8">
|
||||
<div className="inline-flex items-center justify-center w-16 h-16 bg-primary-600 rounded-full mb-4">
|
||||
<Lock className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h1 className="text-3xl font-bold text-neutral-900">Admin Login</h1>
|
||||
<p className="text-neutral-600 mt-2">Sign in to manage your photo galleries</p>
|
||||
{settingsData?.branding_logo_url ? (
|
||||
<img
|
||||
src={`${import.meta.env.VITE_API_URL || 'http://localhost:3001'}${settingsData.branding_logo_url}`}
|
||||
alt={settingsData.branding_company_name || 'Company Logo'}
|
||||
className="h-16 w-auto object-contain mx-auto mb-4"
|
||||
/>
|
||||
) : (
|
||||
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full mb-4" style={{ backgroundColor: 'var(--color-primary, #5C8762)' }}>
|
||||
<Lock className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
)}
|
||||
<h1 className="text-3xl font-bold" style={{ color: 'var(--color-text, #171717)' }}>Admin Login</h1>
|
||||
<p className="mt-2" style={{ color: 'var(--color-text, #171717)', opacity: 0.7 }}>Sign in to manage your photo galleries</p>
|
||||
</div>
|
||||
|
||||
{/* Login Form */}
|
||||
@@ -178,6 +209,12 @@ export const AdminLoginPage: React.FC = () => {
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* reCAPTCHA */}
|
||||
<ReCaptcha
|
||||
onChange={setRecaptchaToken}
|
||||
onExpired={() => setRecaptchaToken(null)}
|
||||
/>
|
||||
|
||||
{/* Submit Button */}
|
||||
<Button
|
||||
type="submit"
|
||||
@@ -192,10 +229,14 @@ export const AdminLoginPage: React.FC = () => {
|
||||
</Card>
|
||||
|
||||
{/* Footer */}
|
||||
<p className="text-center text-sm text-neutral-600 mt-8">
|
||||
<p className="text-center text-sm mt-8" style={{ color: 'var(--color-text, #171717)', opacity: 0.7 }}>
|
||||
Need help? Contact{' '}
|
||||
<a href="mailto:support@example.com" className="text-primary-600 hover:text-primary-700">
|
||||
support@example.com
|
||||
<a
|
||||
href={`mailto:${settingsData?.branding_support_email || 'support@example.com'}`}
|
||||
className="hover:underline"
|
||||
style={{ color: 'var(--color-primary, #5C8762)' }}
|
||||
>
|
||||
{settingsData?.branding_support_email || 'support@example.com'}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user