feat: Integrate content library features, allowing users to save and select blocks within the lesson editor.

This commit is contained in:
2026-02-16 20:52:57 -03:00
parent 9bdbd8ae5a
commit f9bea3c2e0
2 changed files with 65 additions and 4 deletions
@@ -1,7 +1,7 @@
"use client";
import { useEffect, useState } from "react";
import { cmsApi, Lesson, Block, GradingCategory, LibraryBlock, api } from "@/lib/api";
import { cmsApi, Lesson, Block, GradingCategory, LibraryBlock } from "@/lib/api";
import Link from "next/link";
import DescriptionBlock from "@/components/blocks/DescriptionBlock";
import MediaBlock from "@/components/blocks/MediaBlock";
@@ -218,6 +218,39 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
setBlocks(newBlocks);
};
// Content Libraries functions
const handleSaveToLibrary = async (name: string, description: string, tags: string[]) => {
if (!blockToSave) return;
try {
await cmsApi.createLibraryBlock({
name,
description,
block_type: blockToSave.type,
block_data: blockToSave,
tags,
});
alert('¡Bloque guardado en la biblioteca exitosamente!');
} catch (error) {
console.error('Error saving to library:', error);
throw error;
}
};
const handleSelectFromLibrary = (libraryBlock: LibraryBlock) => {
// Create a new block from the library block
const newBlock: Block = {
...libraryBlock.block_data,
id: Math.random().toString(36).substr(2, 9), // New unique ID
};
setBlocks([...blocks, newBlock]);
};
const openSaveToLibraryModal = (block: Block) => {
setBlockToSave(block);
setIsSaveToLibraryModalOpen(true);
};
const handleSummarize = async () => {
if (!lesson) return;
@@ -779,6 +812,15 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
<span className="text-2xl group-hover:scale-110 transition-transform">{isGeneratingQuiz ? '⏳' : '✨'}</span>
<span className="text-[10px] font-black uppercase tracking-widest text-indigo-400">{isGeneratingQuiz ? 'Building...' : 'AI Builder'}</span>
</button>
{/* Browse Library */}
<button
onClick={() => setIsLibraryPanelOpen(true)}
className="flex flex-col items-center gap-2 p-6 bg-gradient-to-b from-emerald-500/20 to-teal-500/20 border border-emerald-500/30 hover:border-emerald-500/60 rounded-3xl transition-all group w-36"
>
<Library className="w-6 h-6 text-emerald-400 group-hover:scale-110 transition-transform" />
<span className="text-[10px] font-black uppercase tracking-widest text-emerald-400">Library</span>
</button>
</div>
</div>
</div>
@@ -854,6 +896,25 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
</div>
</form>
</Modal>
{/* Content Libraries Modals */}
{blockToSave && (
<SaveToLibraryModal
block={blockToSave}
isOpen={isSaveToLibraryModalOpen}
onClose={() => {
setIsSaveToLibraryModalOpen(false);
setBlockToSave(null);
}}
onSave={handleSaveToLibrary}
/>
)}
<LibraryPanel
isOpen={isLibraryPanelOpen}
onClose={() => setIsLibraryPanelOpen(false)}
onSelectBlock={handleSelectFromLibrary}
/>
</div >
);
}
+3 -3
View File
@@ -34,7 +34,7 @@ export default function LibraryPanel({ isOpen, onClose, onSelectBlock }: Library
const loadBlocks = async () => {
setLoading(true);
try {
const data = await api.listLibraryBlocks();
const data = await cmsApi.listLibraryBlocks();
setBlocks(data);
} catch (error) {
console.error('Error loading library blocks:', error);
@@ -68,7 +68,7 @@ export default function LibraryPanel({ isOpen, onClose, onSelectBlock }: Library
const handleUseBlock = async (block: LibraryBlock) => {
try {
// Increment usage counter
await api.incrementBlockUsage(block.id);
await cmsApi.incrementBlockUsage(block.id);
onSelectBlock(block);
onClose();
} catch (error) {
@@ -81,7 +81,7 @@ export default function LibraryPanel({ isOpen, onClose, onSelectBlock }: Library
if (!confirm('¿Estás seguro de eliminar este bloque de la biblioteca?')) return;
try {
await api.deleteLibraryBlock(blockId);
await cmsApi.deleteLibraryBlock(blockId);
setBlocks(blocks.filter(b => b.id !== blockId));
} catch (error) {
console.error('Error deleting block:', error);