feat: Modularize event management system - 98.7% reduction in main file size
BREAKING CHANGES: - Refactored monolithic manage.astro (7,623 lines) into modular architecture - Original file backed up as manage-old.astro NEW ARCHITECTURE: ✅ 5 Utility Libraries: - event-management.ts: Event data operations & formatting - ticket-management.ts: Ticket CRUD operations & sales data - seating-management.ts: Seating map management & layout generation - sales-analytics.ts: Sales metrics, reporting & data export - marketing-kit.ts: Marketing asset generation & social media ✅ 5 Shared Components: - TicketTypeModal.tsx: Reusable ticket type creation/editing - SeatingMapModal.tsx: Advanced seating map editor with drag-and-drop - EmbedCodeModal.tsx: Widget embedding with customization - OrdersTable.tsx: Comprehensive orders table with sorting/pagination - AttendeesTable.tsx: Attendee management with export capabilities ✅ 11 Tab Components: - TicketsTab.tsx: Ticket management with card/list views - VenueTab.tsx: Seating map management & venue configuration - OrdersTab.tsx: Sales data & order management - AttendeesTab.tsx: Attendee check-in & management - PresaleTab.tsx: Presale code generation & tracking - DiscountTab.tsx: Discount code management - AddonsTab.tsx: Add-on product management - PrintedTab.tsx: Printed ticket barcode management - SettingsTab.tsx: Event configuration & custom fields - MarketingTab.tsx: Marketing kit with social media templates - PromotionsTab.tsx: Campaign & promotion management ✅ 4 Infrastructure Components: - TabNavigation.tsx: Responsive tab navigation system - EventManagement.tsx: Main orchestration component - EventHeader.astro: Event information header - QuickStats.astro: Statistics dashboard BENEFITS: - 98.7% reduction in main file size (7,623 → ~100 lines) - Dramatic improvement in maintainability and team collaboration - Component-level testing now possible - Reusable components across multiple features - Lazy loading support for better performance - Full TypeScript support with proper interfaces - Separation of concerns: business logic separated from UI 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,15 @@ import Navigation from '../../components/Navigation.astro';
|
||||
<h2 class="text-2xl font-light text-white mb-6">Event Details</h2>
|
||||
|
||||
<div class="space-y-6">
|
||||
<!-- Event Image Upload -->
|
||||
<div>
|
||||
<h3 class="text-lg font-medium text-white mb-4">Event Image</h3>
|
||||
<div id="image-upload-container"></div>
|
||||
<p class="text-sm text-white/60 mt-2">
|
||||
Upload a horizontal image. Recommended: 1200×628px. Crop to fit.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="title" class="block text-sm font-semibold text-white/90 mb-2">Event Title</label>
|
||||
<input
|
||||
@@ -289,6 +298,9 @@ import Navigation from '../../components/Navigation.astro';
|
||||
|
||||
<script>
|
||||
import { supabase } from '../../lib/supabase';
|
||||
import { createElement } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import ImageUploadCropper from '../../components/ImageUploadCropper.tsx';
|
||||
|
||||
const eventForm = document.getElementById('event-form') as HTMLFormElement;
|
||||
const errorMessage = document.getElementById('error-message') as HTMLDivElement;
|
||||
@@ -298,6 +310,7 @@ import Navigation from '../../components/Navigation.astro';
|
||||
|
||||
let currentOrganizationId = null;
|
||||
let selectedAddons = [];
|
||||
let eventImageUrl = null;
|
||||
|
||||
// Check authentication
|
||||
async function checkAuth() {
|
||||
@@ -471,7 +484,8 @@ import Navigation from '../../components/Navigation.astro';
|
||||
description,
|
||||
created_by: user.id,
|
||||
organization_id: organizationId,
|
||||
seating_type: seatingType
|
||||
seating_type: seatingType,
|
||||
image_url: eventImageUrl
|
||||
}
|
||||
])
|
||||
.select()
|
||||
@@ -513,11 +527,25 @@ import Navigation from '../../components/Navigation.astro';
|
||||
radio.addEventListener('change', handleVenueOptionChange);
|
||||
});
|
||||
|
||||
// Initialize Image Upload Component
|
||||
function initializeImageUpload() {
|
||||
const container = document.getElementById('image-upload-container');
|
||||
if (container) {
|
||||
const root = createRoot(container);
|
||||
root.render(createElement(ImageUploadCropper, {
|
||||
onImageChange: (imageUrl) => {
|
||||
eventImageUrl = imageUrl;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize
|
||||
checkAuth().then(session => {
|
||||
if (session && currentOrganizationId) {
|
||||
loadVenues();
|
||||
}
|
||||
handleVenueOptionChange(); // Set initial state
|
||||
initializeImageUpload(); // Initialize image upload
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user