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,10 +322,11 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div >
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{editMode && (
|
{
|
||||||
|
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="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>
|
<div>
|
||||||
<h3 className="text-xl font-bold flex items-center gap-2">
|
<h3 className="text-xl font-bold flex items-center gap-2">
|
||||||
@@ -371,10 +366,12 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{/* AI Magic Section */}
|
{/* AI Magic Section */}
|
||||||
{editMode && (
|
{
|
||||||
|
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="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">
|
<div className="flex items-center gap-3">
|
||||||
<span className="text-2xl">🪄</span>
|
<span className="text-2xl">🪄</span>
|
||||||
@@ -420,10 +417,12 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{/* AI Summary Visualization */}
|
{/* AI Summary Visualization */}
|
||||||
{(summary || editMode) && (
|
{
|
||||||
|
(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="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 justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
@@ -448,7 +447,8 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</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