"use client" import { useState, useEffect } from 'react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Input } from '@/components/ui/input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' import { Search, Settings, RefreshCw, AlertCircle, Zap, Globe, BarChart3, Code, ShoppingCart, Briefcase, GraduationCap, Plus, Save, X } from 'lucide-react' import { adminApi, formatDate, getComplexityColor } from '@/lib/api/admin' import { BACKEND_URL } from '@/config/backend' import { AdminTemplate, AdminStats } from '@/types/admin.types' import { AdminFeatureSelection } from './admin-feature-selection' interface AdminTemplatesListProps { onTemplateSelect?: (template: AdminTemplate) => void } export function AdminTemplatesList({ onTemplateSelect }: AdminTemplatesListProps) { const [templates, setTemplates] = useState([]) const [stats, setStats] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [searchQuery, setSearchQuery] = useState('') const [categoryFilter, setCategoryFilter] = useState('all') const [showFeaturesManager, setShowFeaturesManager] = useState(false) const [selectedTemplate, setSelectedTemplate] = useState(null) const [showFeatureSelection, setShowFeatureSelection] = useState(false) const [showCreateModal, setShowCreateModal] = useState(false) // Create template form state const [newTemplate, setNewTemplate] = useState({ type: '', title: '', description: '', category: '', icon: '', gradient: '', border: '', text: '', subtext: '' }) const categories = [ "Food Delivery", "E-commerce", "SaaS Platform", "Mobile App", "Dashboard", "CRM System", "Learning Platform", "Healthcare", "Real Estate", "Travel", "Entertainment", "Finance", "Social Media", "Marketplace", "Other" ] // Load templates and stats const loadData = async () => { try { setLoading(true) setError(null) console.log('Loading admin templates data...') const [templatesResponse, statsResponse] = await Promise.all([ adminApi.getAdminTemplates(50, 0, categoryFilter, searchQuery), adminApi.getAdminTemplateStats() ]) console.log('Admin templates response:', templatesResponse) console.log('Admin template stats response:', statsResponse) setTemplates(templatesResponse || []) setStats(statsResponse) } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load admin templates') console.error('Error loading admin templates:', err) } finally { setLoading(false) } } useEffect(() => { loadData() }, [categoryFilter, searchQuery]) // Handle template selection for features const handleManageFeatures = (template: AdminTemplate) => { // Convert AdminTemplate to Template format for feature management const templateForFeatures = { id: template.id, title: template.title, description: template.description, type: template.type, category: template.category, icon: template.icon, gradient: template.gradient, border: template.border, text: template.text, subtext: template.subtext } setSelectedTemplate(templateForFeatures) setShowFeatureSelection(true) } // Handle create template form submission const handleCreateTemplate = async (e: React.FormEvent) => { e.preventDefault() try { setLoading(true) // Create template payload const templateData = { ...newTemplate, created_at: new Date().toISOString(), updated_at: new Date().toISOString() } // Call API to create template (you'll need to implement this endpoint) const response = await fetch(`${BACKEND_URL}/api/templates`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(templateData) }) if (!response.ok) { throw new Error('Failed to create template') } // Reset form and hide it setNewTemplate({ type: '', title: '', description: '', category: '', icon: '', gradient: '', border: '', text: '', subtext: '' }) setShowCreateModal(false) // Reload data to show new template await loadData() } catch (error) { console.error('Error creating template:', error) setError(error instanceof Error ? error.message : 'Failed to create template') } finally { setLoading(false) } } // Get category icon const getCategoryIcon = (category: string) => { switch (category.toLowerCase()) { case 'food delivery': return ShoppingCart case 'e-commerce': case 'ecommerce': return ShoppingCart case 'saas platform': return Code case 'mobile app': return Code case 'dashboard': return BarChart3 case 'crm system': return Briefcase case 'learning platform': return GraduationCap case 'healthcare': return AlertCircle case 'real estate': return Globe case 'travel': return Globe case 'entertainment': return Zap case 'finance': return BarChart3 case 'social media': return Zap case 'marketplace': return ShoppingCart default: return Globe } } // Get category stats for filters const getCategoryStats = () => { // Start with "All Templates" const categoryStats = [ { id: 'all', name: 'All Templates', count: templates.length, icon: Globe } ] // Add categories based on your actual categories array categories.forEach(category => { if (category !== 'Other') { // Skip 'Other' as it will be handled separately categoryStats.push({ id: category.toLowerCase().replace(/\s+/g, '-'), name: category, count: 0, icon: getCategoryIcon(category) }) } }) // Add 'Other' category at the end categoryStats.push({ id: 'other', name: 'Other', count: 0, icon: Globe }) // Count templates by category templates.forEach(template => { const templateCategory = template.category if (templateCategory) { const categoryItem = categoryStats.find(cat => cat.name.toLowerCase() === templateCategory.toLowerCase() || cat.id === templateCategory.toLowerCase().replace(/\s+/g, '-') ) if (categoryItem) { categoryItem.count++ } else { // If category doesn't match any predefined category, add to 'Other' const otherCategory = categoryStats.find(cat => cat.id === 'other') if (otherCategory) { otherCategory.count++ } } } }) return categoryStats } // Filter templates based on search and category const filteredTemplates = templates.filter(template => { const matchesSearch = !searchQuery || template.title?.toLowerCase().includes(searchQuery.toLowerCase()) || template.description?.toLowerCase().includes(searchQuery.toLowerCase()) || template.type?.toLowerCase().includes(searchQuery.toLowerCase()) const matchesCategory = categoryFilter === 'all' || template.category?.toLowerCase() === categoryFilter.toLowerCase() || template.category?.toLowerCase().replace(/\s+/g, '-') === categoryFilter || (categoryFilter === 'other' && !categories.some(cat => cat.toLowerCase() === template.category?.toLowerCase() )) return matchesSearch && matchesCategory }) const TemplateCard = ({ template }: { template: AdminTemplate }) => (
{template.title}
{template.type} {template.category}
{template.description && (

{template.description}

)}
{(template as any).feature_count || 0} features
{template.created_at && formatDate(template.created_at)}
{template.gradient && (
Style: {template.gradient}
)}
) if (loading) { return (
Loading admin templates...
) } if (error) { return (
Error loading admin templates

{error}

) } // Show feature selection view if a template is selected if (showFeatureSelection && selectedTemplate) { return ( { setShowFeatureSelection(false) setSelectedTemplate(null) }} /> ) } return (
{/* Header */}

Admin Templates

Manage features for your templates

{/* Stats Cards */} {stats && (
Total Templates
{(stats as any).total_templates || templates.length}
Categories
{(stats as any).total_categories || categories.length - 1}
Avg Features
{Math.round((stats as any).avg_features_per_template || 0)}
With Features
{(stats as any).templates_with_features || 0}
)} {/* Filters */}
setSearchQuery(e.target.value)} className="pl-10 bg-white/5 border-white/10 text-white" />
{/* Category Filters removed; using only dropdown above */} {/* Create Template Modal */} Create New Template
setNewTemplate(prev => ({ ...prev, type: e.target.value }))} className="bg-white/5 border-white/10 text-white placeholder:text-white/40" required />

Unique identifier for the template

setNewTemplate(prev => ({ ...prev, title: e.target.value }))} className="bg-white/5 border-white/10 text-white placeholder:text-white/40" required />