import { useCallback, useEffect, useMemo, useState } from 'react'; import { Search, Cpu, Zap, BookOpen, CheckCircle2, Circle, Trophy, Loader2, Layers } from 'lucide-react'; import { motion, AnimatePresence } from 'motion/react'; import { cn } from '@/lib/utils'; import { fetchCTopics, type CChapterTopic } from '@/lib/cProgrammingClient'; import CContentPage from './CContentPage'; const STORAGE_KEY = 'ryp_c_completed'; function loadCompleted(): Record { try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}'); } catch { return {}; } } const LEVEL_COLORS: Record = { Core: 'border-blue-500/20 bg-blue-500/20 text-blue-400', Beginner: 'border-emerald-500/20 bg-emerald-500/20 text-emerald-400', Intermediate: 'border-cyan-500/20 bg-cyan-500/20 text-cyan-400', Advanced: 'border-purple-500/20 bg-purple-500/20 text-purple-400', }; interface CLearningPathProps { onBack: () => void; } export default function CLearningPath({ onBack }: CLearningPathProps) { const [topics, setTopics] = useState([]); const [loading, setLoading] = useState(true); const [selectedTopic, setSelectedTopic] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [completed, setCompleted] = useState>(loadCompleted); useEffect(() => { fetchCTopics() .then(data => { setTopics(data); setLoading(false); }) .catch(err => { console.error('Failed to fetch C topics:', err); setLoading(false); }); }, []); const toggleTopic = useCallback((id: string) => { setCompleted(prev => { const next = { ...prev, [id]: !prev[id] }; localStorage.setItem(STORAGE_KEY, JSON.stringify(next)); return next; }); }, []); const totalDone = topics.filter(t => completed[t.id]).length; const totalAll = topics.length; const totalSections = useMemo(() => topics.reduce((sum, topic) => sum + topic.section_count, 0), [topics]); const totalContent = useMemo(() => topics.reduce((sum, topic) => sum + topic.content_count, 0), [topics]); const pct = totalAll > 0 ? Math.round((totalDone / totalAll) * 100) : 0; const filteredTopics = topics.filter(topic => { const query = searchQuery.toLowerCase(); return ( topic.chapter_name.toLowerCase().includes(query) || topic.subtitle?.toLowerCase().includes(query) || topic.sections.some(section => section.section.toLowerCase().includes(query) || section.section_title.toLowerCase().includes(query) ) ); }); return (
{selectedTopic ? ( setSelectedTopic(null)} /> ) : (
Coding Language

C Programming

Study C from the fundamentals of syntax and memory to files, preprocessors, linked lists, and common pitfalls.

setSearchQuery(e.target.value)} className="h-11 w-72 rounded-2xl border border-zinc-800 bg-zinc-950/60 pl-10 pr-4 text-sm text-white outline-none transition-all placeholder-zinc-600 focus:border-blue-500/50 focus:ring-1 focus:ring-blue-500/30" />
Track Progress
{totalDone} / {totalAll} chapters
{totalSections} database topics | {totalContent} with stored details
Completion {pct}%
{pct === 100 && (
C Mastered!
)}
{loading ? (
) : (

Course Chapters

{filteredTopics.length} chapters
Done#ChapterAction
{filteredTopics.map((topic, idx) => { const done = !!completed[topic.id]; return ( { if ((e.target as HTMLElement).closest('button.checkbox-btn')) return; setSelectedTopic(topic); }} >
{topic.chapter_no}
{topic.chapter_name} {topic.level}
{topic.section_count} topics {topic.sections.slice(0, 3).map(section => ( {section.section} {section.section_title} ))} {topic.sections.length > 3 && ( +{topic.sections.length - 3} more )}
); })} {filteredTopics.length === 0 && !loading && (
No chapters found.
)}
)} )}
); }