refactor: rename project from wedding-photo-sharing to PicPeak
Create Release / check-version-change (push) Successful in 2m25s
Automatic Version Bump / version-bump (push) Failing after 8m2s
Create Release / create-release (push) Has been skipped

- Update Docker image names and network configurations
- Rename package.json project names to picpeak-backend/frontend
- Update CI/CD configurations (Drone CI and GitHub Actions)
- Update documentation and setup scripts
- Update application branding in source code
- Change default database name to picpeak
- Update PM2 ecosystem config

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
This commit is contained in:
2025-07-12 09:22:14 +02:00
co-authored by Claude
parent d065132bb7
commit 288b0c25e6
42 changed files with 1116 additions and 422 deletions
+41 -134
View File
@@ -15,16 +15,14 @@ import {
CheckCircle,
Upload,
Image,
Key,
Palette,
Settings
Key
} from 'lucide-react';
import { parseISO, differenceInDays } from 'date-fns';
import { toast } from 'react-toastify';
import { useLocalizedDate } from '../../hooks/useLocalizedDate';
import { Button, Input, Card, Loading } from '../../components/common';
import { PhotoUpload, EventCategoryManager, AdminPhotoGrid, AdminPhotoViewer, PhotoFilters, PasswordResetModal, ThemeDisplay, ThemeCustomizerEnhanced, ThemeEditorModal, HeroPhotoSelector, PhotoUploadModal } from '../../components/admin';
import { EventCategoryManager, AdminPhotoGrid, AdminPhotoViewer, PhotoFilters, PasswordResetModal, ThemeCustomizerEnhanced, ThemeDisplay, HeroPhotoSelector, PhotoUploadModal } from '../../components/admin';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { eventsService } from '../../services/events.service';
import { archiveService } from '../../services/archive.service';
@@ -60,10 +58,8 @@ export const EventDetailsPage: React.FC = () => {
const [activeTab, setActiveTab] = useState<'overview' | 'photos' | 'categories'>('overview');
const [selectedPhoto, setSelectedPhoto] = useState<{ photo: AdminPhoto; index: number } | null>(null);
const [showPasswordReset, setShowPasswordReset] = useState(false);
const [showThemeCustomizer, setShowThemeCustomizer] = useState(false);
const [currentTheme, setCurrentTheme] = useState<ThemeConfig | null>(null);
const [currentPresetName, setCurrentPresetName] = useState<string>('default');
const [showThemeEditorModal, setShowThemeEditorModal] = useState(false);
// Photo filters state
const [photoFilters, setPhotoFilters] = useState({
@@ -203,7 +199,7 @@ export const EventDetailsPage: React.FC = () => {
const handleSaveEdit = () => {
// Prepare color_theme - if we have a custom theme, serialize it
let themeToSave = editForm.color_theme;
if (currentTheme && (currentPresetName === 'custom' || showThemeCustomizer)) {
if (currentTheme && currentPresetName === 'custom') {
themeToSave = JSON.stringify(currentTheme);
} else if (currentPresetName && currentPresetName !== 'custom') {
// Use preset name for non-custom themes
@@ -256,34 +252,6 @@ export const EventDetailsPage: React.FC = () => {
}
};
const handleThemeModalSave = async (theme: ThemeConfig, presetName: string) => {
// Prepare theme for saving
let themeToSave: string;
if (presetName !== 'custom' && GALLERY_THEME_PRESETS[presetName]) {
// Save preset name for standard presets
themeToSave = presetName;
} else {
// Save full theme config for custom themes
themeToSave = JSON.stringify(theme);
}
try {
// Update the event with new theme
await eventsService.updateEvent(parseInt(id!), {
color_theme: themeToSave
});
// Invalidate queries to refresh the data
await queryClient.invalidateQueries({ queryKey: ['admin-event', id] });
// Close modal and show success
setShowThemeEditorModal(false);
toast.success(t('toast.themeUpdated'));
} catch (error) {
console.error('Failed to save theme:', error);
toast.error(t('toast.saveError'));
}
};
return (
<div>
@@ -492,73 +460,6 @@ export const EventDetailsPage: React.FC = () => {
/>
</div>
<div>
<label className="block text-sm font-medium text-neutral-700 mb-1">
{t('events.galleryTheme')}
</label>
{!showThemeCustomizer ? (
<div className="space-y-2">
<select
value={currentPresetName}
onChange={(e) => {
const presetName = e.target.value;
setCurrentPresetName(presetName);
if (presetName !== 'custom') {
const preset = GALLERY_THEME_PRESETS[presetName];
if (preset) {
setCurrentTheme(preset.config);
setEditForm(prev => ({ ...prev, color_theme: presetName }));
}
}
}}
className="w-full px-3 py-2 border border-neutral-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
>
{Object.entries(GALLERY_THEME_PRESETS).map(([key, preset]) => (
<option key={key} value={key}>
{preset.name}
</option>
))}
<option value="custom">{t('branding.customTheme')}</option>
</select>
<Button
variant="outline"
size="sm"
leftIcon={<Settings className="w-4 h-4" />}
onClick={() => setShowThemeCustomizer(true)}
className="w-full"
>
{t('branding.customizeTheme')}
</Button>
</div>
) : (
<div className="space-y-4">
<div className="flex items-center justify-between">
<span className="text-sm text-neutral-600">{t('branding.customizingTheme')}</span>
<Button
variant="ghost"
size="sm"
onClick={() => setShowThemeCustomizer(false)}
>
{t('common.hide')}
</Button>
</div>
<ThemeCustomizerEnhanced
value={currentTheme || GALLERY_THEME_PRESETS.default.config}
onChange={setCurrentTheme}
presetName={currentPresetName}
onPresetChange={(presetName) => {
setCurrentPresetName(presetName);
if (presetName !== 'custom') {
setEditForm(prev => ({ ...prev, color_theme: presetName }));
}
}}
isPreviewMode={false}
showGalleryLayouts={true}
/>
</div>
)}
</div>
{/* Hero Photo Selection */}
<HeroPhotoSelector
photos={photos || []}
@@ -822,28 +723,44 @@ export const EventDetailsPage: React.FC = () => {
</div>
</Card>
{/* Gallery Theme */}
<Card padding="md">
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-semibold text-neutral-900">{t('events.galleryTheme')}</h2>
{!event.is_archived && (
<Button
variant="outline"
size="sm"
leftIcon={<Palette className="w-4 h-4" />}
onClick={() => setShowThemeEditorModal(true)}
>
{t('events.customizeTheme')}
</Button>
)}
</div>
<ThemeDisplay
theme={event.color_theme || GALLERY_THEME_PRESETS.default.config}
presetName={event.color_theme && !event.color_theme.startsWith('{') ? event.color_theme : undefined}
showDetails={true}
/>
</Card>
{/* Theme & Style */}
{isEditing && !event.is_archived && (
<Card padding="md">
<h2 className="text-lg font-semibold text-neutral-900 mb-4">{t('branding.themeAndStyle')}</h2>
<ThemeCustomizerEnhanced
value={currentTheme || GALLERY_THEME_PRESETS.default.config}
onChange={(theme) => {
setCurrentTheme(theme);
setEditForm(prev => ({ ...prev, color_theme: JSON.stringify(theme) }));
}}
presetName={currentPresetName}
onPresetChange={(presetName) => {
setCurrentPresetName(presetName);
if (presetName !== 'custom') {
const preset = GALLERY_THEME_PRESETS[presetName];
if (preset) {
setCurrentTheme(preset.config);
setEditForm(prev => ({ ...prev, color_theme: presetName }));
}
}
}}
isPreviewMode={false}
showGalleryLayouts={true}
/>
</Card>
)}
{/* Theme Display (when not editing) */}
{!isEditing && !event.is_archived && (
<Card padding="md">
<h2 className="text-lg font-semibold text-neutral-900 mb-4">{t('events.galleryTheme')}</h2>
<ThemeDisplay
theme={event.color_theme || GALLERY_THEME_PRESETS.default.config}
presetName={event.color_theme && !event.color_theme.startsWith('{') ? event.color_theme : undefined}
showDetails={true}
/>
</Card>
)}
{/* Archive Status */}
{event.is_archived ? (
@@ -995,16 +912,6 @@ export const EventDetailsPage: React.FC = () => {
/>
)}
{/* Theme Editor Modal */}
{showThemeEditorModal && (
<ThemeEditorModal
isOpen={showThemeEditorModal}
onClose={() => setShowThemeEditorModal(false)}
onSave={handleThemeModalSave}
currentTheme={event.color_theme || 'default'}
eventName={event.event_name}
/>
)}
</div>
);
};