Asistent AI

Structură aplicație asistată de AI

Descrie aplicația, iar AI va crea structura JSON pentru tine

Folosește AI pentru generare inteligentă de structură
Creează pagini, tabele și câmpuri
Respectă bune practici pentru modelarea datelor

La zi

{
  "components": [
    {
      "slug": "navbar",
      "component_name": "Navigation Bar",
      "component_description": "Navbar pentru navigarea între paginile aplicației",
      "component_code": "<nav class=\"bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 sticky top-0 z-50\">\n  <div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n    <div class=\"flex items-center justify-between h-16\">\n      <div class=\"flex items-center gap-2 cursor-pointer\" onclick=\"navigateTo('dashboard')\">\n        <svg class=\"w-7 h-7 text-blue-600 dark:text-blue-400\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/></svg>\n        <span class=\"text-lg font-bold text-gray-900 dark:text-gray-100\">Biblioteca</span>\n      </div>\n      <div class=\"hidden md:flex items-center gap-1\" id=\"nav-links-desktop\"></div>\n      <button onclick=\"toggleMobileMenu()\" class=\"md:hidden p-2 rounded-lg text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors cursor-pointer border-none bg-transparent\" id=\"mobile-menu-btn\">\n        <svg class=\"w-6 h-6\" id=\"menu-icon\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4 6h16M4 12h16M4 18h16\"/></svg>\n        <svg class=\"w-6 h-6 hidden\" id=\"close-icon\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"/></svg>\n      </button>\n    </div>\n  </div>\n  <div class=\"md:hidden hidden border-t border-gray-200 dark:border-gray-700\" id=\"mobile-menu\">\n    <div class=\"px-4 py-3 space-y-1\" id=\"nav-links-mobile\"></div>\n  </div>\n</nav>",
      "component_script": "function navigateTo(slug) {\n  sdk.navigate(slug);\n}\n\nconst navLinks = [\n  { slug: 'dashboard', label: 'Dashboard', icon: '<svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1\"/></svg>' },\n  { slug: 'books', label: 'Cărți', icon: '<svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/></svg>' },\n  { slug: 'add-book', label: 'Adaugă carte', icon: '<svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"/></svg>' }\n];\n\nfunction getCurrentPageSlug() {\n  const path = window.location.pathname;\n  const parts = path.split('/');\n  return parts[parts.length - 1] || 'dashboard';\n}\n\nfunction renderNavLinks() {\n  const currentSlug = getCurrentPageSlug();\n  const desktopContainer = document.getElementById('nav-links-desktop');\n  const mobileContainer = document.getElementById('nav-links-mobile');\n  if (!desktopContainer || !mobileContainer) return;\n\n  desktopContainer.innerHTML = navLinks.map(link => {\n    const isActive = currentSlug === link.slug;\n    const activeClasses = 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-semibold';\n    const inactiveClasses = 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-gray-200';\n    return `<button onclick=\"navigateTo('${link.slug}')\" class=\"inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors cursor-pointer border-none bg-transparent ${isActive ? activeClasses : inactiveClasses}\">${link.icon}<span>${link.label}</span></button>`;\n  }).join('');\n\n  mobileContainer.innerHTML = navLinks.map(link => {\n    const isActive = currentSlug === link.slug;\n    const activeClasses = 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-semibold';\n    const inactiveClasses = 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700';\n    return `<button onclick=\"navigateTo('${link.slug}'); closeMobileMenu();\" class=\"w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-colors cursor-pointer border-none bg-transparent text-left ${isActive ? activeClasses : inactiveClasses}\">${link.icon}<span>${link.label}</span></button>`;\n  }).join('');\n}\n\nfunction toggleMobileMenu() {\n  const menu = document.getElementById('mobile-menu');\n  const menuIcon = document.getElementById('menu-icon');\n  const closeIcon = document.getElementById('close-icon');\n  const isOpen = !menu.classList.contains('hidden');\n  if (isOpen) {\n    menu.classList.add('hidden');\n    menuIcon.classList.remove('hidden');\n    closeIcon.classList.add('hidden');\n  } else {\n    menu.classList.remove('hidden');\n    menuIcon.classList.add('hidden');\n    closeIcon.classList.remove('hidden');\n  }\n}\n\nfunction closeMobileMenu() {\n  const menu = document.getElementById('mobile-menu');\n  const menuIcon = document.getElementById('menu-icon');\n  const closeIcon = document.getElementById('close-icon');\n  menu.classList.add('hidden');\n  menuIcon.classList.remove('hidden');\n  closeIcon.classList.add('hidden');\n}\n\nrenderNavLinks();"
    },
    {
      "slug": "page-layout",
      "component_name": "Page Layout",
      "component_description": "Layout wrapper cu padding și max-width pentru conținutul paginilor",
      "component_code": "<div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-8 bg-gray-50 dark:bg-gray-900 min-h-[calc(100vh-4rem)]\">\n  <div data-slot=\"content\"></div>\n</div>"
    },
    {
      "slug": "stats-cards",
      "component_name": "Stats Cards",
      "component_description": "Carduri cu statistici generale despre lecturi",
      "component_code": "<div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-10\" id=\"stats-cards\"></div>",
      "component_script": "async function loadStats() {\n  try {\n    const books = await sdk.getRecords('books');\n    const totalBooks = books.length;\n    const totalPages = books.reduce((sum, b) => sum + (b['page-count'] || 0), 0);\n    const avgRating = totalBooks > 0 ? (books.reduce((sum, b) => sum + (b.rating || 0), 0) / totalBooks).toFixed(1) : '0.0';\n    const thisYear = new Date().getFullYear();\n    const booksThisYear = books.filter(b => b['date-read'] && new Date(b['date-read']).getFullYear() === thisYear).length;\n\n    const stats = [\n      { label: 'Cărți citite', value: totalBooks, icon: '<svg class=\"w-8 h-8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/></svg>', color: 'bg-blue-50 dark:bg-blue-900/30 border-blue-200 dark:border-blue-800 text-blue-700 dark:text-blue-300' },\n      { label: 'Pagini citite', value: totalPages, icon: '<svg class=\"w-8 h-8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z\"/></svg>', color: 'bg-emerald-50 dark:bg-emerald-900/30 border-emerald-200 dark:border-emerald-800 text-emerald-700 dark:text-emerald-300' },\n      { label: 'Rating mediu', value: avgRating, icon: '<svg class=\"w-8 h-8\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"/></svg>', color: 'bg-amber-50 dark:bg-amber-900/30 border-amber-200 dark:border-amber-800 text-amber-700 dark:text-amber-300' },\n      { label: 'Cărți anul acesta', value: booksThisYear, icon: '<svg class=\"w-8 h-8\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"/></svg>', color: 'bg-rose-50 dark:bg-rose-900/30 border-rose-200 dark:border-rose-800 text-rose-700 dark:text-rose-300' }\n    ];\n\n    document.getElementById('stats-cards').innerHTML = stats.map(s => `\n      <div class=\"rounded-xl border p-6 ${s.color} transition-shadow duration-200 hover:shadow-lg\">\n        <div class=\"flex items-center justify-between gap-4\">\n          <div class=\"min-w-0\">\n            <p class=\"text-sm font-medium opacity-80 mb-2\">${s.label}</p>\n            <p class=\"text-3xl font-bold tracking-tight\">${s.value}</p>\n          </div>\n          <span class=\"flex-shrink-0 opacity-70\">${s.icon}</span>\n        </div>\n      </div>\n    `).join('');\n  } catch (error) {\n    console.error('Eroare la încărcarea statisticilor:', error);\n  }\n}\n\nloadStats();\nsdk.on('books:changed', loadStats);"
    },
    {
      "slug": "recent-books",
      "component_name": "Recent Books",
      "component_description": "Lista ultimelor cărți adăugate",
      "component_code": "<div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-8\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-semibold text-gray-900 dark:text-gray-100\">Cărți recente</h2>\n    <button onclick=\"navigateToBooks()\" class=\"text-sm text-blue-600 dark:text-blue-400 hover:underline cursor-pointer bg-transparent border-none p-0\">Vezi toate →</button>\n  </div>\n  <div id=\"recent-books-list\" class=\"space-y-4\">\n    <p class=\"text-gray-500 dark:text-gray-400 text-sm py-4\">Se încarcă...</p>\n  </div>\n</div>",
      "component_script": "function navigateToBooks() {\n  sdk.navigate('books');\n}\n\nasync function loadRecentBooks() {\n  try {\n    const books = await sdk.getRecords('books', {}, { sort: '-createdAt', limit: 5 });\n    const container = document.getElementById('recent-books-list');\n    if (books.length === 0) {\n      container.innerHTML = '<p class=\"text-gray-500 dark:text-gray-400 text-sm py-4\">Nu ai adăugat nicio carte încă.</p>';\n      return;\n    }\n    container.innerHTML = books.map(b => {\n      const stars = '⭐'.repeat(b.rating || 0);\n      return `\n        <div class=\"flex items-center justify-between p-4 rounded-lg bg-gray-50 dark:bg-gray-700/50 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors cursor-pointer\" onclick=\"viewRecentBook('${b.id}')\">\n          <div class=\"flex-1 min-w-0 pr-4\">\n            <p class=\"font-medium text-gray-900 dark:text-gray-100 truncate mb-1\">${b.title || 'Fără titlu'}</p>\n            <p class=\"text-sm text-gray-500 dark:text-gray-400 truncate\">${b.author || 'Autor necunoscut'}</p>\n          </div>\n          <div class=\"ml-4 text-sm flex-shrink-0\">${stars || '<span class=\\'text-gray-400 dark:text-gray-500\\'>–</span>'}</div>\n        </div>\n      `;\n    }).join('');\n  } catch (error) {\n    console.error('Eroare la încărcarea cărților recente:', error);\n  }\n}\n\nfunction viewRecentBook(id) {\n  sdk.navigate('book-detail', { recordId: id });\n}\n\nloadRecentBooks();\nsdk.on('books:changed', loadRecentBooks);"
    },
    {
      "slug": "genre-chart",
      "component_name": "Genre Chart",
      "component_description": "Distribuția cărților pe genuri",
      "component_code": "<div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-8\">\n  <h2 class=\"text-xl font-semibold text-gray-900 dark:text-gray-100 mb-6\">Distribuție pe genuri</h2>\n  <div id=\"genre-chart\" class=\"space-y-5\">\n    <p class=\"text-gray-500 dark:text-gray-400 text-sm py-4\">Se încarcă...</p>\n  </div>\n</div>",
      "component_script": "async function loadGenreChart() {\n  try {\n    const books = await sdk.getRecords('books');\n    const container = document.getElementById('genre-chart');\n    if (books.length === 0) {\n      container.innerHTML = '<p class=\"text-gray-500 dark:text-gray-400 text-sm py-4\">Nu ai adăugat nicio carte încă.</p>';\n      return;\n    }\n    const genreCount = {};\n    books.forEach(b => {\n      const genre = b.genre || 'Neclasificat';\n      genreCount[genre] = (genreCount[genre] || 0) + 1;\n    });\n    const sorted = Object.entries(genreCount).sort((a, b) => b[1] - a[1]);\n    const max = sorted[0][1];\n    const colors = ['bg-blue-500', 'bg-emerald-500', 'bg-amber-500', 'bg-rose-500', 'bg-purple-500', 'bg-cyan-500', 'bg-orange-500', 'bg-teal-500'];\n    container.innerHTML = sorted.map(([genre, count], i) => {\n      const pct = Math.round((count / max) * 100);\n      const color = colors[i % colors.length];\n      return `\n        <div>\n          <div class=\"flex justify-between text-sm mb-2\">\n            <span class=\"text-gray-700 dark:text-gray-300 font-medium\">${genre}</span>\n            <span class=\"text-gray-500 dark:text-gray-400 ml-4\">${count} ${count === 1 ? 'carte' : 'cărți'}</span>\n          </div>\n          <div class=\"w-full bg-gray-200 dark:bg-gray-700 rounded-full h-3\">\n            <div class=\"${color} h-3 rounded-full transition-all duration-500\" style=\"width: ${pct}%\"></div>\n          </div>\n        </div>\n      `;\n    }).join('');\n  } catch (error) {\n    console.error('Eroare la încărcarea chart-ului:', error);\n  }\n}\n\nloadGenreChart();\nsdk.on('books:changed', loadGenreChart);"
    },
    {
      "slug": "books-content",
      "component_name": "Books Page Layout",
      "component_description": "Layout complet cu titlu, panou lateral de filtre și grid de cărți",
      "component_code": "<div>\n  <!-- Page Header -->\n  <div class=\"flex items-center justify-between mb-6\">\n    <h1 class=\"text-2xl sm:text-3xl font-bold text-gray-900 dark:text-gray-100\">Cărți</h1>\n    <button onclick=\"goToAddBook()\" class=\"inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white font-medium transition-colors whitespace-nowrap cursor-pointer border-none\">\n      <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4v16m8-8H4\"/></svg>\n      Adaugă carte\n    </button>\n  </div>\n\n  <!-- Mobile Filter Toggle -->\n  <div class=\"lg:hidden mb-4\">\n    <button onclick=\"toggleFilters()\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300 flex items-center justify-between cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors\">\n      <span class=\"flex items-center gap-2\">\n        <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"/></svg>\n        Filtre\n        <span id=\"active-filters-badge\" class=\"hidden ml-1 px-1.5 py-0.5 text-xs font-bold rounded-full bg-blue-100 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300\"></span>\n      </span>\n      <svg id=\"filter-chevron\" class=\"w-4 h-4 text-gray-400 transition-transform duration-200\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19 9l-7 7-7-7\"/></svg>\n    </button>\n  </div>\n\n  <!-- Main Layout -->\n  <div class=\"flex flex-col lg:flex-row gap-6\">\n    <!-- Sidebar -->\n    <aside id=\"filters-sidebar\" class=\"hidden lg:block w-full lg:w-72 lg:flex-shrink-0\">\n      <div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-5 lg:sticky lg:top-6\">\n        <div class=\"flex items-center justify-between mb-5\">\n          <h3 class=\"font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2\">\n            <svg class=\"w-4 h-4 text-gray-400\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"/></svg>\n            Filtre\n          </h3>\n          <button onclick=\"resetFilters()\" id=\"reset-btn\" class=\"text-xs text-blue-600 dark:text-blue-400 hover:underline cursor-pointer bg-transparent border-none p-0 hidden\">Resetează</button>\n        </div>\n\n        <!-- Search -->\n        <div class=\"mb-5\">\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Căutare</label>\n          <div class=\"relative\">\n            <svg class=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"/></svg>\n            <input type=\"text\" id=\"search-input\" placeholder=\"Titlu sau autor...\" class=\"w-full pl-10 pr-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" oninput=\"filterBooks()\">\n          </div>\n        </div>\n\n        <!-- Genre Filter -->\n        <div class=\"mb-5\">\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Gen</label>\n          <select id=\"genre-filter\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 outline-none focus:ring-2 focus:ring-blue-500\" onchange=\"filterBooks()\">\n            <option value=\"\">Toate genurile</option>\n          </select>\n        </div>\n\n        <!-- Rating Filter -->\n        <div class=\"mb-5\">\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Rating minim</label>\n          <select id=\"rating-filter\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 outline-none focus:ring-2 focus:ring-blue-500\" onchange=\"filterBooks()\">\n            <option value=\"\">Orice rating</option>\n            <option value=\"5\">⭐⭐⭐⭐⭐</option>\n            <option value=\"4\">⭐⭐⭐⭐+</option>\n            <option value=\"3\">⭐⭐⭐+</option>\n            <option value=\"2\">⭐⭐+</option>\n            <option value=\"1\">⭐+</option>\n          </select>\n        </div>\n\n        <!-- Active filters info -->\n        <div id=\"filter-info\" class=\"hidden pt-4 border-t border-gray-100 dark:border-gray-700\">\n          <p class=\"text-xs text-gray-500 dark:text-gray-400\" id=\"filter-info-text\"></p>\n        </div>\n      </div>\n    </aside>\n\n    <!-- Main Content -->\n    <main class=\"flex-1 min-w-0\">\n      <div class=\"flex items-center justify-between mb-4\">\n        <p id=\"books-count\" class=\"text-sm text-gray-500 dark:text-gray-400\"></p>\n      </div>\n      <div id=\"books-grid\" class=\"grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-5\">\n        <div class=\"col-span-full flex flex-col items-center justify-center py-16\">\n          <svg class=\"w-12 h-12 text-gray-300 dark:text-gray-600 mb-3 animate-pulse\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/></svg>\n          <p class=\"text-gray-400 dark:text-gray-500 text-sm\">Se încarcă cărțile...</p>\n        </div>\n      </div>\n    </main>\n  </div>\n</div>",
      "component_script": "let allBooks = [];\n\nconst genreColors = {\n  'Ficțiune': { bg: 'bg-violet-100 dark:bg-violet-900/40', text: 'text-violet-700 dark:text-violet-300', border: 'border-l-violet-500 dark:border-l-violet-400', accent: 'bg-violet-500' },\n  'Non-ficțiune': { bg: 'bg-cyan-100 dark:bg-cyan-900/40', text: 'text-cyan-700 dark:text-cyan-300', border: 'border-l-cyan-500 dark:border-l-cyan-400', accent: 'bg-cyan-500' },\n  'Science Fiction': { bg: 'bg-indigo-100 dark:bg-indigo-900/40', text: 'text-indigo-700 dark:text-indigo-300', border: 'border-l-indigo-500 dark:border-l-indigo-400', accent: 'bg-indigo-500' },\n  'Fantasy': { bg: 'bg-purple-100 dark:bg-purple-900/40', text: 'text-purple-700 dark:text-purple-300', border: 'border-l-purple-500 dark:border-l-purple-400', accent: 'bg-purple-500' },\n  'Thriller': { bg: 'bg-red-100 dark:bg-red-900/40', text: 'text-red-700 dark:text-red-300', border: 'border-l-red-500 dark:border-l-red-400', accent: 'bg-red-500' },\n  'Mister': { bg: 'bg-slate-100 dark:bg-slate-900/40', text: 'text-slate-700 dark:text-slate-300', border: 'border-l-slate-500 dark:border-l-slate-400', accent: 'bg-slate-500' },\n  'Romance': { bg: 'bg-pink-100 dark:bg-pink-900/40', text: 'text-pink-700 dark:text-pink-300', border: 'border-l-pink-500 dark:border-l-pink-400', accent: 'bg-pink-500' },\n  'Istorie': { bg: 'bg-amber-100 dark:bg-amber-900/40', text: 'text-amber-700 dark:text-amber-300', border: 'border-l-amber-500 dark:border-l-amber-400', accent: 'bg-amber-500' },\n  'Biografie': { bg: 'bg-teal-100 dark:bg-teal-900/40', text: 'text-teal-700 dark:text-teal-300', border: 'border-l-teal-500 dark:border-l-teal-400', accent: 'bg-teal-500' },\n  'Dezvoltare personală': { bg: 'bg-emerald-100 dark:bg-emerald-900/40', text: 'text-emerald-700 dark:text-emerald-300', border: 'border-l-emerald-500 dark:border-l-emerald-400', accent: 'bg-emerald-500' },\n  'Filozofie': { bg: 'bg-gray-100 dark:bg-gray-900/40', text: 'text-gray-700 dark:text-gray-300', border: 'border-l-gray-500 dark:border-l-gray-400', accent: 'bg-gray-500' },\n  'Poezie': { bg: 'bg-fuchsia-100 dark:bg-fuchsia-900/40', text: 'text-fuchsia-700 dark:text-fuchsia-300', border: 'border-l-fuchsia-500 dark:border-l-fuchsia-400', accent: 'bg-fuchsia-500' },\n  'Clasic': { bg: 'bg-yellow-100 dark:bg-yellow-900/40', text: 'text-yellow-700 dark:text-yellow-300', border: 'border-l-yellow-500 dark:border-l-yellow-400', accent: 'bg-yellow-500' }\n};\nconst defaultGenreColor = { bg: 'bg-blue-100 dark:bg-blue-900/40', text: 'text-blue-700 dark:text-blue-300', border: 'border-l-blue-500 dark:border-l-blue-400', accent: 'bg-blue-500' };\n\nfunction getGenreColor(genre) {\n  return genreColors[genre] || defaultGenreColor;\n}\n\nfunction goToAddBook() {\n  sdk.navigate('add-book');\n}\n\nfunction viewBook(id) {\n  sdk.navigate('book-detail', { recordId: id });\n}\n\nfunction editBook(id) {\n  sdk.navigate('edit-book', { recordId: id });\n}\n\nfunction toggleFilters() {\n  const sidebar = document.getElementById('filters-sidebar');\n  const chevron = document.getElementById('filter-chevron');\n  sidebar.classList.toggle('hidden');\n  if (!sidebar.classList.contains('hidden')) {\n    chevron.style.transform = 'rotate(180deg)';\n  } else {\n    chevron.style.transform = '';\n  }\n}\n\nfunction updateFilterUI() {\n  const search = document.getElementById('search-input').value;\n  const genre = document.getElementById('genre-filter').value;\n  const rating = document.getElementById('rating-filter').value;\n  const resetBtn = document.getElementById('reset-btn');\n  const badge = document.getElementById('active-filters-badge');\n  const filterInfo = document.getElementById('filter-info');\n  const filterInfoText = document.getElementById('filter-info-text');\n\n  let activeCount = 0;\n  if (search) activeCount++;\n  if (genre) activeCount++;\n  if (rating) activeCount++;\n\n  if (activeCount > 0) {\n    resetBtn.classList.remove('hidden');\n    badge.classList.remove('hidden');\n    badge.textContent = activeCount;\n    filterInfo.classList.remove('hidden');\n    const parts = [];\n    if (search) parts.push('„' + search + '\"');\n    if (genre) parts.push(genre);\n    if (rating) parts.push('rating ≥ ' + rating);\n    filterInfoText.textContent = 'Filtre active: ' + parts.join(', ');\n  } else {\n    resetBtn.classList.add('hidden');\n    badge.classList.add('hidden');\n    filterInfo.classList.add('hidden');\n  }\n}\n\nfunction resetFilters() {\n  document.getElementById('search-input').value = '';\n  document.getElementById('genre-filter').value = '';\n  document.getElementById('rating-filter').value = '';\n  filterBooks();\n}\n\nasync function loadGenres() {\n  try {\n    const books = await sdk.getRecords('books');\n    const genres = [...new Set(books.map(b => b.genre).filter(Boolean))].sort();\n    const select = document.getElementById('genre-filter');\n    select.innerHTML = '<option value=\"\">Toate genurile</option>' + genres.map(g => `<option value=\"${g}\">${g}</option>`).join('');\n  } catch (error) {\n    console.error(error);\n  }\n}\n\nasync function loadBooks() {\n  try {\n    allBooks = await sdk.getRecords('books');\n    loadGenres();\n    renderBooks(allBooks);\n    updateCount(allBooks.length, allBooks.length);\n  } catch (error) {\n    console.error('Eroare la încărcarea cărților:', error);\n  }\n}\n\nfunction updateCount(filtered, total) {\n  const el = document.getElementById('books-count');\n  if (filtered === total) {\n    el.textContent = total + (total === 1 ? ' carte' : ' cărți');\n  } else {\n    el.textContent = filtered + ' din ' + total + (total === 1 ? ' carte' : ' cărți');\n  }\n}\n\nfunction filterBooks() {\n  const search = document.getElementById('search-input').value.toLowerCase();\n  const genre = document.getElementById('genre-filter').value;\n  const ratingMin = parseInt(document.getElementById('rating-filter').value) || 0;\n\n  const filtered = allBooks.filter(b => {\n    const matchSearch = !search || (b.title || '').toLowerCase().includes(search) || (b.author || '').toLowerCase().includes(search);\n    const matchGenre = !genre || b.genre === genre;\n    const matchRating = (b.rating || 0) >= ratingMin;\n    return matchSearch && matchGenre && matchRating;\n  });\n  renderBooks(filtered);\n  updateCount(filtered.length, allBooks.length);\n  updateFilterUI();\n}\n\nfunction renderBooks(books) {\n  const container = document.getElementById('books-grid');\n  if (!container) return;\n  if (books.length === 0) {\n    container.innerHTML = '<div class=\"col-span-full flex flex-col items-center justify-center py-16\"><svg class=\"w-16 h-16 text-gray-300 dark:text-gray-600 mb-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/></svg><p class=\"text-gray-500 dark:text-gray-400 text-lg font-medium\">Nu s-au găsit cărți</p><p class=\"text-gray-400 dark:text-gray-500 text-sm mt-1\">Încearcă să modifici filtrele sau adaugă o carte nouă</p></div>';\n    return;\n  }\n  container.innerHTML = books.map(b => {\n    const gc = getGenreColor(b.genre);\n    const starsFilled = b.rating ? '<span class=\"text-amber-400\">' + '★'.repeat(b.rating) + '</span>' : '';\n    const starsEmpty = b.rating ? '<span class=\"text-gray-300 dark:text-gray-600\">' + '☆'.repeat(5 - b.rating) + '</span>' : '<span class=\"text-gray-300 dark:text-gray-600\">☆☆☆☆☆</span>';\n    const dateStr = b['date-read'] ? new Date(b['date-read']).toLocaleDateString('ro-RO', { day: 'numeric', month: 'short', year: 'numeric' }) : '';\n    const initials = (b.title || '?').substring(0, 2).toUpperCase();\n    return `\n      <div class=\"group relative bg-white dark:bg-gray-800 rounded-2xl border border-gray-200 dark:border-gray-700 border-l-4 ${gc.border} overflow-hidden hover:shadow-xl dark:hover:shadow-gray-900/50 hover:-translate-y-1 transition-all duration-300\">\n        <div class=\"p-5 pb-4\">\n          <div class=\"flex items-start gap-4\">\n            <div class=\"flex-shrink-0 w-12 h-16 rounded-lg ${gc.accent} flex items-center justify-center text-white font-bold text-sm shadow-md\">\n              ${initials}\n            </div>\n            <div class=\"flex-1 min-w-0\">\n              <h3 class=\"font-bold text-gray-900 dark:text-gray-100 text-base leading-tight mb-0.5 line-clamp-2\">${b.title || 'Fără titlu'}</h3>\n              <p class=\"text-gray-500 dark:text-gray-400 text-sm\">de ${b.author || 'Autor necunoscut'}</p>\n            </div>\n          </div>\n        </div>\n        <div class=\"px-5 pb-3\">\n          <div class=\"flex items-center gap-2 mb-3 flex-wrap\">\n            <span class=\"inline-block px-2.5 py-0.5 rounded-full text-xs font-semibold ${gc.bg} ${gc.text}\">${b.genre || 'Neclasificat'}</span>\n            <span class=\"text-sm tracking-wide\">${starsFilled}${starsEmpty}</span>\n          </div>\n          ${b.notes ? `<p class=\"text-gray-500 dark:text-gray-400 text-sm line-clamp-2 leading-relaxed mb-3\">${b.notes}</p>` : ''}\n        </div>\n        <div class=\"px-5 py-3 bg-gray-50 dark:bg-gray-750 border-t border-gray-100 dark:border-gray-700 flex items-center justify-between\">\n          <div class=\"flex items-center gap-3 text-xs text-gray-400 dark:text-gray-500\">\n            ${b['page-count'] ? `<span class=\"flex items-center gap-1\"><svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z\"/></svg>${b['page-count']} pag</span>` : ''}\n            ${dateStr ? `<span class=\"flex items-center gap-1\"><svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"/></svg>${dateStr}</span>` : ''}\n          </div>\n          <div class=\"flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n            <button onclick=\"viewBook('${b.id}')\" class=\"p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-400 hover:text-emerald-600 dark:hover:text-emerald-400 transition-colors\" title=\"Previzualizare\">\n              <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z\"/></svg>\n            </button>\n            <button onclick=\"editBook('${b.id}')\" class=\"p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors\" title=\"Editează\">\n              <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"/></svg>\n            </button>\n            <button onclick=\"deleteBook('${b.id}')\" class=\"p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-400 hover:text-red-500 dark:hover:text-red-400 transition-colors\" title=\"Șterge\">\n              <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"/></svg>\n            </button>\n          </div>\n        </div>\n      </div>\n    `;\n  }).join('');\n}\n\nasync function deleteBook(id) {\n  if (!confirm('Sigur vrei să ștergi această carte?')) return;\n  try {\n    await sdk.deleteRecord('books', id);\n    sdk.emit('books:changed');\n    loadBooks();\n  } catch (error) {\n    console.error('Eroare la ștergere:', error);\n  }\n}\n\nloadBooks();\nsdk.on('books:changed', loadBooks);"
    },
    {
      "slug": "add-book-form",
      "component_name": "Add Book Form",
      "component_description": "Formularul complet pentru adăugarea unei cărți noi",
      "component_code": "<div class=\"max-w-2xl mx-auto\">\n  <div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 sm:p-8\">\n    <div class=\"flex items-center justify-between mb-6\">\n      <h1 class=\"text-2xl font-bold text-gray-900 dark:text-gray-100\">Adaugă o carte</h1>\n      <button onclick=\"goToBooksList()\" class=\"text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition-colors cursor-pointer bg-transparent border-none p-0\">← Înapoi la listă</button>\n    </div>\n    <form id=\"add-book-form\" onsubmit=\"handleAddBook(event)\" class=\"space-y-5\">\n      <div>\n        <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Titlu *</label>\n        <input type=\"text\" id=\"book-title\" required class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" placeholder=\"Introdu titlul cărții\">\n      </div>\n      <div>\n        <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Autor *</label>\n        <input type=\"text\" id=\"book-author\" required class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" placeholder=\"Introdu autorul\">\n      </div>\n      <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Gen</label>\n          <select id=\"book-genre\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 outline-none focus:ring-2 focus:ring-blue-500\">\n            <option value=\"\">Selectează genul</option>\n            <option value=\"Ficțiune\">Ficțiune</option>\n            <option value=\"Non-ficțiune\">Non-ficțiune</option>\n            <option value=\"Science Fiction\">Science Fiction</option>\n            <option value=\"Fantasy\">Fantasy</option>\n            <option value=\"Thriller\">Thriller</option>\n            <option value=\"Mister\">Mister</option>\n            <option value=\"Romance\">Romance</option>\n            <option value=\"Istorie\">Istorie</option>\n            <option value=\"Biografie\">Biografie</option>\n            <option value=\"Dezvoltare personală\">Dezvoltare personală</option>\n            <option value=\"Filozofie\">Filozofie</option>\n            <option value=\"Poezie\">Poezie</option>\n            <option value=\"Clasic\">Clasic</option>\n            <option value=\"Altele\">Altele</option>\n          </select>\n        </div>\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Număr pagini</label>\n          <input type=\"number\" id=\"book-pages\" min=\"1\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" placeholder=\"300\">\n        </div>\n      </div>\n      <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Data citirii</label>\n          <input type=\"date\" id=\"book-date\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\">\n        </div>\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Rating</label>\n          <div id=\"star-rating\" class=\"flex gap-1 mt-2\">\n            <button type=\"button\" onclick=\"setRating(1)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors star-btn\">★</button>\n            <button type=\"button\" onclick=\"setRating(2)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors star-btn\">★</button>\n            <button type=\"button\" onclick=\"setRating(3)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors star-btn\">★</button>\n            <button type=\"button\" onclick=\"setRating(4)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors star-btn\">★</button>\n            <button type=\"button\" onclick=\"setRating(5)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors star-btn\">★</button>\n          </div>\n          <input type=\"hidden\" id=\"book-rating\" value=\"0\">\n        </div>\n      </div>\n      <div>\n        <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Notițe</label>\n        <textarea id=\"book-notes\" rows=\"4\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none resize-y\" placeholder=\"Scrie o scurtă recenzie sau notițe despre carte...\"></textarea>\n      </div>\n      <div class=\"flex gap-3 pt-2\">\n        <button type=\"submit\" id=\"submit-btn\" class=\"flex-1 px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white font-semibold transition-colors cursor-pointer\">Salvează cartea</button>\n        <button type=\"button\" onclick=\"goToBooksList()\" class=\"px-6 py-3 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 font-medium transition-colors cursor-pointer\">Anulează</button>\n      </div>\n      <div id=\"form-message\" class=\"hidden text-center text-sm py-2 rounded-lg\"></div>\n    </form>\n  </div>\n</div>",
      "component_script": "let currentRating = 0;\n\nfunction goToBooksList() {\n  sdk.navigate('books');\n}\n\nfunction setRating(value) {\n  currentRating = value;\n  document.getElementById('book-rating').value = value;\n  const buttons = document.querySelectorAll('.star-btn');\n  buttons.forEach((btn, i) => {\n    if (i < value) {\n      btn.classList.remove('text-gray-300', 'dark:text-gray-600');\n      btn.classList.add('text-amber-400');\n    } else {\n      btn.classList.remove('text-amber-400');\n      btn.classList.add('text-gray-300', 'dark:text-gray-600');\n    }\n  });\n}\n\nasync function handleAddBook(event) {\n  event.preventDefault();\n  const btn = document.getElementById('submit-btn');\n  const msg = document.getElementById('form-message');\n\n  const values = {\n    title: document.getElementById('book-title').value.trim(),\n    author: document.getElementById('book-author').value.trim(),\n    genre: document.getElementById('book-genre').value,\n    'page-count': parseInt(document.getElementById('book-pages').value) || 0,\n    'date-read': document.getElementById('book-date').value || null,\n    rating: parseInt(document.getElementById('book-rating').value) || 0,\n    notes: document.getElementById('book-notes').value.trim()\n  };\n\n  btn.disabled = true;\n  btn.textContent = 'Se salvează...';\n\n  try {\n    await sdk.createRecord('books', values);\n    msg.className = 'text-center text-sm py-2 rounded-lg bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300';\n    msg.textContent = 'Cartea a fost adăugată cu succes!';\n    msg.classList.remove('hidden');\n    sdk.emit('books:changed');\n    setTimeout(() => { sdk.navigate('books'); }, 1000);\n  } catch (error) {\n    msg.className = 'text-center text-sm py-2 rounded-lg bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-300';\n    msg.textContent = 'A apărut o eroare. Încearcă din nou.';\n    msg.classList.remove('hidden');\n    btn.disabled = false;\n    btn.textContent = 'Salvează cartea';\n    console.error(error);\n  }\n}"
    },
    {
      "slug": "edit-book-form",
      "component_name": "Edit Book Form",
      "component_description": "Formularul pentru editarea unei cărți existente cu date precompletate",
      "component_code": "<div class=\"max-w-2xl mx-auto\">\n  <div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 sm:p-8\">\n    <div class=\"flex items-center justify-between mb-6\">\n      <h1 class=\"text-2xl font-bold text-gray-900 dark:text-gray-100\">Editează cartea</h1>\n      <button onclick=\"goBackToBooks()\" class=\"text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition-colors cursor-pointer bg-transparent border-none p-0\">← Înapoi la listă</button>\n    </div>\n    <form id=\"edit-book-form\" onsubmit=\"handleEditBook(event)\" class=\"space-y-5\">\n      <input type=\"hidden\" id=\"edit-book-id\">\n      <div>\n        <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Titlu *</label>\n        <input type=\"text\" id=\"edit-title\" required class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" placeholder=\"Introdu titlul cărții\">\n      </div>\n      <div>\n        <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Autor *</label>\n        <input type=\"text\" id=\"edit-author\" required class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" placeholder=\"Introdu autorul\">\n      </div>\n      <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Gen</label>\n          <select id=\"edit-genre\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 outline-none focus:ring-2 focus:ring-blue-500\">\n            <option value=\"\">Selectează genul</option>\n            <option value=\"Ficțiune\">Ficțiune</option>\n            <option value=\"Non-ficțiune\">Non-ficțiune</option>\n            <option value=\"Science Fiction\">Science Fiction</option>\n            <option value=\"Fantasy\">Fantasy</option>\n            <option value=\"Thriller\">Thriller</option>\n            <option value=\"Mister\">Mister</option>\n            <option value=\"Romance\">Romance</option>\n            <option value=\"Istorie\">Istorie</option>\n            <option value=\"Biografie\">Biografie</option>\n            <option value=\"Dezvoltare personală\">Dezvoltare personală</option>\n            <option value=\"Filozofie\">Filozofie</option>\n            <option value=\"Poezie\">Poezie</option>\n            <option value=\"Clasic\">Clasic</option>\n            <option value=\"Altele\">Altele</option>\n          </select>\n        </div>\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Număr pagini</label>\n          <input type=\"number\" id=\"edit-pages\" min=\"1\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\" placeholder=\"300\">\n        </div>\n      </div>\n      <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Data citirii</label>\n          <input type=\"date\" id=\"edit-date\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none\">\n        </div>\n        <div>\n          <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Rating</label>\n          <div id=\"edit-star-rating\" class=\"flex gap-1 mt-2\">\n            <button type=\"button\" onclick=\"setEditRating(1)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors edit-star-btn\">★</button>\n            <button type=\"button\" onclick=\"setEditRating(2)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors edit-star-btn\">★</button>\n            <button type=\"button\" onclick=\"setEditRating(3)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors edit-star-btn\">★</button>\n            <button type=\"button\" onclick=\"setEditRating(4)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors edit-star-btn\">★</button>\n            <button type=\"button\" onclick=\"setEditRating(5)\" class=\"text-3xl text-gray-300 dark:text-gray-600 hover:text-amber-400 dark:hover:text-amber-400 transition-colors edit-star-btn\">★</button>\n          </div>\n          <input type=\"hidden\" id=\"edit-rating\" value=\"0\">\n        </div>\n      </div>\n      <div>\n        <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5\">Notițe</label>\n        <textarea id=\"edit-notes\" rows=\"4\" class=\"w-full px-4 py-2.5 rounded-lg bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none resize-y\" placeholder=\"Scrie o scurtă recenzie sau notițe despre carte...\"></textarea>\n      </div>\n      <div class=\"flex gap-3 pt-2\">\n        <button type=\"submit\" id=\"edit-submit-btn\" class=\"flex-1 px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white font-semibold transition-colors cursor-pointer\">Salvează modificările</button>\n        <button type=\"button\" onclick=\"goBackToBooks()\" class=\"px-6 py-3 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 font-medium transition-colors cursor-pointer\">Anulează</button>\n      </div>\n      <div id=\"edit-form-message\" class=\"hidden text-center text-sm py-2 rounded-lg\"></div>\n    </form>\n  </div>\n</div>",
      "component_script": "let editRating = 0;\n\nfunction goBackToBooks() {\n  sdk.navigate('books');\n}\n\nfunction setEditRating(value) {\n  editRating = value;\n  document.getElementById('edit-rating').value = value;\n  const buttons = document.querySelectorAll('.edit-star-btn');\n  buttons.forEach((btn, i) => {\n    if (i < value) {\n      btn.classList.remove('text-gray-300', 'dark:text-gray-600');\n      btn.classList.add('text-amber-400');\n    } else {\n      btn.classList.remove('text-amber-400');\n      btn.classList.add('text-gray-300', 'dark:text-gray-600');\n    }\n  });\n}\n\nasync function loadBookForEdit() {\n  const bookId = sdk.getRecordIdFromUrl();\n  if (!bookId) {\n    sdk.navigate('books');\n    return;\n  }\n  try {\n    const book = await sdk.getRecord('books', bookId);\n    document.getElementById('edit-book-id').value = book.id;\n    document.getElementById('edit-title').value = book.title || '';\n    document.getElementById('edit-author').value = book.author || '';\n    document.getElementById('edit-genre').value = book.genre || '';\n    document.getElementById('edit-pages').value = book['page-count'] || '';\n    document.getElementById('edit-date').value = book['date-read'] ? book['date-read'].split('T')[0] : '';\n    document.getElementById('edit-notes').value = book.notes || '';\n    if (book.rating) {\n      setEditRating(book.rating);\n    }\n  } catch (error) {\n    console.error('Eroare la încărcarea cărții:', error);\n    sdk.navigate('books');\n  }\n}\n\nasync function handleEditBook(event) {\n  event.preventDefault();\n  const btn = document.getElementById('edit-submit-btn');\n  const msg = document.getElementById('edit-form-message');\n  const bookId = document.getElementById('edit-book-id').value;\n\n  const values = {\n    title: document.getElementById('edit-title').value.trim(),\n    author: document.getElementById('edit-author').value.trim(),\n    genre: document.getElementById('edit-genre').value,\n    'page-count': parseInt(document.getElementById('edit-pages').value) || 0,\n    'date-read': document.getElementById('edit-date').value || null,\n    rating: parseInt(document.getElementById('edit-rating').value) || 0,\n    notes: document.getElementById('edit-notes').value.trim()\n  };\n\n  btn.disabled = true;\n  btn.textContent = 'Se salvează...';\n\n  try {\n    await sdk.updateRecord('books', bookId, values);\n    msg.className = 'text-center text-sm py-2 rounded-lg bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300';\n    msg.textContent = 'Cartea a fost actualizată cu succes!';\n    msg.classList.remove('hidden');\n    sdk.emit('books:changed');\n    setTimeout(() => { sdk.navigate('books'); }, 1000);\n  } catch (error) {\n    msg.className = 'text-center text-sm py-2 rounded-lg bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-300';\n    msg.textContent = 'A apărut o eroare. Încearcă din nou.';\n    msg.classList.remove('hidden');\n    btn.disabled = false;\n    btn.textContent = 'Salvează modificările';\n    console.error(error);\n  }\n}\n\nloadBookForEdit();"
    },
    {
      "slug": "book-detail-view",
      "component_name": "Book Detail View",
      "component_description": "Vizualizarea completă a detaliilor unei cărți cu acțiuni",
      "component_code": "<div id=\"book-detail-container\" class=\"max-w-3xl mx-auto\">\n  <div class=\"flex items-center justify-center py-20\">\n    <svg class=\"w-10 h-10 text-gray-300 dark:text-gray-600 animate-pulse\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253\"/></svg>\n  </div>\n</div>",
      "component_script": "const detailGenreColors = {\n  'Ficțiune': { bg: 'bg-violet-100 dark:bg-violet-900/40', text: 'text-violet-700 dark:text-violet-300', accent: 'bg-violet-500' },\n  'Non-ficțiune': { bg: 'bg-cyan-100 dark:bg-cyan-900/40', text: 'text-cyan-700 dark:text-cyan-300', accent: 'bg-cyan-500' },\n  'Science Fiction': { bg: 'bg-indigo-100 dark:bg-indigo-900/40', text: 'text-indigo-700 dark:text-indigo-300', accent: 'bg-indigo-500' },\n  'Fantasy': { bg: 'bg-purple-100 dark:bg-purple-900/40', text: 'text-purple-700 dark:text-purple-300', accent: 'bg-purple-500' },\n  'Thriller': { bg: 'bg-red-100 dark:bg-red-900/40', text: 'text-red-700 dark:text-red-300', accent: 'bg-red-500' },\n  'Mister': { bg: 'bg-slate-100 dark:bg-slate-900/40', text: 'text-slate-700 dark:text-slate-300', accent: 'bg-slate-500' },\n  'Romance': { bg: 'bg-pink-100 dark:bg-pink-900/40', text: 'text-pink-700 dark:text-pink-300', accent: 'bg-pink-500' },\n  'Istorie': { bg: 'bg-amber-100 dark:bg-amber-900/40', text: 'text-amber-700 dark:text-amber-300', accent: 'bg-amber-500' },\n  'Biografie': { bg: 'bg-teal-100 dark:bg-teal-900/40', text: 'text-teal-700 dark:text-teal-300', accent: 'bg-teal-500' },\n  'Dezvoltare personală': { bg: 'bg-emerald-100 dark:bg-emerald-900/40', text: 'text-emerald-700 dark:text-emerald-300', accent: 'bg-emerald-500' },\n  'Filozofie': { bg: 'bg-gray-100 dark:bg-gray-900/40', text: 'text-gray-700 dark:text-gray-300', accent: 'bg-gray-500' },\n  'Poezie': { bg: 'bg-fuchsia-100 dark:bg-fuchsia-900/40', text: 'text-fuchsia-700 dark:text-fuchsia-300', accent: 'bg-fuchsia-500' },\n  'Clasic': { bg: 'bg-yellow-100 dark:bg-yellow-900/40', text: 'text-yellow-700 dark:text-yellow-300', accent: 'bg-yellow-500' }\n};\nconst detailDefaultColor = { bg: 'bg-blue-100 dark:bg-blue-900/40', text: 'text-blue-700 dark:text-blue-300', accent: 'bg-blue-500' };\n\nfunction getDetailGenreColor(genre) {\n  return detailGenreColors[genre] || detailDefaultColor;\n}\n\nfunction goBackToBooks() {\n  sdk.navigate('books');\n}\n\nfunction goToEditBook(id) {\n  sdk.navigate('edit-book', { recordId: id });\n}\n\nasync function deleteBookFromDetail(id) {\n  if (!confirm('Sigur vrei să ștergi această carte? Acțiunea este ireversibilă.')) return;\n  try {\n    await sdk.deleteRecord('books', id);\n    sdk.emit('books:changed');\n    sdk.navigate('books');\n  } catch (error) {\n    console.error('Eroare la ștergere:', error);\n  }\n}\n\nasync function loadBookDetail() {\n  const bookId = sdk.getRecordIdFromUrl();\n  if (!bookId) {\n    sdk.navigate('books');\n    return;\n  }\n\n  try {\n    const book = await sdk.getRecord('books', bookId);\n    const container = document.getElementById('book-detail-container');\n    const gc = getDetailGenreColor(book.genre);\n    const initials = (book.title || '?').substring(0, 2).toUpperCase();\n\n    const starsFilled = book.rating ? '<span class=\"text-amber-400 text-2xl\">' + '★'.repeat(book.rating) + '</span>' : '';\n    const starsEmpty = book.rating ? '<span class=\"text-gray-300 dark:text-gray-600 text-2xl\">' + '☆'.repeat(5 - book.rating) + '</span>' : '<span class=\"text-gray-300 dark:text-gray-600 text-2xl\">☆☆☆☆☆</span>';\n\n    const dateStr = book['date-read'] ? new Date(book['date-read']).toLocaleDateString('ro-RO', { day: 'numeric', month: 'long', year: 'numeric' }) : '';\n    const createdStr = book.createdAt ? new Date(book.createdAt).toLocaleDateString('ro-RO', { day: 'numeric', month: 'long', year: 'numeric' }) : '';\n    const editedStr = book.editedAt ? new Date(book.editedAt).toLocaleDateString('ro-RO', { day: 'numeric', month: 'long', year: 'numeric' }) : '';\n\n    container.innerHTML = `\n      <div class=\"mb-6\">\n        <button onclick=\"goBackToBooks()\" class=\"inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition-colors cursor-pointer bg-transparent border-none p-0\">\n          <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\"/></svg>\n          Înapoi la listă\n        </button>\n      </div>\n\n      <div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-2xl overflow-hidden shadow-sm\">\n        <!-- Header -->\n        <div class=\"p-6 sm:p-8 border-b border-gray-100 dark:border-gray-700\">\n          <div class=\"flex items-start gap-5\">\n            <div class=\"flex-shrink-0 w-20 h-28 rounded-xl ${gc.accent} flex items-center justify-center text-white font-bold text-xl shadow-lg\">\n              ${initials}\n            </div>\n            <div class=\"flex-1 min-w-0\">\n              <h1 class=\"text-2xl sm:text-3xl font-bold text-gray-900 dark:text-gray-100 leading-tight mb-2\">${book.title || 'Fără titlu'}</h1>\n              <p class=\"text-lg text-gray-500 dark:text-gray-400 mb-3\">de ${book.author || 'Autor necunoscut'}</p>\n              <div class=\"flex items-center gap-3 flex-wrap\">\n                ${book.genre ? `<span class=\"inline-block px-3 py-1 rounded-full text-sm font-semibold ${gc.bg} ${gc.text}\">${book.genre}</span>` : ''}\n                <span class=\"tracking-wide\">${starsFilled}${starsEmpty}</span>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <!-- Details Grid -->\n        <div class=\"p-6 sm:p-8 border-b border-gray-100 dark:border-gray-700\">\n          <h2 class=\"text-sm font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mb-4\">Detalii</h2>\n          <div class=\"grid grid-cols-1 sm:grid-cols-3 gap-5\">\n            <div class=\"flex items-center gap-3 p-4 rounded-xl bg-gray-50 dark:bg-gray-700/50\">\n              <div class=\"flex-shrink-0 w-10 h-10 rounded-lg bg-blue-100 dark:bg-blue-900/40 flex items-center justify-center\">\n                <svg class=\"w-5 h-5 text-blue-600 dark:text-blue-400\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z\"/></svg>\n              </div>\n              <div>\n                <p class=\"text-xs text-gray-500 dark:text-gray-400\">Pagini</p>\n                <p class=\"text-lg font-semibold text-gray-900 dark:text-gray-100\">${book['page-count'] ? book['page-count'] + ' pag' : '–'}</p>\n              </div>\n            </div>\n            <div class=\"flex items-center gap-3 p-4 rounded-xl bg-gray-50 dark:bg-gray-700/50\">\n              <div class=\"flex-shrink-0 w-10 h-10 rounded-lg bg-emerald-100 dark:bg-emerald-900/40 flex items-center justify-center\">\n                <svg class=\"w-5 h-5 text-emerald-600 dark:text-emerald-400\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"/></svg>\n              </div>\n              <div>\n                <p class=\"text-xs text-gray-500 dark:text-gray-400\">Data citirii</p>\n                <p class=\"text-lg font-semibold text-gray-900 dark:text-gray-100\">${dateStr || '–'}</p>\n              </div>\n            </div>\n            <div class=\"flex items-center gap-3 p-4 rounded-xl bg-gray-50 dark:bg-gray-700/50\">\n              <div class=\"flex-shrink-0 w-10 h-10 rounded-lg bg-amber-100 dark:bg-amber-900/40 flex items-center justify-center\">\n                <svg class=\"w-5 h-5 text-amber-600 dark:text-amber-400\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"/></svg>\n              </div>\n              <div>\n                <p class=\"text-xs text-gray-500 dark:text-gray-400\">Rating</p>\n                <p class=\"text-lg font-semibold text-gray-900 dark:text-gray-100\">${book.rating ? book.rating + '/5' : '–'}</p>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <!-- Notes -->\n        ${book.notes ? `\n        <div class=\"p-6 sm:p-8 border-b border-gray-100 dark:border-gray-700\">\n          <h2 class=\"text-sm font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mb-4\">Notițe</h2>\n          <div class=\"p-5 rounded-xl bg-gray-50 dark:bg-gray-700/50 border border-gray-100 dark:border-gray-600\">\n            <p class=\"text-gray-700 dark:text-gray-300 leading-relaxed whitespace-pre-wrap\">${book.notes}</p>\n          </div>\n        </div>\n        ` : ''}\n\n        <!-- Metadata -->\n        <div class=\"p-6 sm:p-8 border-b border-gray-100 dark:border-gray-700\">\n          <div class=\"flex items-center gap-6 text-xs text-gray-400 dark:text-gray-500\">\n            ${createdStr ? `<span class=\"flex items-center gap-1.5\"><svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\"/></svg>Adăugat: ${createdStr}</span>` : ''}\n            ${editedStr ? `<span class=\"flex items-center gap-1.5\"><svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"/></svg>Modificat: ${editedStr}</span>` : ''}\n          </div>\n        </div>\n\n        <!-- Actions -->\n        <div class=\"p-6 sm:p-8\">\n          <div class=\"flex flex-col sm:flex-row gap-3\">\n            <button onclick=\"goToEditBook('${book.id}')\" class=\"flex-1 inline-flex items-center justify-center gap-2 px-5 py-3 rounded-xl bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white font-semibold transition-colors cursor-pointer border-none\">\n              <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"/></svg>\n              Editează cartea\n            </button>\n            <button onclick=\"deleteBookFromDetail('${book.id}')\" class=\"inline-flex items-center justify-center gap-2 px-5 py-3 rounded-xl border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/30 font-semibold transition-colors cursor-pointer bg-transparent\">\n              <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"/></svg>\n              Șterge\n            </button>\n          </div>\n        </div>\n      </div>\n    `;\n  } catch (error) {\n    console.error('Eroare la încărcarea detaliilor:', error);\n    const container = document.getElementById('book-detail-container');\n    container.innerHTML = `\n      <div class=\"mb-6\">\n        <button onclick=\"goBackToBooks()\" class=\"inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition-colors cursor-pointer bg-transparent border-none p-0\">\n          <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\"/></svg>\n          Înapoi la listă\n        </button>\n      </div>\n      <div class=\"bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-10 text-center\">\n        <svg class=\"w-16 h-16 text-gray-300 dark:text-gray-600 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z\"/></svg>\n        <p class=\"text-gray-500 dark:text-gray-400 text-lg font-medium mb-2\">Cartea nu a fost găsită</p>\n        <p class=\"text-gray-400 dark:text-gray-500 text-sm\">Este posibil să fi fost ștearsă sau ID-ul este invalid.</p>\n      </div>\n    `;\n  }\n}\n\nloadBookDetail();"
    }
  ],
  "pages": [
    {
      "slug": "dashboard",
      "title": "Dashboard",
      "description": "Pagina principală cu statistici despre cărțile citite",
      "components": [
        "navbar",
        {
          "componentRef": "page-layout",
          "children": [
            {
              "slot": "content",
              "componentRef": "stats-cards"
            },
            {
              "slot": "content",
              "componentRef": "recent-books"
            },
            {
              "slot": "content",
              "componentRef": "genre-chart"
            }
          ]
        }
      ]
    },
    {
      "slug": "books",
      "title": "Cărțile mele",
      "description": "Lista completă a cărților citite cu filtrare și căutare",
      "components": [
        "navbar",
        {
          "componentRef": "page-layout",
          "children": [
            {
              "slot": "content",
              "componentRef": "books-content"
            }
          ]
        }
      ]
    },
    {
      "slug": "add-book",
      "title": "Adaugă carte",
      "description": "Formular pentru adăugarea unei noi cărți",
      "components": [
        "navbar",
        {
          "componentRef": "page-layout",
          "children": [
            {
              "slot": "content",
              "componentRef": "add-book-form"
            }
          ]
        }
      ]
    },
    {
      "slug": "edit-book",
      "title": "Editează carte",
      "description": "Formular pentru editarea unei cărți existente",
      "components": [
        "navbar",
        {
          "componentRef": "page-layout",
          "children": [
            {
              "slot": "content",
              "componentRef": "edit-book-form"
            }
          ]
        }
      ]
    },
    {
      "slug": "book-detail",
      "title": "Detalii carte",
      "description": "Pagina de previzualizare completă a unei cărți",
      "components": [
        "navbar",
        {
          "componentRef": "page-layout",
          "children": [
            {
              "slot": "content",
              "componentRef": "book-detail-view"
            }
          ]
        }
      ]
    }
  ],
  "tables": [
    {
      "slug": "books",
      "name": "Cărți",
      "description": "Tabela cu cărțile citite",
      "fields": [
        {
          "slug": "title",
          "name": "Titlu",
          "type": "String"
        },
        {
          "slug": "author",
          "name": "Autor",
          "type": "String"
        },
        {
          "slug": "genre",
          "name": "Gen",
          "type": "String"
        },
        {
          "slug": "page-count",
          "name": "Număr pagini",
          "type": "Number"
        },
        {
          "slug": "date-read",
          "name": "Data citirii",
          "type": "Date"
        },
        {
          "slug": "rating",
          "name": "Rating",
          "type": "Number"
        },
        {
          "slug": "notes",
          "name": "Notițe",
          "type": "String"
        }
      ]
    }
  ]
}