feat: Complete platform enhancement with multi-tenant architecture
Major additions: - Territory manager system with application workflow - Custom pricing and page builder with Craft.js - Enhanced Stripe Connect onboarding - CodeReadr QR scanning integration - Kiosk mode for venue sales - Super admin dashboard and analytics - MCP integration for AI-powered operations Infrastructure improvements: - Centralized API client and routing system - Enhanced authentication with organization context - Comprehensive theme management system - Advanced event management with custom tabs - Performance monitoring and accessibility features Database schema updates: - Territory management tables - Custom pages and pricing structures - Kiosk PIN system - Enhanced organization profiles - CodeReadr integration tables 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,8 @@ import Layout from '../layouts/Layout.astro';
|
||||
import { supabase } from '../lib/supabase';
|
||||
|
||||
// Check authentication
|
||||
const { data: { session } } = await Astro.request.headers.get('cookie')
|
||||
const cookieHeader = Astro.request.headers.get('cookie');
|
||||
const { data: { session } } = cookieHeader
|
||||
? await supabase.auth.getSession()
|
||||
: { data: { session: null } };
|
||||
|
||||
@@ -40,7 +41,7 @@ const { data: inventoryPools } = await supabase
|
||||
)
|
||||
)
|
||||
`)
|
||||
.eq('organization_id', userProfile.organization_id);
|
||||
.eq('organization_id', userProfile?.organization_id || '');
|
||||
---
|
||||
|
||||
<Layout title="Inventory Pools - Black Canyon Tickets">
|
||||
@@ -133,7 +134,7 @@ const { data: inventoryPools } = await supabase
|
||||
</div>
|
||||
<div class="bg-gray-50 rounded-lg p-4">
|
||||
<div class="text-sm font-medium text-gray-500">Available</div>
|
||||
<div class="text-2xl font-semibold text-green-600">{pool.total_capacity - pool.allocated_capacity}</div>
|
||||
<div class="text-2xl font-semibold text-green-600">{pool.total_capacity - (pool.allocated_capacity || 0)}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -238,13 +239,13 @@ const { data: inventoryPools } = await supabase
|
||||
|
||||
// Show modal
|
||||
function showCreateModal() {
|
||||
createPoolModal.classList.remove('hidden');
|
||||
createPoolModal?.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Hide modal
|
||||
function hideCreateModal() {
|
||||
createPoolModal.classList.add('hidden');
|
||||
createPoolForm.reset();
|
||||
createPoolModal?.classList.add('hidden');
|
||||
(createPoolForm as HTMLFormElement)?.reset();
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
@@ -263,18 +264,18 @@ const { data: inventoryPools } = await supabase
|
||||
createPoolForm?.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(createPoolForm);
|
||||
const formData = new FormData(createPoolForm as HTMLFormElement);
|
||||
const poolData = {
|
||||
name: formData.get('name'),
|
||||
description: formData.get('description') || null,
|
||||
total_capacity: parseInt(formData.get('total_capacity')),
|
||||
organization_id: window.userOrgId // This would be set from the server-side data
|
||||
total_capacity: parseInt(formData.get('total_capacity') as string),
|
||||
organization_id: (window as any).userOrgId // This would be set from the server-side data
|
||||
};
|
||||
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('inventory_pools')
|
||||
.insert(poolData)
|
||||
.insert(poolData as any)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
@@ -289,5 +290,5 @@ const { data: inventoryPools } = await supabase
|
||||
});
|
||||
|
||||
// Store organization ID for form submission
|
||||
window.userOrgId = '{userProfile?.organization_id}';
|
||||
(window as any).userOrgId = '{userProfile?.organization_id}';
|
||||
</script>
|
||||
Reference in New Issue
Block a user