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:
2025-07-12 18:21:40 -06:00
parent a02d64a86c
commit 26a87d0d00
232 changed files with 33175 additions and 5365 deletions

View File

@@ -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>