Component Library Reference Guide
Quick Reference for All New UI Components​
1. Layout Components​
AdminLayoutV2​
Purpose: Main admin panel layout with collapsible sidebar and command palette
Usage:
import AdminLayoutV2 from './components/admin/AdminLayoutV2';
const YourAdminPage = () => (
<AdminLayoutV2>
<h1>Your Content Here</h1>
</AdminLayoutV2>
);
Features:
- ✅ Collapsible sidebar (click toggle or auto-collapses on mobile)
- ✅ Command palette (Cmd+K / Ctrl+K)
- ✅ User info with role badge
- ✅ Smooth animations
- ✅ Keyboard navigation
- ✅ Mobile responsive
2. Core UI Components​
Card​
Purpose: Container for grouped content with optional header
Props:
interface CardProps {
children: ReactNode;
title?: string;
subtitle?: string;
icon?: ReactNode;
actions?: ReactNode;
variant?: 'default' | 'elevated' | 'outlined';
hover?: boolean;
className?: string;
}
Examples:
import { Card } from './components/ui/Card';
import { Sparkles } from 'lucide-react';
// Basic card
<Card>
<p>Simple content</p>
</Card>
// Card with title and icon
<Card
title="AI Configuration"
subtitle="Choose your generation settings"
icon={<Sparkles className="w-5 h-5 text-primary" />}
>
<div>Your settings here</div>
</Card>
// Card with actions
<Card
title="Course Overview"
actions={
<button>Edit</button>
}
>
<div>Course details</div>
</Card>
// Elevated hover card
<Card variant="elevated" hover>
<div>This card lifts on hover</div>
</Card>
Button​
Purpose: Primary interactive element with multiple variants
Props:
interface ButtonProps {
children: ReactNode;
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
size?: 'sm' | 'md' | 'lg';
loading?: boolean;
disabled?: boolean;
icon?: ReactNode;
iconRight?: ReactNode;
fullWidth?: boolean;
onClick?: () => void;
}
Examples:
import { Button } from './components/ui/Button';
import { Save, ChevronRight } from 'lucide-react';
// Primary button with icon
<Button
variant="primary"
icon={<Save />}
onClick={handleSave}
>
Save Course
</Button>
// Secondary button
<Button variant="secondary" size="lg">
Cancel
</Button>
// Ghost button
<Button variant="ghost">
View Details
</Button>
// Danger button
<Button variant="danger">
Delete
</Button>
// Loading state
<Button variant="primary" loading>
Generating...
</Button>
// Icon on right
<Button
variant="primary"
iconRight={<ChevronRight />}
>
Continue
</Button>
// Full width
<Button fullWidth variant="primary">
Submit
</Button>
Toggle​
Purpose: On/off switch with smooth animation
Props:
interface ToggleProps {
checked: boolean;
onChange: (checked: boolean) => void;
disabled?: boolean;
size?: 'sm' | 'md' | 'lg';
label?: string;
description?: string;
}
Examples:
import { Toggle } from './components/ui/Toggle';
// Basic toggle
const [enabled, setEnabled] = useState(false);
<Toggle
checked={enabled}
onChange={setEnabled}
/>
// Toggle with label
<Toggle
checked={enabled}
onChange={setEnabled}
label="Enable AI Features"
description="Use artificial intelligence to enhance your courses"
/>
// Small toggle
<Toggle
checked={enabled}
onChange={setEnabled}
size="sm"
label="Dark Mode"
/>
// Disabled toggle
<Toggle
checked={true}
onChange={() => {}}
disabled
label="Premium Features (Locked)"
/>
Skeleton​
Purpose: Loading placeholders with pulse animation
Examples:
import {
Skeleton,
SkeletonCard,
SkeletonCourseStructure
} from './components/ui/Skeleton';
// Basic skeleton
<Skeleton width="200px" height="20px" />
// Full width skeleton with custom height
<Skeleton height="3rem" />
// Rounded skeleton
<Skeleton width="100px" rounded="full" />
// Skeleton card (pre-built)
<SkeletonCard lines={5} />
// Course structure skeleton (pre-built)
{isLoading && <SkeletonCourseStructure />}
// Custom skeleton layout
<div className="space-y-4">
<Skeleton width="60%" height="2rem" />
<Skeleton width="100%" height="1rem" />
<Skeleton width="80%" height="1rem" />
</div>
3. Course Creation Components​
CourseStructureEditor​
Purpose: Drag-and-drop course structure builder
Usage:
import { CourseStructureEditor } from './components/course-creation/CourseStructureEditor';
const [course, setCourse] = useState({
title: 'My Course',
sections: [
{
id: 'section-1',
title: 'Introduction',
position: 0,
lessons: [
{ id: 'lesson-1', title: 'Welcome', position: 0 }
]
}
]
});
<CourseStructureEditor
course={course}
onUpdate={setCourse}
/>
Features:
- ✅ Drag to reorder sections
- ✅ Drag to reorder lessons within sections
- ✅ Inline editing of titles
- ✅ Add/delete sections and lessons
- ✅ Keyboard shortcuts (Delete, Cmd+D to duplicate)
DraggableSection​
Purpose: Individual draggable section component
Props:
interface DraggableSectionProps {
section: {
id: string;
title: string;
description?: string;
lessons: Lesson[];
};
index: number;
onUpdate: (updates: Partial<Section>) => void;
onDelete: () => void;
onAddLesson: () => void;
onUpdateLesson: (lessonId: string, updates: Partial<Lesson>) => void;
onDeleteLesson: (lessonId: string) => void;
}
DraggableLesson​
Purpose: Individual draggable lesson component
Props:
interface DraggableLessonProps {
lesson: {
id: string;
title: string;
content?: string;
youtube_video_id?: string;
duration_seconds?: number;
};
index: number;
onUpdate: (updates: Partial<Lesson>) => void;
onDelete: () => void;
}
LessonContentEditor​
Purpose: Markdown editor for lesson content with AI generation
Usage:
import { LessonContentEditor } from './components/course-creation/LessonContentEditor';
<LessonContentEditor
lesson={currentLesson}
onUpdate={(content) => updateLesson(currentLesson.id, { content })}
/>
Features:
- ✅ Rich text editing (bold, italic, code)
- ✅ Markdown support
- ✅ Code syntax highlighting
- ✅ AI content generation button
- ✅ Auto-save (with debouncing)
FirecrawlToggle​
Purpose: Enable/disable research mode with URL inputs
Usage:
import { FirecrawlToggle } from './components/course-creation/FirecrawlToggle';
const [firecrawlEnabled, setFirecrawlEnabled] = useState(false);
const [urls, setUrls] = useState([]);
<FirecrawlToggle
enabled={firecrawlEnabled}
onToggle={setFirecrawlEnabled}
urls={urls}
onAddUrl={(url) => setUrls([...urls, url])}
onRemoveUrl={(index) => setUrls(urls.filter((_, i) => i !== index))}
/>
4. Animation Patterns​
Framer Motion Usage​
Fade In Animation:
import { motion } from 'framer-motion';
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4 }}
>
Your content
</motion.div>
Hover Scale:
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
Click me
</motion.button>
Stagger Children:
<motion.div
variants={{
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
}}
initial="hidden"
animate="visible"
>
{items.map((item) => (
<motion.div
key={item.id}
variants={{
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 }
}}
>
{item.content}
</motion.div>
))}
</motion.div>
Layout Animation (for drag & drop):
<motion.div layout>
This animates when its layout changes
</motion.div>
5. Styling Utilities​
CSS Custom Properties​
Access theme variables in your components:
/* In your component CSS */
.my-component {
background: var(--bg-secondary);
color: var(--text-primary);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
padding: var(--space-6);
}
/* Hover states */
.my-component:hover {
background: var(--bg-tertiary);
border-color: var(--border-strong);
}
Utility Classes​
Use these pre-built utility classes:
// Backgrounds
<div className="bg-gradient-primary">Gradient background</div>
<div className="glass">Glassmorphic effect</div>
<div className="frosted">Frosted glass effect</div>
// Text
<h1 className="text-gradient">Gradient text</h1>
// Animations
<div className="animate-fade-in">Fades in</div>
<div className="animate-pulse">Pulses</div>
<div className="animate-spin">Spins (for loaders)</div>
6. Form Components​
Custom Input with Validation​
const FormInput = ({
label,
error,
required,
icon,
...props
}) => (
<div className="form-group">
<label className="block text-sm font-medium text-text-secondary mb-2">
{label}
{required && <span className="text-error ml-1">*</span>}
</label>
<div className="relative">
{icon && (
<div className="absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary">
{icon}
</div>
)}
<input
className={`
w-full px-4 py-3
${icon ? 'pl-10' : ''}
bg-bg-secondary
border ${error ? 'border-error' : 'border-border-default'}
rounded-xl
text-text-primary
placeholder:text-text-tertiary
focus:border-primary focus:ring-2 focus:ring-primary/20
transition-all
`}
{...props}
/>
</div>
{error && (
<p className="mt-1 text-sm text-error">{error}</p>
)}
</div>
);
// Usage:
<FormInput
label="Course Title"
required
icon={<BookOpen className="w-5 h-5" />}
placeholder="Enter course title..."
error={errors.title}
/>
7. Modal/Dialog Component​
import { motion, AnimatePresence } from 'framer-motion';
import { X } from 'lucide-react';
const Modal = ({ isOpen, onClose, title, children }) => (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black/75 backdrop-blur-sm flex items-center justify-center z-50 p-4"
onClick={onClose}
>
<motion.div
initial={{ scale: 0.95, y: 20 }}
animate={{ scale: 1, y: 0 }}
exit={{ scale: 0.95, y: 20 }}
className="bg-bg-secondary border border-border-default rounded-2xl max-w-2xl w-full max-h-[90vh] overflow-hidden"
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-border-subtle">
<h2 className="text-xl font-bold text-white">{title}</h2>
<button
onClick={onClose}
className="p-2 hover:bg-bg-tertiary rounded-lg transition-colors"
>
<X className="w-5 h-5" />
</button>
</div>
{/* Content */}
<div className="p-6 overflow-y-auto">
{children}
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
);
// Usage:
const [isOpen, setIsOpen] = useState(false);
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Edit Lesson"
>
<LessonContentEditor lesson={currentLesson} />
</Modal>
8. Toast Notifications​
import { motion, AnimatePresence } from 'framer-motion';
import { CheckCircle, AlertCircle, X } from 'lucide-react';
const Toast = ({ type = 'success', message, onClose }) => {
const config = {
success: {
icon: <CheckCircle className="w-5 h-5" />,
bg: 'bg-success/10',
border: 'border-success/20',
text: 'text-success'
},
error: {
icon: <AlertCircle className="w-5 h-5" />,
bg: 'bg-error/10',
border: 'border-error/20',
text: 'text-error'
},
info: {
icon: <AlertCircle className="w-5 h-5" />,
bg: 'bg-info/10',
border: 'border-info/20',
text: 'text-info'
}
};
const { icon, bg, border, text } = config[type];
return (
<motion.div
initial={{ opacity: 0, y: -50, scale: 0.3 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, x: 300 }}
className={`
flex items-center gap-3 p-4 rounded-xl border
${bg} ${border}
shadow-lg backdrop-blur-sm
`}
>
<span className={text}>{icon}</span>
<span className="flex-1 text-white font-medium">{message}</span>
<button
onClick={onClose}
className="p-1 hover:bg-white/10 rounded transition-colors"
>
<X className="w-4 h-4" />
</button>
</motion.div>
);
};
// Toast Container
const ToastContainer = ({ toasts, removeToast }) => (
<div className="fixed top-4 right-4 z-50 space-y-2">
<AnimatePresence>
{toasts.map((toast) => (
<Toast
key={toast.id}
type={toast.type}
message={toast.message}
onClose={() => removeToast(toast.id)}
/>
))}
</AnimatePresence>
</div>
);
9. Progress Bar​
const ProgressBar = ({ value, max = 100, label, variant = 'primary' }) => {
const percentage = (value / max) * 100;
const colors = {
primary: 'bg-primary',
success: 'bg-success',
warning: 'bg-warning',
error: 'bg-error'
};
return (
<div className="space-y-2">
{label && (
<div className="flex justify-between text-sm">
<span className="text-text-secondary">{label}</span>
<span className="text-text-primary font-medium">
{value} / {max}
</span>
</div>
)}
<div className="w-full h-2 bg-bg-elevated rounded-full overflow-hidden">
<motion.div
initial={{ width: 0 }}
animate={{ width: `${percentage}%` }}
transition={{ duration: 0.5, ease: "easeOut" }}
className={`h-full ${colors[variant]} rounded-full`}
/>
</div>
</div>
);
};
// Usage:
<ProgressBar
value={15}
max={25}
label="Lessons Completed"
variant="success"
/>
10. Badge Component​
const Badge = ({ children, variant = 'default', size = 'md' }) => {
const variants = {
default: 'bg-bg-elevated text-text-primary',
primary: 'bg-primary/20 text-primary',
success: 'bg-success/20 text-success',
warning: 'bg-warning/20 text-warning',
error: 'bg-error/20 text-error'
};
const sizes = {
sm: 'px-2 py-0.5 text-xs',
md: 'px-3 py-1 text-sm',
lg: 'px-4 py-1.5 text-base'
};
return (
<span className={`
inline-flex items-center gap-1
rounded-full font-medium
${variants[variant]}
${sizes[size]}
`}>
{children}
</span>
);
};
// Usage:
<Badge variant="success" size="sm">Active</Badge>
<Badge variant="warning">Coming Soon</Badge>
<Badge variant="error">Draft</Badge>
Summary​
Total Components Provided: 20+
Component Categories:
- ✅ Layout (AdminLayoutV2)
- ✅ Core UI (Card, Button, Toggle, Skeleton)
- ✅ Course Creation (Draggable components, Editor)
- ✅ Forms (Input, Textarea, Select patterns)
- ✅ Feedback (Toast, Modal, Progress)
- ✅ Data Display (Badge, Card)
All components include:
- TypeScript-ready prop interfaces
- Accessibility features (ARIA, focus management)
- Responsive design
- Dark theme support
- Smooth animations
Reference this guide when building new features!