-
Channel-Based Recommendations
+
+ Channel-Based Recommendations
+
{Object.keys(channelRecommendations).length === 0 ? (
-
No channel-based recommendations available.
+
+ No channel-based recommendations available.
+
) : (
- {Object.entries(channelRecommendations).map(([channelName, modules]) => (
-
-
-
- {channelName}
-
- ({modules.length} modules)
-
-
- {modules
- .filter(module => !items.some(item => item.module_id === module.id))
- .map(module => (
-
-
-
-
{module.module_title}
- {module.level && (
-
- {module.level.name}
-
- )}
- {module.matching_skills && module.matching_skills > 0 && (
-
- {module.matching_skills} skills match
-
+ {Object.entries(channelRecommendations).map(
+ ([channelName, modules]) => (
+
+
+
+ {channelName}
+
+
+ ({modules.length} modules)
+
+
+
+ {modules
+ .filter(
+ (module) =>
+ !items.some(
+ (item) => item.module_id === module.id
+ )
+ )
+ .map((module) => (
+
+
+
+
+ {module.module_title}
+
+ {module.level && (
+
+ {module.level.name}
+
+ )}
+ {module.matching_skills &&
+ module.matching_skills > 0 && (
+
+ {module.matching_skills} skills match
+
+ )}
+
+
+ {module.course_name} • {module.module_type}
+
+ {module.description && (
+
+ {module.description}
+
)}
-
- {module.course_name} • {module.module_type}
-
- {module.description && (
-
- {module.description}
-
- )}
+
-
-
- ))
- }
- {modules.filter(module => !items.some(item => item.module_id === module.id)).length === 0 && (
-
All modules from this channel are already in your roadmap.
- )}
+ ))}
+ {modules.filter(
+ (module) =>
+ !items.some((item) => item.module_id === module.id)
+ ).length === 0 && (
+
+ All modules from this channel are already in your
+ roadmap.
+
+ )}
+
-
- ))}
+ )
+ )}
)}
- )}
+ )} */}
);
}
diff --git a/components/roadmap/RoadmapList.tsx b/components/roadmap/RoadmapList.tsx
index 56dfd0b..26b0f9a 100644
--- a/components/roadmap/RoadmapList.tsx
+++ b/components/roadmap/RoadmapList.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import { useState } from "react";
import { Roadmap } from "./types";
@@ -8,15 +6,27 @@ interface Props {
onSelect: (roadmap: Roadmap) => void;
onDelete: (roadmapId: number) => void;
onCreateNew: () => void;
- onAutoGenerate: () => void;
+ onAutoGenerate: () => Promise<{
+ roadmap?: Roadmap;
+ modulesAdded?: number;
+ } | void>;
+ isAiEnabled: boolean;
}
-export default function RoadmapList({ roadmaps, onSelect, onDelete, onCreateNew, onAutoGenerate }: Props) {
+export default function RoadmapList({
+ roadmaps,
+ onSelect,
+ onDelete,
+ onCreateNew,
+ onAutoGenerate,
+ isAiEnabled,
+}: Props) {
const [deletingId, setDeletingId] = useState
(null);
+ const [autoGenMessage, setAutoGenMessage] = useState(null);
const handleDelete = async (roadmapId: number) => {
if (!confirm("Are you sure you want to delete this roadmap?")) return;
-
+
setDeletingId(roadmapId);
try {
await onDelete(roadmapId);
@@ -25,17 +35,45 @@ export default function RoadmapList({ roadmaps, onSelect, onDelete, onCreateNew,
}
};
+ const handleAutoGenerate = async () => {
+ setAutoGenMessage(null);
+ try {
+ const result = await onAutoGenerate();
+ if (
+ !result ||
+ (result.modulesAdded !== undefined && result.modulesAdded === 0)
+ ) {
+ setAutoGenMessage(
+ "No new modules to recommend. You can create it manually if you want."
+ );
+ }
+ } catch (err: any) {
+ const msg = err?.message || "Failed to auto-generate roadmap.";
+ if (msg.toLowerCase().includes("same set of modules")) {
+ setAutoGenMessage(
+ "No new modules to recommend. You can create it manually if you want."
+ );
+ } else {
+ setAutoGenMessage(msg);
+ }
+ }
+ };
+
return (
-
My Learning Roadmaps
+
+ My Learning Roadmaps
+
-
+ {isAiEnabled && (
+
+ )}
+ {autoGenMessage && (
+
+ {autoGenMessage}
+
+
+ )}
+
{roadmaps.length === 0 ? (
You don't have any roadmaps yet.
-
+ {isAiEnabled && (
+
+ )}