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>
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
import type { APIRoute } from 'astro';
|
|
import { territoryManagerAPI } from '../../../../lib/territory-manager-api';
|
|
|
|
export const GET: APIRoute = async ({ request, url }) => {
|
|
try {
|
|
// Check admin permissions
|
|
// This would be implemented with proper auth middleware
|
|
// For now, we'll assume the user is authenticated and has admin role
|
|
|
|
const searchParams = url.searchParams;
|
|
const page = parseInt(searchParams.get('page') || '1');
|
|
const limit = parseInt(searchParams.get('limit') || '10');
|
|
const status = searchParams.get('status');
|
|
const territory = searchParams.get('territory');
|
|
const date = searchParams.get('date');
|
|
const search = searchParams.get('search');
|
|
|
|
// Get applications from database
|
|
let applications = await territoryManagerAPI.getApplications(status || undefined);
|
|
|
|
// Filter by territory if specified
|
|
if (territory) {
|
|
applications = applications.filter(app => app.desired_territory === territory);
|
|
}
|
|
|
|
// Filter by date if specified
|
|
if (date) {
|
|
const now = new Date();
|
|
let cutoffDate: Date;
|
|
|
|
switch (date) {
|
|
case 'today': {
|
|
cutoffDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
break;
|
|
}
|
|
case 'week': {
|
|
cutoffDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
break;
|
|
}
|
|
case 'month': {
|
|
cutoffDate = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
break;
|
|
}
|
|
case 'quarter': {
|
|
const quarterStart = Math.floor(now.getMonth() / 3) * 3;
|
|
cutoffDate = new Date(now.getFullYear(), quarterStart, 1);
|
|
break;
|
|
}
|
|
default: {
|
|
cutoffDate = new Date(0);
|
|
}
|
|
}
|
|
|
|
applications = applications.filter(app => new Date(app.created_at) >= cutoffDate);
|
|
}
|
|
|
|
// Filter by search term if specified
|
|
if (search) {
|
|
const searchTerm = search.toLowerCase();
|
|
applications = applications.filter(app =>
|
|
app.full_name.toLowerCase().includes(searchTerm) ||
|
|
app.email.toLowerCase().includes(searchTerm)
|
|
);
|
|
}
|
|
|
|
// Calculate pagination
|
|
const total = applications.length;
|
|
const startIndex = (page - 1) * limit;
|
|
const endIndex = startIndex + limit;
|
|
const paginatedApplications = applications.slice(startIndex, endIndex);
|
|
|
|
return new Response(JSON.stringify({
|
|
applications: paginatedApplications,
|
|
total,
|
|
page,
|
|
limit,
|
|
totalPages: Math.ceil(total / limit)
|
|
}), {
|
|
status: 200,
|
|
headers: { 'Content-Type': 'application/json' }
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Error fetching applications:', error);
|
|
return new Response(JSON.stringify({ error: 'Internal server error' }), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' }
|
|
});
|
|
}
|
|
}; |