|
|
|
|
@@ -1,12 +1,12 @@
|
|
|
|
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
|
|
|
import { ArrowDown, ArrowLeft, ArrowUp, BookOpen, ExternalLink, Loader2, Pencil, Plus, Save, Trash2, Upload, X } from 'lucide-react';
|
|
|
|
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
|
|
|
import { adminApi, instructorApi, LearningPath, LearningPathInput, TrailCourseOption } from '../services/api';
|
|
|
|
|
import { deleteCourse } from '../services/db';
|
|
|
|
|
import { adminApi, instructorApi, LearningPath, LearningPathInput } from '../services/api';
|
|
|
|
|
import { deleteCourse, getManagedCourses } from '../services/db';
|
|
|
|
|
import { CourseCoverImage } from '../components/CourseCoverImage';
|
|
|
|
|
import { useToast } from '../context/ToastContext';
|
|
|
|
|
|
|
|
|
|
type CourseOption = TrailCourseOption;
|
|
|
|
|
type CourseOption = { id: string; title: string; status: string; category: string; coverImageUrl: string | null };
|
|
|
|
|
const emptyInput = (): LearningPathInput => ({ title: '', description: '', coverImageUrl: null, coverImageZoom: 1, coverImagePositionX: 50, coverImagePositionY: 50, status: 'draft', courseIds: [] });
|
|
|
|
|
const toInput = (trail: LearningPath): LearningPathInput => ({ title: trail.title, description: trail.description, coverImageUrl: trail.coverImageUrl, coverImageZoom: trail.coverImageZoom, coverImagePositionX: trail.coverImagePositionX, coverImagePositionY: trail.coverImagePositionY, status: trail.status === 'published' ? 'published' : 'draft', courseIds: trail.courses.map((course) => course.id) });
|
|
|
|
|
|
|
|
|
|
@@ -26,8 +26,14 @@ export const TrailDetail: React.FC = () => {
|
|
|
|
|
const load = async () => {
|
|
|
|
|
setIsLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const [pathsResponse, coursesResponse] = await Promise.all([adminApi.listPaths(), adminApi.listPathCourses()]);
|
|
|
|
|
setCourses(coursesResponse.data);
|
|
|
|
|
const [pathsResponse, managedCourses] = await Promise.all([adminApi.listPaths(), getManagedCourses()]);
|
|
|
|
|
setCourses(managedCourses.map((course) => ({
|
|
|
|
|
id: course.id,
|
|
|
|
|
title: course.title,
|
|
|
|
|
status: course.status || 'draft',
|
|
|
|
|
category: course.category,
|
|
|
|
|
coverImageUrl: course.thumbnail || null,
|
|
|
|
|
})));
|
|
|
|
|
if (!isNew) {
|
|
|
|
|
const found = pathsResponse.data.find((item) => item.id === trailId);
|
|
|
|
|
if (!found) { showToast('Trilha não encontrada.', 'error'); navigate('/admin'); return; }
|
|
|
|
|
|