bookwiz.io / components / TemplateSelector.tsx
TemplateSelector.tsx
Raw
'use client'

import { useState, useCallback } from 'react'
import { BookTemplate } from '@/lib/types/database'
import { 
  DocumentTextIcon, 
  SparklesIcon,
  BookOpenIcon,
  CheckCircleIcon
} from '@heroicons/react/24/outline'

interface TemplateSelectorProps {
  templates: BookTemplate[]
  selectedTemplateId: string | null
  onTemplateSelect: (templateId: string) => void
  loading?: boolean
}

export default function TemplateSelector({ 
  templates, 
  selectedTemplateId, 
  onTemplateSelect,
  loading = false 
}: TemplateSelectorProps) {
  const getTemplateIcon = useCallback((templateName: string) => {
    if (templateName.toLowerCase().includes('comprehensive')) {
      return SparklesIcon
    } else if (templateName.toLowerCase().includes('minimal')) {
      return DocumentTextIcon
    }
    return BookOpenIcon
  }, [])

  if (loading) {
    return (
      <div className="space-y-3">
        <div className="text-base font-semibold text-slate-300 mb-3">
          Loading Templates...
        </div>
        <div className="space-y-3">
          {[1, 2].map((i) => (
            <div key={i} className="animate-pulse">
              <div className="bg-slate-800/50 rounded-xl border border-slate-600/50 p-4 h-20" />
            </div>
          ))}
        </div>
      </div>
    )
  }

  return (
    <div className="space-y-4">
      <div className="space-y-3">
        {templates.map((template) => {
          const IconComponent = getTemplateIcon(template.name)
          const isSelected = selectedTemplateId === template.id

          return (
            <div
              key={template.id}
              className={`relative cursor-pointer rounded-xl border-2 transition-colors duration-150 ${
                isSelected
                  ? 'border-teal-500 bg-gradient-to-r from-teal-900/30 to-cyan-900/20'
                  : 'border-slate-600/50 bg-slate-800/30 hover:border-slate-500 hover:bg-slate-800/50'
              }`}
              onClick={() => onTemplateSelect(template.id)}
            >
              {/* Selection indicator */}
              {isSelected && (
                <div className="absolute -top-2 -right-2 w-6 h-6 bg-gradient-to-r from-teal-500 to-cyan-500 rounded-full flex items-center justify-center">
                  <CheckCircleIcon className="w-4 h-4 text-white" />
                </div>
              )}

              <div className="p-4">
                <div className="flex items-center space-x-3">
                  <div className={`flex-shrink-0 p-2 rounded-lg transition-colors duration-150 ${
                    isSelected 
                      ? 'bg-gradient-to-r from-teal-600 to-cyan-600' 
                      : 'bg-slate-700/50'
                  }`}>
                    <IconComponent className="h-5 w-5 text-white" />
                  </div>
                  
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center justify-between">
                      <h3 className={`text-base font-bold ${
                        isSelected ? 'text-teal-100' : 'text-white'
                      }`}>
                        {template.name}
                      </h3>
                      {template.is_default && (
                        <span className="inline-flex items-center px-1 py-0.5 rounded-full text-xs font-semibold bg-gradient-to-r from-yellow-500/20 to-orange-500/20 text-yellow-300 border border-yellow-500/30 whitespace-nowrap">
                           Recommended
                        </span>
                      )}
                    </div>
                    
                    {template.description && (
                      <p className="text-sm text-slate-400 mt-1 line-clamp-2 leading-relaxed">
                        {template.description}
                      </p>
                    )}
                  </div>
                </div>
              </div>
            </div>
          )
        })}
      </div>

      {templates.length === 0 && (
        <div className="text-center py-8 bg-slate-800/20 rounded-xl border border-slate-700/50">
          <BookOpenIcon className="h-12 w-12 mx-auto mb-3 text-slate-500" />
          <h3 className="text-sm font-semibold text-slate-400 mb-1">No Templates Available</h3>
          <p className="text-xs text-slate-500">Templates will appear here when available</p>
        </div>
      )}
    </div>
  )
}