mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-03 14:22:41 +02:00
Add AI guide
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { AITutorLayout } from '../AITutor/AITutorLayout';
|
||||
import { AIGuideContent } from './AIGuideContent';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { ExternalLink } from 'lucide-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { generateGuide } from '../../helper/generate-ai-guide';
|
||||
import { shuffle } from '../../helper/shuffle';
|
||||
import { useToast } from '../../hooks/use-toast';
|
||||
import { isLoggedIn } from '../../lib/jwt';
|
||||
import {
|
||||
aiGuideSuggestionsOptions,
|
||||
getAiGuideOptions,
|
||||
} from '../../queries/ai-guide';
|
||||
import { queryClient } from '../../stores/query-client';
|
||||
import { GenerateAIGuide } from './GenerateAIGuide';
|
||||
import { AIGuideChat } from './AIGuideChat';
|
||||
import { AITutorLayout } from '../AITutor/AITutorLayout';
|
||||
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal';
|
||||
import { isLoggedIn } from '../../lib/jwt';
|
||||
import { shuffle } from '../../helper/shuffle';
|
||||
import { generateGuide } from '../../helper/generate-ai-guide';
|
||||
import { useToast } from '../../hooks/use-toast';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { AIGuideChat } from './AIGuideChat';
|
||||
import { AIGuideContent } from './AIGuideContent';
|
||||
import { GenerateAIGuide } from './GenerateAIGuide';
|
||||
|
||||
type AIGuideProps = {
|
||||
guideSlug?: string;
|
||||
@@ -157,8 +158,8 @@ export function ListSuggestions(props: ListSuggestionsProps) {
|
||||
const { title, suggestions, depth, isLoading, currentGuideTitle } = props;
|
||||
|
||||
return (
|
||||
<div className="group relative overflow-hidden rounded-xl border border-gray-300 bg-linear-to-br from-gray-100 to-gray-50 shadow-xs transition-all duration-200 hover:shadow-sm">
|
||||
<div className="border-b border-gray-200/80 bg-white/60 px-5 py-4">
|
||||
<div className="group relative overflow-hidden rounded-xl border border-gray-300 bg-linear-to-br from-gray-100 to-gray-50 shadow-xs transition-all duration-200">
|
||||
<div className="border-b border-gray-200 bg-white px-5 py-4">
|
||||
<h2 className="text-lg font-semibold text-gray-900">{title}</h2>
|
||||
<p className="mt-1 text-sm text-gray-600">
|
||||
{depth === 'essentials'
|
||||
@@ -173,7 +174,7 @@ export function ListSuggestions(props: ListSuggestionsProps) {
|
||||
{[1, 2].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="h-10 w-full animate-pulse rounded-lg bg-gray-200/70"
|
||||
className="h-10 w-full animate-pulse rounded-lg bg-white"
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
@@ -198,19 +199,7 @@ export function ListSuggestions(props: ListSuggestionsProps) {
|
||||
<span className="flex-1 truncate group-hover/item:text-gray-900">
|
||||
{topic}
|
||||
</span>
|
||||
<svg
|
||||
className="ml-2 h-4 w-4 text-gray-400 transition-colors group-hover/item:text-gray-600"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
||||
/>
|
||||
</svg>
|
||||
<ExternalLink className="ml-2 size-4 text-gray-400 group-hover/item:text-gray-600" />
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
|
@@ -3,10 +3,11 @@ import { useChat, type ChatMessage } from '../../hooks/use-chat';
|
||||
import { RoadmapAIChatCard } from '../RoadmapAIChat/RoadmapAIChatCard';
|
||||
import {
|
||||
ArrowDownIcon,
|
||||
BotIcon, LockIcon,
|
||||
BotIcon,
|
||||
LockIcon,
|
||||
PauseCircleIcon,
|
||||
SendIcon,
|
||||
Trash2Icon
|
||||
Trash2Icon,
|
||||
} from 'lucide-react';
|
||||
import { ChatHeaderButton } from '../FrameRenderer/RoadmapFloatingChat';
|
||||
import { isLoggedIn } from '../../lib/jwt';
|
||||
@@ -153,7 +154,7 @@ export function AIGuideChat(props: AIGuideChatProps) {
|
||||
</div>
|
||||
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="absolute bg-gray-100 inset-0 flex items-center justify-center">
|
||||
<LoadingChip message="Loading..." />
|
||||
</div>
|
||||
)}
|
||||
@@ -170,11 +171,11 @@ export function AIGuideChat(props: AIGuideChatProps) {
|
||||
isIntro
|
||||
/>
|
||||
{isQuestionsLoading && (
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex flex-col gap-2">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="h-[38px] w-full animate-pulse rounded-lg bg-gray-200"
|
||||
className="h-[48px] w-full animate-pulse rounded-lg bg-gray-200"
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
@@ -183,24 +184,26 @@ export function AIGuideChat(props: AIGuideChatProps) {
|
||||
randomQuestions &&
|
||||
randomQuestions.length > 0 &&
|
||||
messages.length === 0 && (
|
||||
<>
|
||||
<ul className="flex flex-col gap-1">
|
||||
<div className="space-y-2">
|
||||
<p className="mb-2 text-xs font-normal text-gray-500">
|
||||
Some questions you might have about this lesson.
|
||||
</p>
|
||||
<div className="space-y-1">
|
||||
{randomQuestions?.map((question) => {
|
||||
return (
|
||||
<li key={`chat-${question}`}>
|
||||
<button
|
||||
className="w-fit rounded-lg border border-gray-200 bg-white p-2 text-left text-sm text-balance hover:bg-white/40"
|
||||
onClick={() => {
|
||||
handleSubmitInput(question);
|
||||
}}
|
||||
>
|
||||
<p className="text-gray-500">{question}</p>
|
||||
</button>
|
||||
</li>
|
||||
<button
|
||||
key={`chat-${question}`}
|
||||
className="flex h-full self-start rounded-md bg-yellow-500/10 px-3 py-2 text-left text-sm text-black hover:bg-yellow-500/20"
|
||||
onClick={() => {
|
||||
handleSubmitInput(question);
|
||||
}}
|
||||
>
|
||||
{question}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{messages.map((chat, index) => {
|
||||
|
Reference in New Issue
Block a user