refactor: Clean up unused imports, improve type safety, and fix UI text and navigation links.
This commit is contained in:
@@ -162,6 +162,23 @@ El servicio CMS expone una API RESTful en el puerto `3001`. A continuación se d
|
|||||||
- **URL**: `GET /organizations/{id}/branding`
|
- **URL**: `GET /organizations/{id}/branding`
|
||||||
- **Descripción**: Recupera la identidad visual (logo y colores) de una organización.
|
- **Descripción**: Recupera la identidad visual (logo y colores) de una organización.
|
||||||
|
|
||||||
|
### 👥 Gestión de Usuarios (Admin)
|
||||||
|
|
||||||
|
#### Listar Usuarios
|
||||||
|
- **URL**: `GET /users`
|
||||||
|
- **Descripción**: Obtiene todos los usuarios registrados en el sistema.
|
||||||
|
|
||||||
|
#### Actualizar Usuario
|
||||||
|
- **URL**: `PUT /users/{id}`
|
||||||
|
- **Descripción**: Permite cambiar el rol o la organización de un usuario.
|
||||||
|
- **Body (JSON)**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"role": "string",
|
||||||
|
"organization_id": "uuid"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 📦 Configuración y Ejecución
|
## 📦 Configuración y Ejecución
|
||||||
|
|
||||||
1. **Variables de Entorno**:
|
1. **Variables de Entorno**:
|
||||||
|
|||||||
+2
-1
@@ -95,7 +95,8 @@
|
|||||||
- [ ] XP and leveling system
|
- [ ] XP and leveling system
|
||||||
- [x] **Course Management Enhancements**:
|
- [x] **Course Management Enhancements**:
|
||||||
- [x] Manual naming for modules, lessons, and activities during creation.
|
- [x] Manual naming for modules, lessons, and activities during creation.
|
||||||
- [x] Drag-and-drop reordering for modules, lessons, and activities.
|
- [x] Reordering for modules, lessons, and activities (Level up/down).
|
||||||
|
- [x] Deletion of modules and lessons with confirmation.
|
||||||
- [x] **Pacing Control**:
|
- [x] **Pacing Control**:
|
||||||
- [x] Self-paced mode (Evergreen).
|
- [x] Self-paced mode (Evergreen).
|
||||||
- [x] Instructor-led mode (Cohort-based with start/end dates).
|
- [x] Instructor-led mode (Cohort-based with start/end dates).
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { cmsApi, Organization } from '@/lib/api';
|
import { cmsApi, Organization } from '@/lib/api';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
import { Plus, Building2, Globe, Calendar, ExternalLink, ShieldCheck, Palette, Upload, Save, X, Check } from 'lucide-react';
|
import { Plus, Building2, Globe, Calendar, ExternalLink, ShieldCheck, Palette, Upload, Save, X } from 'lucide-react';
|
||||||
|
|
||||||
export default function OrganizationsPage() {
|
export default function OrganizationsPage() {
|
||||||
const [organizations, setOrganizations] = useState<Organization[]>([]);
|
const [organizations, setOrganizations] = useState<Organization[]>([]);
|
||||||
@@ -322,7 +322,7 @@ export default function OrganizationsPage() {
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="w-5 h-5 bg-white/20 rounded flex items-center justify-center overflow-hidden">
|
<div className="w-5 h-5 bg-white/20 rounded flex items-center justify-center overflow-hidden">
|
||||||
{selectedOrg.logo_url ? (
|
{selectedOrg.logo_url ? (
|
||||||
<img src={selectedOrg.logo_url} className="w-full h-full object-contain" />
|
<img src={selectedOrg.logo_url} alt="Logo" className="w-full h-full object-contain" />
|
||||||
) : <div className="w-3 h-3 bg-white" />}
|
) : <div className="w-3 h-3 bg-white" />}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-16 h-2 bg-white/30 rounded" />
|
<div className="w-16 h-2 bg-white/30 rounded" />
|
||||||
@@ -350,7 +350,7 @@ export default function OrganizationsPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-3 rounded-lg bg-blue-500/10 border border-blue-500/20">
|
<div className="p-3 rounded-lg bg-blue-500/10 border border-blue-500/20">
|
||||||
<p className="text-[10px] text-blue-400 leading-relaxed">
|
<p className="text-[10px] text-blue-400 leading-relaxed">
|
||||||
This is a real-time preview of how the brand identity will apply to the student's learning experience.
|
This is a real-time preview of how the brand identity will apply to the student's learning experience.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,13 +16,7 @@ import {
|
|||||||
Pencil,
|
Pencil,
|
||||||
ChevronUp,
|
ChevronUp,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
Trash2,
|
Trash2
|
||||||
PlayCircle,
|
|
||||||
FileText,
|
|
||||||
Calendar,
|
|
||||||
Settings,
|
|
||||||
Layout,
|
|
||||||
CheckCircle2
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
export default function LessonEditor({ params }: { params: { id: string; lessonId: string } }) {
|
export default function LessonEditor({ params }: { params: { id: string; lessonId: string } }) {
|
||||||
@@ -109,7 +103,7 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
max_attempts: maxAttempts,
|
max_attempts: maxAttempts,
|
||||||
allow_retry: allowRetry,
|
allow_retry: allowRetry,
|
||||||
due_date: dueDate ? new Date(dueDate).toISOString() : undefined,
|
due_date: dueDate ? new Date(dueDate).toISOString() : undefined,
|
||||||
important_date_type: (importantDateType || undefined) as any
|
important_date_type: (importantDateType || undefined) as 'exam' | 'assignment' | 'milestone' | 'live-session' | undefined
|
||||||
});
|
});
|
||||||
setLesson(updated);
|
setLesson(updated);
|
||||||
setEditMode(false);
|
setEditMode(false);
|
||||||
@@ -199,7 +193,7 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-6 border-b border-white/5 pb-8">
|
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-6 border-b border-white/5 pb-8">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<div className="flex items-center gap-2 text-[10px] text-blue-500 font-bold uppercase tracking-[0.2em]">
|
<div className="flex items-center gap-2 text-[10px] text-blue-500 font-bold uppercase tracking-[0.2em]">
|
||||||
<Link href={`/courses/${params.id}`} className="hover:text-white transition-colors">Outline</Link>
|
<Link href={`/ courses / ${params.id} `} className="hover:text-white transition-colors">Outline</Link>
|
||||||
<span className="text-gray-700">/</span>
|
<span className="text-gray-700">/</span>
|
||||||
<span>Activity</span>
|
<span>Activity</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -274,8 +268,8 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 animate-in zoom-in-95 duration-300">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 animate-in zoom-in-95 duration-300">
|
||||||
{gradingCategories.length === 0 ? (
|
{gradingCategories.length === 0 ? (
|
||||||
<div className="col-span-full py-4 text-center border border-dashed border-white/10 rounded-2xl text-xs text-gray-500 italic">
|
<div className="col-span-full py-4 text-center border border-dashed border-white/10 rounded-2xl text-xs text-gray-500 italic">
|
||||||
No grading categories defined. <Link href={`/courses/${params.id}/grading`} className="text-blue-400 underline ml-1">Go to Grading Policy</Link>
|
No grading categories defined. <Link href={`/ courses / ${params.id} /grading`} className="text-blue-400 underline ml-1">Go to Grading Policy</Link >
|
||||||
</div>
|
</div >
|
||||||
) : (
|
) : (
|
||||||
gradingCategories.map((cat) => (
|
gradingCategories.map((cat) => (
|
||||||
<button
|
<button
|
||||||
@@ -292,7 +286,7 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</button>
|
</button>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div >
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-6 border-t border-white/5 animate-in fade-in duration-500">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-6 border-t border-white/5 animate-in fade-in duration-500">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
@@ -328,127 +322,133 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div >
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{editMode && (
|
{
|
||||||
<div className="bg-white/5 border border-white/10 rounded-3xl p-8 space-y-6 animate-in fade-in slide-in-from-top-4 duration-500">
|
editMode && (
|
||||||
<div>
|
<div className="bg-white/5 border border-white/10 rounded-3xl p-8 space-y-6 animate-in fade-in slide-in-from-top-4 duration-500">
|
||||||
<h3 className="text-xl font-bold flex items-center gap-2">
|
|
||||||
<span className="text-blue-500">📅</span> Scheduling & Deadlines
|
|
||||||
</h3>
|
|
||||||
<p className="text-sm text-gray-500 mt-1">Set deadlines and mark important dates for this activity</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
||||||
<div className="space-y-4">
|
|
||||||
<label className="block">
|
|
||||||
<span className="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-2 block">Due Date</span>
|
|
||||||
<input
|
|
||||||
type="date"
|
|
||||||
value={dueDate}
|
|
||||||
onChange={(e) => setDueDate(e.target.value)}
|
|
||||||
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-blue-500 transition-all font-bold"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-4">
|
|
||||||
<label className="block">
|
|
||||||
<span className="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-2 block">Date Type</span>
|
|
||||||
<select
|
|
||||||
value={importantDateType}
|
|
||||||
onChange={(e) => setImportantDateType(e.target.value)}
|
|
||||||
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-blue-500 transition-all appearance-none font-bold"
|
|
||||||
>
|
|
||||||
<option value="" className="bg-gray-900">Standard Activity</option>
|
|
||||||
<option value="exam" className="bg-gray-900">Exam</option>
|
|
||||||
<option value="assignment" className="bg-gray-900">Assignment</option>
|
|
||||||
<option value="milestone" className="bg-gray-900">Milestone</option>
|
|
||||||
<option value="live-session" className="bg-gray-900">Live Session</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* AI Magic Section */}
|
|
||||||
{editMode && (
|
|
||||||
<div className="bg-white/5 border border-white/10 rounded-3xl p-8 space-y-6 animate-in fade-in slide-in-from-top-4 duration-500">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<span className="text-2xl">🪄</span>
|
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-xl font-bold italic tracking-tight">AI Content Assistant</h3>
|
<h3 className="text-xl font-bold flex items-center gap-2">
|
||||||
<p className="text-xs text-gray-400 mt-1 uppercase tracking-widest font-bold">Automate your content creation</p>
|
<span className="text-blue-500">📅</span> Scheduling & Deadlines
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-gray-500 mt-1">Set deadlines and mark important dates for this activity</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
{(lesson.content_type === 'video' || lesson.content_type === 'audio') && (
|
<div className="space-y-4">
|
||||||
<button
|
<label className="block">
|
||||||
onClick={handleTranscribe}
|
<span className="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-2 block">Due Date</span>
|
||||||
disabled={isTranscribing}
|
<input
|
||||||
className={`p-6 rounded-2xl border transition-all text-left flex flex-col gap-2 ${lesson.transcription ? 'bg-green-500/10 border-green-500/30 text-green-400' : 'bg-blue-500/10 border-blue-500/30 text-blue-400 hover:border-blue-500/60'}`}
|
type="date"
|
||||||
>
|
value={dueDate}
|
||||||
<span className="text-xl">{isTranscribing ? '⏳' : '🎤'}</span>
|
onChange={(e) => setDueDate(e.target.value)}
|
||||||
<div className="text-[10px] font-black uppercase tracking-widest opacity-80">Video/Audio</div>
|
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-blue-500 transition-all font-bold"
|
||||||
<div className="font-bold">{isTranscribing ? 'Transcribing...' : lesson.transcription ? 'Update Transcript' : 'Transcribe Video'}</div>
|
/>
|
||||||
</button>
|
</label>
|
||||||
)}
|
</div>
|
||||||
|
|
||||||
<button
|
<div className="space-y-4">
|
||||||
onClick={handleSummarize}
|
<label className="block">
|
||||||
disabled={isGeneratingSummary || !lesson.transcription}
|
<span className="text-[10px] font-black uppercase tracking-widest text-gray-500 mb-2 block">Date Type</span>
|
||||||
className={`p-6 rounded-2xl border transition-all text-left flex flex-col gap-2 ${summary ? 'bg-green-500/10 border-green-500/30 text-green-400' : 'bg-indigo-500/10 border-indigo-500/30 text-indigo-400 hover:border-indigo-500/60 disabled:opacity-30 disabled:cursor-not-allowed'}`}
|
<select
|
||||||
>
|
value={importantDateType}
|
||||||
<span className="text-xl">{isGeneratingSummary ? '⏳' : '✍️'}</span>
|
onChange={(e) => setImportantDateType(e.target.value)}
|
||||||
<div className="text-[10px] font-black uppercase tracking-widest opacity-80">Summarization</div>
|
className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-blue-500 transition-all appearance-none font-bold"
|
||||||
<div className="font-bold">{isGeneratingSummary ? 'Generating...' : summary ? 'Update Summary' : 'Generate Summary'}</div>
|
>
|
||||||
{!lesson.transcription && <div className="text-[8px] opacity-60">Requires Transcript</div>}
|
<option value="" className="bg-gray-900">Standard Activity</option>
|
||||||
</button>
|
<option value="exam" className="bg-gray-900">Exam</option>
|
||||||
|
<option value="assignment" className="bg-gray-900">Assignment</option>
|
||||||
<button
|
<option value="milestone" className="bg-gray-900">Milestone</option>
|
||||||
onClick={handleGenerateQuiz}
|
<option value="live-session" className="bg-gray-900">Live Session</option>
|
||||||
disabled={isGeneratingQuiz || !lesson.transcription}
|
</select>
|
||||||
className="p-6 bg-purple-500/10 border border-purple-500/30 hover:border-purple-500/60 rounded-2xl transition-all text-left flex flex-col gap-2 text-purple-400 disabled:opacity-30 disabled:cursor-not-allowed"
|
</label>
|
||||||
>
|
|
||||||
<span className="text-xl">{isGeneratingQuiz ? '⏳' : '💡'}</span>
|
|
||||||
<div className="text-[10px] font-black uppercase tracking-widest opacity-80">Assessments</div>
|
|
||||||
<div className="font-bold">{isGeneratingQuiz ? 'Building...' : 'Generate Quiz'}</div>
|
|
||||||
{!lesson.transcription && <div className="text-[8px] opacity-60">Requires Transcript</div>}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* AI Summary Visualization */}
|
|
||||||
{(summary || editMode) && (
|
|
||||||
<div className="bg-gradient-to-br from-indigo-500/10 to-blue-500/10 border border-indigo-500/20 rounded-3xl p-8 space-y-6 animate-in fade-in duration-700">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<span className="text-2xl">✨</span>
|
|
||||||
<div>
|
|
||||||
<h3 className="text-xl font-bold font-black italic tracking-tight">AI Lesson Summary</h3>
|
|
||||||
<p className="text-xs text-gray-400 mt-1 uppercase tracking-widest font-bold">Key insights generated by intelligence</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{editMode ? (
|
{/* AI Magic Section */}
|
||||||
<textarea
|
{
|
||||||
value={summary}
|
editMode && (
|
||||||
onChange={(e) => setSummary(e.target.value)}
|
<div className="bg-white/5 border border-white/10 rounded-3xl p-8 space-y-6 animate-in fade-in slide-in-from-top-4 duration-500">
|
||||||
placeholder="A concise summary of the lesson content..."
|
<div className="flex items-center gap-3">
|
||||||
className="w-full bg-white/5 border border-white/10 rounded-2xl p-6 text-sm text-gray-300 focus:outline-none focus:border-blue-500/50 min-h-[120px] transition-all"
|
<span className="text-2xl">🪄</span>
|
||||||
/>
|
<div>
|
||||||
) : (
|
<h3 className="text-xl font-bold italic tracking-tight">AI Content Assistant</h3>
|
||||||
<div className="text-sm text-gray-400 leading-relaxed italic border-l-2 border-indigo-500/30 pl-6 py-2">
|
<p className="text-xs text-gray-400 mt-1 uppercase tracking-widest font-bold">Automate your content creation</p>
|
||||||
"{summary}"
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</div>
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
)}
|
{(lesson.content_type === 'video' || lesson.content_type === 'audio') && (
|
||||||
|
<button
|
||||||
|
onClick={handleTranscribe}
|
||||||
|
disabled={isTranscribing}
|
||||||
|
className={`p-6 rounded-2xl border transition-all text-left flex flex-col gap-2 ${lesson.transcription ? 'bg-green-500/10 border-green-500/30 text-green-400' : 'bg-blue-500/10 border-blue-500/30 text-blue-400 hover:border-blue-500/60'}`}
|
||||||
|
>
|
||||||
|
<span className="text-xl">{isTranscribing ? '⏳' : '🎤'}</span>
|
||||||
|
<div className="text-[10px] font-black uppercase tracking-widest opacity-80">Video/Audio</div>
|
||||||
|
<div className="font-bold">{isTranscribing ? 'Transcribing...' : lesson.transcription ? 'Update Transcript' : 'Transcribe Video'}</div>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleSummarize}
|
||||||
|
disabled={isGeneratingSummary || !lesson.transcription}
|
||||||
|
className={`p-6 rounded-2xl border transition-all text-left flex flex-col gap-2 ${summary ? 'bg-green-500/10 border-green-500/30 text-green-400' : 'bg-indigo-500/10 border-indigo-500/30 text-indigo-400 hover:border-indigo-500/60 disabled:opacity-30 disabled:cursor-not-allowed'}`}
|
||||||
|
>
|
||||||
|
<span className="text-xl">{isGeneratingSummary ? '⏳' : '✍️'}</span>
|
||||||
|
<div className="text-[10px] font-black uppercase tracking-widest opacity-80">Summarization</div>
|
||||||
|
<div className="font-bold">{isGeneratingSummary ? 'Generating...' : summary ? 'Update Summary' : 'Generate Summary'}</div>
|
||||||
|
{!lesson.transcription && <div className="text-[8px] opacity-60">Requires Transcript</div>}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleGenerateQuiz}
|
||||||
|
disabled={isGeneratingQuiz || !lesson.transcription}
|
||||||
|
className="p-6 bg-purple-500/10 border border-purple-500/30 hover:border-purple-500/60 rounded-2xl transition-all text-left flex flex-col gap-2 text-purple-400 disabled:opacity-30 disabled:cursor-not-allowed"
|
||||||
|
>
|
||||||
|
<span className="text-xl">{isGeneratingQuiz ? '⏳' : '💡'}</span>
|
||||||
|
<div className="text-[10px] font-black uppercase tracking-widest opacity-80">Assessments</div>
|
||||||
|
<div className="font-bold">{isGeneratingQuiz ? 'Building...' : 'Generate Quiz'}</div>
|
||||||
|
{!lesson.transcription && <div className="text-[8px] opacity-60">Requires Transcript</div>}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
{/* AI Summary Visualization */}
|
||||||
|
{
|
||||||
|
(summary || editMode) && (
|
||||||
|
<div className="bg-gradient-to-br from-indigo-500/10 to-blue-500/10 border border-indigo-500/20 rounded-3xl p-8 space-y-6 animate-in fade-in duration-700">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<span className="text-2xl">✨</span>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-xl font-bold font-black italic tracking-tight">AI Lesson Summary</h3>
|
||||||
|
<p className="text-xs text-gray-400 mt-1 uppercase tracking-widest font-bold">Key insights generated by intelligence</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{editMode ? (
|
||||||
|
<textarea
|
||||||
|
value={summary}
|
||||||
|
onChange={(e) => setSummary(e.target.value)}
|
||||||
|
placeholder="A concise summary of the lesson content..."
|
||||||
|
className="w-full bg-white/5 border border-white/10 rounded-2xl p-6 text-sm text-gray-300 focus:outline-none focus:border-blue-500/50 min-h-[120px] transition-all"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="text-sm text-gray-400 leading-relaxed italic border-l-2 border-indigo-500/30 pl-6 py-2">
|
||||||
|
"{summary}"
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
<div className="space-y-16">
|
<div className="space-y-16">
|
||||||
{blocks.map((block, index) => (
|
{blocks.map((block, index) => (
|
||||||
@@ -626,6 +626,6 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user