wip: view switch

feat/ai-roadmap
Arik Chakma 1 month ago
parent 55b4cc634a
commit 6294fd652d
  1. 48
      src/components/GenerateCourse/AICourseContent.tsx
  2. 74
      src/components/GenerateCourse/AIRoadmapViewSwitch.tsx

@ -258,6 +258,7 @@ export function AICourseContent(props: AICourseContentProps) {
<span className="font-medium">{totalModules} modules</span> <span className="font-medium">{totalModules} modules</span>
<span className="text-gray-400"></span> <span className="text-gray-400"></span>
<span className="font-medium">{totalCourseLessons} lessons</span> <span className="font-medium">{totalCourseLessons} lessons</span>
{viewMode === 'module' && ( {viewMode === 'module' && (
<span className="flex flex-row items-center gap-1 lg:hidden"> <span className="flex flex-row items-center gap-1 lg:hidden">
<span className="text-gray-400"></span> <span className="text-gray-400"></span>
@ -272,6 +273,7 @@ export function AICourseContent(props: AICourseContentProps) {
</button> </button>
</span> </span>
)} )}
{finishedPercentage > 0 && ( {finishedPercentage > 0 && (
<> <>
<span className="text-gray-400"></span> <span className="text-gray-400"></span>
@ -291,18 +293,12 @@ export function AICourseContent(props: AICourseContentProps) {
/> />
</div> </div>
{viewMode === 'module' && ( <AIRoadmapViewSwitch
<button viewMode={viewMode}
onClick={() => { setViewMode={setViewMode}
setExpandedModules({}); isLoading={isLoading}
setViewMode('outline'); variant="text"
}} />
className="flex flex-shrink-0 items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900 max-lg:hidden"
>
<BookOpenCheck size={18} className="mr-2" />
View Course Outline
</button>
)}
</div> </div>
</header> </header>
@ -337,20 +333,16 @@ export function AICourseContent(props: AICourseContentProps) {
)} )}
></span> ></span>
{viewMode !== 'outline' && ( {viewMode === 'module' && (
<button <AIRoadmapViewSwitch
onClick={() => { viewMode={viewMode}
setExpandedModules({}); setViewMode={setViewMode}
setViewMode('outline'); isLoading={isLoading}
}} variant="icon"
className="flex items-center gap-1 rounded-md bg-gray-200 px-2.5 py-1.5 text-xs transition-colors hover:bg-gray-300" />
>
<BookOpenCheck size={14} />
View Outline
</button>
)} )}
{viewMode === 'outline' && ( {viewMode !== 'module' && (
<button <button
onClick={() => { onClick={() => {
setExpandedModules({ setExpandedModules({
@ -422,14 +414,6 @@ export function AICourseContent(props: AICourseContentProps) {
/> />
)} )}
{(viewMode === 'outline' || viewMode === 'roadmap') && (
<AIRoadmapViewSwitch
viewMode={viewMode}
setViewMode={setViewMode}
isLoading={isLoading}
/>
)}
{viewMode === 'outline' && ( {viewMode === 'outline' && (
<AICourseOutlineView <AICourseOutlineView
course={course} course={course}

@ -1,3 +1,4 @@
import { BookOpenCheckIcon, SignpostIcon, type LucideIcon } from 'lucide-react';
import { cn } from '../../lib/classname'; import { cn } from '../../lib/classname';
import type { AICourseViewMode } from './AICourseContent'; import type { AICourseViewMode } from './AICourseContent';
@ -5,35 +6,76 @@ type AIRoadmapViewSwitchProps = {
viewMode: AICourseViewMode; viewMode: AICourseViewMode;
setViewMode: (mode: AICourseViewMode) => void; setViewMode: (mode: AICourseViewMode) => void;
isLoading: boolean; isLoading: boolean;
variant?: 'icon' | 'text';
}; };
export function AIRoadmapViewSwitch(props: AIRoadmapViewSwitchProps) { export function AIRoadmapViewSwitch(props: AIRoadmapViewSwitchProps) {
const { viewMode, setViewMode, isLoading } = props; const { viewMode, setViewMode, isLoading, variant = 'icon' } = props;
return ( return (
<div className="sticky top-0 z-10 mx-auto mb-5 flex justify-center"> <div
<div className="grid min-w-[200px] grid-cols-2 gap-0.5 rounded-xl border border-gray-200 bg-white p-0.5 shadow-sm">
<button
className={cn( className={cn(
'rounded-lg px-2 py-1 text-sm font-medium disabled:cursor-not-allowed', 'grid shrink-0 grid-cols-2 gap-0.5 rounded-md border border-gray-300 bg-white p-0.5 shadow-sm',
viewMode === 'outline' && 'bg-gray-100 text-gray-800',
)} )}
>
<SwitchButton
onClick={() => setViewMode('outline')} onClick={() => setViewMode('outline')}
isActive={viewMode === 'outline'}
disabled={isLoading} disabled={isLoading}
> variant={variant}
Outline icon={BookOpenCheckIcon}
</button> label="Outline"
/>
<SwitchButton
onClick={() => setViewMode('roadmap')}
isActive={viewMode === 'roadmap'}
disabled={isLoading}
variant={variant}
icon={SignpostIcon}
label="Roadmap"
/>
</div>
);
}
type SwitchButtonProps = {
onClick: () => void;
isActive: boolean;
disabled: boolean;
variant?: 'icon' | 'text';
icon: LucideIcon;
label: string;
};
export function SwitchButton(props: SwitchButtonProps) {
const {
onClick,
isActive,
disabled,
variant = 'icon',
icon: Icon,
label,
} = props;
return (
<button <button
className={cn( className={cn(
'rounded-lg px-2 py-1 text-sm font-medium disabled:cursor-not-allowed', 'flex items-center justify-center gap-1.5 rounded text-sm hover:bg-gray-100 disabled:cursor-not-allowed',
viewMode === 'roadmap' && 'bg-gray-100 text-gray-800', isActive && 'bg-gray-100 text-gray-800',
variant === 'text' ? 'px-2 py-1.5' : 'p-[5px]',
)} )}
onClick={() => setViewMode('roadmap')} onClick={onClick}
disabled={isLoading} disabled={disabled}
> >
Roadmap <Icon
className={cn(
'size-4',
variant === 'icon' && 'h-3 w-3',
isActive && 'text-gray-800',
)}
/>
{variant === 'text' && label}
</button> </button>
</div>
</div>
); );
} }

Loading…
Cancel
Save