diff --git a/src/components/micro_learning/MicroLearningContainer.jsx b/src/components/micro_learning/MicroLearningContainer.jsx index 57d2db5..0a78d42 100644 --- a/src/components/micro_learning/MicroLearningContainer.jsx +++ b/src/components/micro_learning/MicroLearningContainer.jsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import ConceptExplainer from './ConceptExplainer'; import ScenarioQuiz from './ScenarioQuiz'; import FlashcardSet from './FlashcardSet'; -import ReflectionPrompt from './ReflectionPrompt'; + import { useMicroLearningCompletions } from '../../hooks/useMicroLearningCompletions'; export default function MicroLearningContainer({ microLearning, sessionWeek, onCompletedSuccessfully }) { @@ -42,8 +42,7 @@ export default function MicroLearningContainer({ microLearning, sessionWeek, onC return ; case 'flashcard_set': return ; - case 'reflection_prompt': - return ; + default: return
Unknown micro learning type.
; } diff --git a/src/components/micro_learning/MicroLearningSelector.jsx b/src/components/micro_learning/MicroLearningSelector.jsx index 55821d7..055eefb 100644 --- a/src/components/micro_learning/MicroLearningSelector.jsx +++ b/src/components/micro_learning/MicroLearningSelector.jsx @@ -1,5 +1,5 @@ -import React, { useState } from 'react'; -import { Loader, BookOpen, Target, Layers, MessageCircle } from 'lucide-react'; +import React, { useState, useEffect } from 'react'; +import { Loader, BookOpen, Target, Layers, CheckCircle } from 'lucide-react'; import { useMicroLearnings } from '../../hooks/useMicroLearnings'; import MicroLearningContainer from './MicroLearningContainer'; import Card from '../ui/Card'; @@ -23,19 +23,28 @@ const TYPES = [ description: 'Test your recall with a set of quick flashcards.', icon: Layers, }, - { - key: 'reflection_prompt', - label: 'Reflection Prompt', - description: 'Connect the topic to your own professional experience.', - icon: MessageCircle, - }, ]; export default function MicroLearningSelector({ topicId, sessionWeek, onTopicCompleted }) { - const { getOrGenerate } = useMicroLearnings(); + const { getOrGenerate, checkExistingTypes } = useMicroLearnings(); const [selectedML, setSelectedML] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); + const [existingTypes, setExistingTypes] = useState({}); + + // Check which types already have generated content + useEffect(() => { + if (!topicId) return; + let cancelled = false; + + checkExistingTypes(topicId).then((result) => { + if (!cancelled) setExistingTypes(result); + }).catch((err) => { + console.warn('[MicroLearningSelector] Could not check existing types:', err); + }); + + return () => { cancelled = true; }; + }, [topicId]); const handleSelection = async (type) => { setLoading(true); @@ -43,6 +52,8 @@ export default function MicroLearningSelector({ topicId, sessionWeek, onTopicCom try { const record = await getOrGenerate(topicId, type); setSelectedML(record); + // Mark this type as existing after successful generation + setExistingTypes(prev => ({ ...prev, [type]: true })); } catch (err) { console.error('[MicroLearningSelector] Generation failed:', err); setError(err.message || 'Failed to generate content. Please try again.'); @@ -97,7 +108,7 @@ export default function MicroLearningSelector({ topicId, sessionWeek, onTopicCom ); } - // Type selection menu — always shows all 4 types + // Type selection menu return (
@@ -105,21 +116,30 @@ export default function MicroLearningSelector({ topicId, sessionWeek, onTopicCom

Select how you want to engage with this topic.

- {TYPES.map(({ key, label, description, icon: Icon }) => ( -
handleSelection(key)} - > -
-
- + {TYPES.map(({ key, label, description, icon: Icon }) => { + const exists = existingTypes[key]; + return ( +
handleSelection(key)} + > + {exists && ( +
+ + Generated +
+ )} +
+
+ +
+

{label}

-

{label}

+

{description}

-

{description}

-
- ))} + ); + })}
); diff --git a/src/hooks/useMicroLearnings.js b/src/hooks/useMicroLearnings.js index c55dfd6..c0f4ff7 100644 --- a/src/hooks/useMicroLearnings.js +++ b/src/hooks/useMicroLearnings.js @@ -1,4 +1,4 @@ -import { getOrGenerateMicroLearning, regenerateMicroLearning } from '../lib/microLearningService'; +import { getOrGenerateMicroLearning, regenerateMicroLearning, getExistingTypes } from '../lib/microLearningService'; export function useMicroLearnings() { /** @@ -16,5 +16,13 @@ export function useMicroLearnings() { return regenerateMicroLearning(topicId, type); }; - return { getOrGenerate, regenerate }; + /** + * Check which micro learning types already exist for a given topic. + * Returns { concept_explainer: true, scenario_quiz: false, ... } + */ + const checkExistingTypes = async (topicId) => { + return getExistingTypes(topicId); + }; + + return { getOrGenerate, regenerate, checkExistingTypes }; } diff --git a/src/lib/microLearningService.js b/src/lib/microLearningService.js index d76e522..1633e2f 100644 --- a/src/lib/microLearningService.js +++ b/src/lib/microLearningService.js @@ -15,7 +15,6 @@ import { EMIT_CONCEPT_EXPLAINER_TOOL, EMIT_SCENARIO_QUIZ_TOOL, EMIT_FLASHCARD_SET_TOOL, - EMIT_REFLECTION_PROMPT_TOOL, } from './llmTools'; import * as db from './db'; @@ -53,15 +52,6 @@ Mix three question types: - Relationships: "How does X relate to Y?" Keep answers concise — one or two sentences maximum.`, }, - reflection_prompt: { - tool: EMIT_REFLECTION_PROMPT_TOOL, - tier: 'fast', - maxTokens: 1024, - instructions: `Generate a reflection prompt. -The question must be open-ended and cannot be answered with a fact. -It must require the employee to think about their own professional context — their team, their role, their past experience. -The model answer should show depth and specificity (3–5 sentences). It is not a rubric — it is an example of thoughtful reflection.`, - }, }; const SYSTEM_PROMPT = `You are an expert learning content writer for Respellion, an internal IT company. @@ -145,6 +135,21 @@ export async function deleteAllForTopic(topicId) { } } +// ── Public helpers ──────────────────────────────────────────────────────────── + +/** + * Check which micro learning types already exist for a given topic. + * Returns an object like { concept_explainer: true, scenario_quiz: false, ... } + */ +export async function getExistingTypes(topicId) { + const types = Object.keys(MICRO_LEARNING_TYPES); + const result = {}; + for (const type of types) { + result[type] = !!(await findExisting(topicId, type)); + } + return result; +} + // ── Internal helpers ────────────────────────────────────────────────────────── async function findExisting(topicId, type) {