Files
blackcanyontickets/create-test-data.cjs
dzinesco dbf4b11e81 fix: Implement comprehensive edit event button functionality and resolve authentication issues
Major fixes and improvements:
- Fixed edit event button functionality with proper event handlers and DOM ready state checking
- Added status column to tickets table via Supabase migration to resolve 500 API errors
- Updated stats API to correctly calculate revenue from decimal price values
- Resolved authentication redirect loops by fixing cookie configuration for Docker environment
- Fixed Permissions-Policy header syntax errors
- Added comprehensive debugging and error handling for event management
- Implemented modal-based event editing with form validation and API integration
- Enhanced event data loading with proper error handling and user feedback

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14 18:49:49 -06:00

247 lines
7.8 KiB
JavaScript

const { createClient } = require('@supabase/supabase-js');
require('dotenv').config();
const supabaseUrl = process.env.PUBLIC_SUPABASE_URL;
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!supabaseUrl || !supabaseServiceKey) {
console.error('❌ Missing required environment variables');
process.exit(1);
}
const supabase = createClient(supabaseUrl, supabaseServiceKey, {
auth: {
autoRefreshToken: false,
persistSession: false
}
});
async function createTestData() {
const eventId = '7ac12bd2-8509-4db3-b1bc-98a808646311';
console.log('🎫 Creating test ticket types and data...');
try {
// Step 1: Check if ticket types already exist
const { data: existingTicketTypes, error: checkError } = await supabase
.from('ticket_types')
.select('id, name, price')
.eq('event_id', eventId);
if (checkError) {
console.error('❌ Error checking existing ticket types:', checkError);
return;
}
if (existingTicketTypes && existingTicketTypes.length > 0) {
console.log('✓ Ticket types already exist:', existingTicketTypes.map(t => t.name).join(', '));
} else {
console.log('Creating ticket types...');
// Create ticket types
const ticketTypes = [
{
event_id: eventId,
name: 'General Admission',
description: 'Standard entry to the event',
price: 50.00,
quantity_available: 100,
quantity_sold: 0,
is_active: true,
sort_order: 0
},
{
event_id: eventId,
name: 'VIP',
description: 'VIP access with premium seating',
price: 125.00,
quantity_available: 25,
quantity_sold: 0,
is_active: true,
sort_order: 1
},
{
event_id: eventId,
name: 'Student',
description: 'Discounted tickets for students',
price: 25.00,
quantity_available: 50,
quantity_sold: 0,
is_active: true,
sort_order: 2
}
];
const { data: newTicketTypes, error: createError } = await supabase
.from('ticket_types')
.insert(ticketTypes)
.select();
if (createError) {
console.error('❌ Error creating ticket types:', createError);
return;
}
console.log('✓ Created ticket types:', newTicketTypes.map(t => t.name).join(', '));
}
// Step 2: Check if sample tickets exist
const { data: existingTickets, error: ticketCheckError } = await supabase
.from('tickets')
.select('id, price')
.eq('event_id', eventId);
if (ticketCheckError) {
console.error('❌ Error checking tickets:', ticketCheckError);
return;
}
if (existingTickets && existingTickets.length > 0) {
console.log(`${existingTickets.length} tickets already exist`);
} else {
console.log('Creating sample tickets...');
// Get ticket types to create tickets for
const { data: ticketTypes, error: ttError } = await supabase
.from('ticket_types')
.select('id, name, price')
.eq('event_id', eventId);
if (ttError || !ticketTypes || ticketTypes.length === 0) {
console.error('❌ No ticket types found to create tickets for');
return;
}
// Create some sample sold tickets
const sampleTickets = [];
// 5 general admission tickets
const gaType = ticketTypes.find(t => t.name === 'General Admission');
if (gaType) {
for (let i = 1; i <= 5; i++) {
sampleTickets.push({
event_id: eventId,
ticket_type_id: gaType.id,
price: gaType.price,
purchaser_email: `customer${i}@example.com`,
purchaser_name: `Customer ${i}`,
checked_in: i <= 2, // First 2 are checked in
scanned_at: i <= 2 ? new Date().toISOString() : null,
created_at: new Date(Date.now() - (i * 24 * 60 * 60 * 1000)).toISOString() // Spread over last 5 days
});
}
}
// 2 VIP tickets
const vipType = ticketTypes.find(t => t.name === 'VIP');
if (vipType) {
for (let i = 1; i <= 2; i++) {
sampleTickets.push({
event_id: eventId,
ticket_type_id: vipType.id,
price: vipType.price,
purchaser_email: `vip${i}@example.com`,
purchaser_name: `VIP Customer ${i}`,
checked_in: i === 1, // First VIP is checked in
scanned_at: i === 1 ? new Date().toISOString() : null,
created_at: new Date(Date.now() - (i * 12 * 60 * 60 * 1000)).toISOString() // Recent purchases
});
}
}
// 1 student ticket
const studentType = ticketTypes.find(t => t.name === 'Student');
if (studentType) {
sampleTickets.push({
event_id: eventId,
ticket_type_id: studentType.id,
price: studentType.price,
purchaser_email: 'student1@university.edu',
purchaser_name: 'Student User',
checked_in: false,
scanned_at: null,
created_at: new Date(Date.now() - (6 * 60 * 60 * 1000)).toISOString() // 6 hours ago
});
}
if (sampleTickets.length > 0) {
const { data: newTickets, error: createTicketsError } = await supabase
.from('tickets')
.insert(sampleTickets)
.select();
if (createTicketsError) {
console.error('❌ Error creating sample tickets:', createTicketsError);
return;
}
console.log(`✓ Created ${newTickets.length} sample tickets`);
}
}
// Step 3: Test the stats API by calling it directly
console.log('\n🧪 Testing stats calculation...');
const { data: tickets, error: ticketsError } = await supabase
.from('tickets')
.select(`
id,
ticket_type_id,
price,
checked_in,
scanned_at
`)
.eq('event_id', eventId);
if (ticketsError) {
console.error('❌ Error loading tickets for stats:', ticketsError);
return;
}
const { data: ticketTypes, error: ticketTypesError } = await supabase
.from('ticket_types')
.select('id, quantity_available, price')
.eq('event_id', eventId);
if (ticketTypesError) {
console.error('❌ Error loading ticket types for stats:', ticketTypesError);
return;
}
// Calculate stats manually to verify
const soldTickets = tickets || []; // All tickets in table are considered sold
const checkedInTickets = tickets?.filter(t => t.checked_in || t.scanned_at) || [];
const totalRevenue = soldTickets.reduce((sum, ticket) => {
const priceInDollars = ticket.price || 0;
return sum + Math.round(priceInDollars * 100); // Convert to cents
}, 0);
const totalAvailable = ticketTypes?.reduce((sum, type) => sum + (type.quantity_available || 0), 0) || 0;
const ticketsSold = soldTickets.length;
const ticketsAvailable = totalAvailable - ticketsSold;
const stats = {
totalRevenue,
ticketsSold,
ticketsAvailable,
checkedIn: checkedInTickets.length
};
console.log('✓ Calculated stats:', stats);
console.log('\n🎉 Test data setup complete!');
console.log('=====================================');
console.log(`Event ID: ${eventId}`);
console.log(`Ticket types: ${ticketTypes?.length || 0}`);
console.log(`Total tickets: ${tickets?.length || 0}`);
console.log(`Sold tickets: ${ticketsSold}`);
console.log(`Checked in: ${checkedInTickets.length}`);
console.log(`Total revenue: $${(totalRevenue / 100).toFixed(2)}`);
} catch (error) {
console.error('💥 Unexpected error:', error);
}
}
createTestData();