Add ai-course dropdown

feat/ai-tutor-redesign
Kamran Ahmed 4 days ago
parent 9156b4b700
commit 204a421559
  1. 2
      src/components/AITutor/AITutorLayout.tsx
  2. 69
      src/components/AITutor/DifficultyDropdown.tsx
  3. 65
      src/components/GenerateCourse/AICourse.tsx
  4. 2
      src/components/GenerateCourse/FineTuneCourse.tsx

@ -11,7 +11,7 @@ export function AITutorLayout(props: AITutorLayoutProps) {
return (
<div className="flex flex-grow flex-row">
<AITutorSidebar activeTab={activeTab} />
<div className="flex flex-grow flex-col bg-gray-100 px-4 py-4">
<div className="flex flex-grow h-screen overflow-y-scroll flex-col bg-gray-100 px-4 py-4">
{children}
</div>
</div>

@ -0,0 +1,69 @@
import { ChevronDown } from 'lucide-react';
import { useState, useRef, useEffect } from 'react';
import { cn } from '../../lib/classname';
import {
difficultyLevels,
type DifficultyLevel,
} from '../GenerateCourse/AICourse';
type DifficultyDropdownProps = {
value: DifficultyLevel;
onChange: (value: DifficultyLevel) => void;
};
export function DifficultyDropdown(props: DifficultyDropdownProps) {
const { value, onChange } = props;
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (
dropdownRef.current &&
!dropdownRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
return (
<div className="relative" ref={dropdownRef}>
<button
type="button"
onClick={() => setIsOpen(!isOpen)}
className={cn(
'flex items-center gap-2 rounded-full bg-gray-100 px-3 py-1 text-sm text-gray-700 hover:bg-gray-200 hover:text-black',
)}
>
<span className="capitalize">{value}</span>
<ChevronDown size={16} className={cn(isOpen && 'rotate-180')} />
</button>
{isOpen && (
<div className="absolute z-10 mt-1 flex flex-col overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
{difficultyLevels.map((level) => (
<button
key={level}
type="button"
onClick={() => {
onChange(level);
setIsOpen(false);
}}
className={cn(
'px-5 py-2 text-left text-sm capitalize hover:bg-gray-100',
value === level && 'bg-gray-200 font-medium hover:bg-gray-200',
)}
>
{level}
</button>
))}
</div>
)}
</div>
);
}

@ -1,9 +1,10 @@
import { SearchIcon, WandIcon } from 'lucide-react';
import { WandIcon } from 'lucide-react';
import { useEffect, useState } from 'react';
import { cn } from '../../lib/classname';
import { isLoggedIn } from '../../lib/jwt';
import { showLoginPopup } from '../../lib/popup';
import { FineTuneCourse } from './FineTuneCourse';
import { DifficultyDropdown } from '../AITutor/DifficultyDropdown';
import {
clearFineTuneData,
getCourseFineTuneData,
@ -71,7 +72,7 @@ export function AICourse(props: AICourseProps) {
}
return (
<div className="flex w-full max-w-3xl mx-auto flex-grow flex-col justify-center">
<div className="mx-auto flex w-full max-w-3xl flex-grow flex-col justify-center">
<h1 className="mb-2.5 text-center text-4xl font-bold max-sm:mb-2 max-sm:text-left max-sm:text-xl">
What can I help you learn?
</h1>
@ -79,59 +80,27 @@ export function AICourse(props: AICourseProps) {
Enter a topic below to generate a personalized course for it
</p>
<div className="rounded-lg border border-gray-200 bg-white p-6 max-sm:p-4">
<div className="rounded-lg border border-gray-300 bg-white">
<form
className="flex flex-col gap-5"
className="flex flex-col"
onSubmit={(e) => {
e.preventDefault();
onSubmit();
}}
>
<div className="flex flex-col">
<label
htmlFor="keyword"
className="mb-2.5 text-sm font-medium text-gray-700"
>
Course Topic
</label>
<div className="relative">
<div className="absolute top-1/2 left-3 -translate-y-1/2 text-gray-400">
<SearchIcon size={18} />
</div>
<input
id="keyword"
type="text"
value={keyword}
onChange={(e) => setKeyword(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="e.g., Algebra, JavaScript, Photography"
className="w-full rounded-md border border-gray-300 bg-white p-3 pl-10 text-gray-900 focus:ring-1 focus:ring-gray-500 focus:outline-hidden max-sm:placeholder:text-base"
maxLength={50}
/>
</div>
</div>
<input
id="keyword"
type="text"
value={keyword}
onChange={(e) => setKeyword(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Ask tutor to teach you..."
className="w-full rounded-md border-none bg-transparent px-4 pt-4 pb-8 text-gray-900 focus:outline-hidden max-sm:placeholder:text-base"
maxLength={50}
/>
<div className="flex flex-col">
<label className="mb-2.5 text-sm font-medium text-gray-700">
Difficulty Level
</label>
<div className="flex gap-2 max-sm:flex-col max-sm:gap-1">
{difficultyLevels.map((level) => (
<button
key={level}
type="button"
onClick={() => setDifficulty(level)}
className={cn(
'rounded-md border px-4 py-2 capitalize max-sm:text-sm',
difficulty === level
? 'border-gray-800 bg-gray-800 text-white'
: 'border-gray-200 bg-gray-100 text-gray-700 hover:bg-gray-200',
)}
>
{level}
</button>
))}
</div>
<div className="flex flex-col px-4">
<DifficultyDropdown value={difficulty} onChange={setDifficulty} />
</div>
<FineTuneCourse

@ -52,7 +52,7 @@ export function FineTuneCourse(props: FineTuneCourseProps) {
} = props;
return (
<div className="flex flex-col overflow-hidden rounded-lg border border-gray-200 transition-all">
<div className="flex flex-col overflow-hidden transition-all">
<label
className={cn(
'group flex cursor-pointer select-none flex-row items-center gap-2.5 px-4 py-3 text-left text-gray-500 transition-colors hover:bg-gray-100 focus:outline-hidden',

Loading…
Cancel
Save