feat: create new course

feat/create-new-course
Arik Chakma 3 days ago committed by Kamran Ahmed
parent 30d3a86784
commit 646cc3c826
  1. 54
      src/components/TopicDetail/CreateCourseModal.tsx
  2. 24
      src/components/TopicDetail/TopicDetail.tsx
  3. 13
      src/components/TopicDetail/TopicDetailAI.tsx

@ -0,0 +1,54 @@
import { ChevronRightIcon, SearchIcon } from 'lucide-react';
import { Modal } from '../Modal';
type CreateCourseModalProps = {
onClose: () => void;
};
export function CreateCourseModal(props: CreateCourseModalProps) {
const { onClose } = props;
return (
<Modal
onClose={onClose}
wrapperClassName="h-auto mt-20"
overlayClassName="items-start"
bodyClassName="p-1.5"
>
<form
onSubmit={(e) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
const subject = formData.get('subject');
window.location.href = `/ai/search?term=${subject}&difficulty=beginner&src=topic`;
onClose();
}}
>
<label
className="mb-2.5 ml-1 inline-block text-sm leading-none"
htmlFor="subject"
>
Subject
</label>
<div className="relative overflow-hidden rounded-lg border">
<input
id="subject"
type="text"
className="w-full bg-white p-2.5 px-8 text-sm focus:bg-gray-50 focus:outline-hidden"
placeholder="Enter a Subject for the Course"
name="subject"
autoFocus={true}
/>
<div className="absolute top-0 left-0 flex h-full items-center justify-center px-2 text-gray-500">
<SearchIcon className="size-4" />
</div>
<button className="absolute top-0 right-0 flex h-full items-center justify-center px-2 hover:bg-gray-200">
<ChevronRightIcon className="size-4" />
</button>
</div>
</form>
</Modal>
);
}

@ -42,6 +42,7 @@ import { cn } from '../../lib/classname.ts';
import type { AIChatHistoryType } from '../GenerateCourse/AICourseLessonChat.tsx';
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal.tsx';
import { TopicProgressButton } from './TopicProgressButton.tsx';
import { CreateCourseModal } from './CreateCourseModal.tsx';
type TopicDetailProps = {
resourceId?: string;
@ -119,6 +120,8 @@ export function TopicDetail(props: TopicDetailProps) {
const [showUpgradeModal, setShowUpgradeModal] = useState(false);
const [isCustomResource, setIsCustomResource] = useState(false);
const [showSubjectSearchModal, setShowSubjectSearchModal] = useState(false);
const toast = useToast();
const [showPaidResourceDisclaimer, setShowPaidResourceDisclaimer] =
@ -139,6 +142,7 @@ export function TopicDetail(props: TopicDetailProps) {
setShowUpgradeModal(false);
setAiChatHistory(defaultChatHistory);
setActiveTab('content');
setShowSubjectSearchModal(false);
};
// Close the topic detail when user clicks outside the topic detail
@ -349,10 +353,6 @@ export function TopicDetail(props: TopicDetailProps) {
return null;
}
const resourceTitleForSearch = resourceTitle
?.toLowerCase()
?.replace(/\s+?roadmap/gi, '');
const tnsLink =
'https://thenewstack.io/devops/?utm_source=roadmap.sh&utm_medium=Referral&utm_campaign=Topic';
@ -362,10 +362,6 @@ export function TopicDetail(props: TopicDetailProps) {
return resource.topicIds.includes(normalizedTopicId);
});
const hasPaidScrimbaLinks = paidResourcesForTopic.some(
(resource) => resource?.url?.toLowerCase().indexOf('scrimba') !== -1,
);
const shouldShowAiTab = !isCustomResource && resourceType === 'roadmap';
return (
@ -379,6 +375,10 @@ export function TopicDetail(props: TopicDetailProps) {
<UpgradeAccountModal onClose={() => setShowUpgradeModal(false)} />
)}
{showSubjectSearchModal && (
<CreateCourseModal onClose={() => setShowSubjectSearchModal(false)} />
)}
{isLoading && (
<div className="flex h-full w-full justify-center">
<Spinner
@ -448,6 +448,14 @@ export function TopicDetail(props: TopicDetailProps) {
handleClose();
showLoginPopup();
}}
onShowSubjectSearchModal={() => {
if (!isLoggedIn()) {
showLoginPopup();
return;
}
setShowSubjectSearchModal(true);
}}
/>
)}

@ -11,6 +11,8 @@ import {
Gift,
Loader2Icon,
LockIcon,
PlusIcon,
SearchIcon,
SendIcon,
Trash2,
} from 'lucide-react';
@ -42,6 +44,8 @@ type TopicDetailAIProps = {
onUpgrade: () => void;
onLogin: () => void;
onShowSubjectSearchModal: () => void;
};
export function TopicDetailAI(props: TopicDetailAIProps) {
@ -53,6 +57,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
topicId,
onUpgrade,
onLogin,
onShowSubjectSearchModal,
} = props;
const textareaRef = useRef<HTMLTextAreaElement>(null);
@ -298,6 +303,14 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
))}
</a>
)}
<button
onClick={onShowSubjectSearchModal}
className="flex items-center gap-1.5 rounded-md border border-gray-300 bg-transparent px-2 py-1 hover:bg-gray-200 hover:text-black"
>
<PlusIcon className="h-3 w-3" />
Create a Course
</button>
</div>
</div>
)}

Loading…
Cancel
Save