Outline switcher

feat/ai-roadmap
Kamran Ahmed 3 weeks ago
parent 5d1e796b3d
commit 370e15f313
  1. 2
      src/components/GenerateCourse/AICourseContent.tsx
  2. 55
      src/components/GenerateCourse/AICourseOutlineHeader.tsx
  3. 4
      src/components/GenerateCourse/AICourseOutlineView.tsx
  4. 4
      src/components/GenerateCourse/AICourseRoadmapView.tsx
  5. 2
      src/components/GenerateCourse/RegenerateOutline.tsx

@ -428,6 +428,7 @@ export function AICourseContent(props: AICourseContentProps) {
setSidebarOpen={setSidebarOpen} setSidebarOpen={setSidebarOpen}
setViewMode={setViewMode} setViewMode={setViewMode}
setExpandedModules={setExpandedModules} setExpandedModules={setExpandedModules}
viewMode={viewMode}
/> />
)} )}
@ -443,6 +444,7 @@ export function AICourseContent(props: AICourseContentProps) {
setViewMode={setViewMode} setViewMode={setViewMode}
setExpandedModules={setExpandedModules} setExpandedModules={setExpandedModules}
onUpgradeClick={() => setShowUpgradeModal(true)} onUpgradeClick={() => setShowUpgradeModal(true)}
viewMode={viewMode}
/> />
)} )}

@ -1,15 +1,20 @@
import { cn } from '../../lib/classname'; import { cn } from '../../lib/classname';
import type { AiCourse } from '../../lib/ai'; import type { AiCourse } from '../../lib/ai';
import { RegenerateOutline } from './RegenerateOutline'; import { RegenerateOutline } from './RegenerateOutline';
import type { AICourseViewMode } from './AICourseContent';
import { BookOpenCheck, Signpost } from 'lucide-react';
type AICourseOutlineHeaderProps = { type AICourseOutlineHeaderProps = {
course: AiCourse; course: AiCourse;
isLoading: boolean; isLoading: boolean;
onRegenerateOutline: (prompt?: string) => void; onRegenerateOutline: (prompt?: string) => void;
viewMode: AICourseViewMode;
setViewMode: (mode: AICourseViewMode) => void;
}; };
export function AICourseOutlineHeader(props: AICourseOutlineHeaderProps) { export function AICourseOutlineHeader(props: AICourseOutlineHeaderProps) {
const { course, isLoading, onRegenerateOutline } = props; const { course, isLoading, onRegenerateOutline, viewMode, setViewMode } =
props;
return ( return (
<div <div
@ -27,9 +32,49 @@ export function AICourseOutlineHeader(props: AICourseOutlineHeaderProps) {
</p> </p>
</div> </div>
{!isLoading && ( <div className="absolute right-3 top-3 flex items-center gap-2">
<RegenerateOutline onRegenerateOutline={onRegenerateOutline} /> {!isLoading && (
)} <>
<div className="flex rounded-md border border-gray-200 bg-white p-0.5 mr-1">
<button
onClick={() => setViewMode('outline')}
className={cn(
'flex items-center gap-1 rounded px-2 py-1 text-sm transition-colors',
viewMode === 'outline'
? 'bg-gray-200 text-gray-900'
: 'text-gray-500 hover:text-gray-900',
)}
>
<BookOpenCheck
className={cn(
'size-4',
viewMode === 'outline' && 'text-gray-900',
)}
/>
<span>Outline</span>
</button>
<button
onClick={() => setViewMode('roadmap')}
className={cn(
'flex items-center gap-1 rounded px-2 py-1 text-sm transition-colors',
viewMode === 'roadmap'
? 'bg-gray-200 text-gray-900'
: 'text-gray-500 hover:text-gray-900',
)}
>
<Signpost
className={cn(
'size-4',
viewMode === 'roadmap' && 'text-gray-900',
)}
/>
<span>Map</span>
</button>
</div>
<RegenerateOutline onRegenerateOutline={onRegenerateOutline} />
</>
)}
</div>
</div> </div>
); );
} }

@ -16,6 +16,7 @@ type AICourseOutlineViewProps = {
setSidebarOpen: (open: boolean) => void; setSidebarOpen: (open: boolean) => void;
setViewMode: (mode: AICourseViewMode) => void; setViewMode: (mode: AICourseViewMode) => void;
setExpandedModules: Dispatch<SetStateAction<Record<number, boolean>>>; setExpandedModules: Dispatch<SetStateAction<Record<number, boolean>>>;
viewMode: AICourseViewMode;
}; };
export function AICourseOutlineView(props: AICourseOutlineViewProps) { export function AICourseOutlineView(props: AICourseOutlineViewProps) {
@ -28,6 +29,7 @@ export function AICourseOutlineView(props: AICourseOutlineViewProps) {
setSidebarOpen, setSidebarOpen,
setViewMode, setViewMode,
setExpandedModules, setExpandedModules,
viewMode,
} = props; } = props;
const aiCourseProgress = course.done || []; const aiCourseProgress = course.done || [];
@ -38,6 +40,8 @@ export function AICourseOutlineView(props: AICourseOutlineViewProps) {
course={course} course={course}
isLoading={isLoading} isLoading={isLoading}
onRegenerateOutline={onRegenerateOutline} onRegenerateOutline={onRegenerateOutline}
viewMode={viewMode}
setViewMode={setViewMode}
/> />
{course.title ? ( {course.title ? (
<div className="flex flex-col p-6 max-lg:mt-0.5 max-lg:p-4"> <div className="flex flex-col p-6 max-lg:mt-0.5 max-lg:p-4">

@ -36,6 +36,7 @@ export type AICourseRoadmapViewProps = {
setViewMode: (mode: AICourseViewMode) => void; setViewMode: (mode: AICourseViewMode) => void;
onUpgradeClick: () => void; onUpgradeClick: () => void;
setExpandedModules: Dispatch<SetStateAction<Record<number, boolean>>>; setExpandedModules: Dispatch<SetStateAction<Record<number, boolean>>>;
viewMode: AICourseViewMode;
}; };
export function AICourseRoadmapView(props: AICourseRoadmapViewProps) { export function AICourseRoadmapView(props: AICourseRoadmapViewProps) {
@ -50,6 +51,7 @@ export function AICourseRoadmapView(props: AICourseRoadmapViewProps) {
setViewMode, setViewMode,
setExpandedModules, setExpandedModules,
onUpgradeClick, onUpgradeClick,
viewMode,
} = props; } = props;
const containerEl = useRef<HTMLDivElement>(null); const containerEl = useRef<HTMLDivElement>(null);
@ -212,6 +214,8 @@ export function AICourseRoadmapView(props: AICourseRoadmapViewProps) {
setViewMode('outline'); setViewMode('outline');
onRegenerateOutline(prompt); onRegenerateOutline(prompt);
}} }}
viewMode={viewMode}
setViewMode={setViewMode}
/> />
{isLoading && ( {isLoading && (
<div className="absolute inset-0 flex h-full w-full items-center justify-center"> <div className="absolute inset-0 flex h-full w-full items-center justify-center">

@ -40,7 +40,7 @@ export function RegenerateOutline(props: RegenerateOutlineProps) {
/> />
)} )}
<div className="absolute right-3 top-3" ref={ref}> <div ref={ref} className="flex items-center">
<button <button
className={cn('text-gray-400 hover:text-black', { className={cn('text-gray-400 hover:text-black', {
'text-black': isDropdownVisible, 'text-black': isDropdownVisible,

Loading…
Cancel
Save