mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-08 00:00:42 +02:00
wip
This commit is contained in:
@@ -63,7 +63,7 @@ export function AIGuideActions(props: AIGuideActionsType) {
|
|||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div className="absolute top-8 right-0 z-10 w-48 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
|
<div className="absolute top-8 right-0 z-10 w-48 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
|
||||||
<a
|
<a
|
||||||
href={`/ai/guides/${guideSlug}`}
|
href={`/ai/guide/${guideSlug}`}
|
||||||
className="flex w-full items-center gap-1.5 p-2 text-sm font-medium text-gray-500 hover:bg-gray-100 hover:text-black disabled:cursor-not-allowed disabled:opacity-70"
|
className="flex w-full items-center gap-1.5 p-2 text-sm font-medium text-gray-500 hover:bg-gray-100 hover:text-black disabled:cursor-not-allowed disabled:opacity-70"
|
||||||
>
|
>
|
||||||
<ArrowUpRightIcon className="h-3.5 w-3.5" />
|
<ArrowUpRightIcon className="h-3.5 w-3.5" />
|
||||||
|
@@ -19,7 +19,7 @@ export function AIGuideCard(props: AIGuideCardProps) {
|
|||||||
return (
|
return (
|
||||||
<div className="relative flex flex-grow flex-col">
|
<div className="relative flex flex-grow flex-col">
|
||||||
<a
|
<a
|
||||||
href={`/ai/guides/${guide.slug}`}
|
href={`/ai/guide/${guide.slug}`}
|
||||||
className="hover:border-gray-3 00 group relative flex h-full min-h-[140px] w-full flex-col overflow-hidden rounded-lg border border-gray-200 bg-white p-4 text-left transition-all hover:bg-gray-50"
|
className="hover:border-gray-3 00 group relative flex h-full min-h-[140px] w-full flex-col overflow-hidden rounded-lg border border-gray-200 bg-white p-4 text-left transition-all hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
@@ -107,18 +107,20 @@ export function AIGuide(props: AIGuideProps) {
|
|||||||
)}
|
)}
|
||||||
{!guideSlug && <GenerateAIGuide onGuideSlugChange={setGuideSlug} />}
|
{!guideSlug && <GenerateAIGuide onGuideSlugChange={setGuideSlug} />}
|
||||||
|
|
||||||
{!isAiGuideSuggestionsLoading && aiGuide && !isRegenerating && (
|
{aiGuide && !isRegenerating && (
|
||||||
<div className="mt-4 grid grid-cols-2 divide-x divide-gray-200 rounded-lg border border-gray-200 bg-white">
|
<div className="mt-4 grid grid-cols-2 divide-x divide-gray-200 rounded-lg border border-gray-200 bg-white">
|
||||||
<ListSuggestions
|
<ListSuggestions
|
||||||
title="Related Topics"
|
title="Related Topics"
|
||||||
suggestions={relatedTopics}
|
suggestions={relatedTopics}
|
||||||
depth="essentials"
|
depth="essentials"
|
||||||
|
isLoading={isAiGuideSuggestionsLoading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ListSuggestions
|
<ListSuggestions
|
||||||
title="Dive Deeper"
|
title="Dive Deeper"
|
||||||
suggestions={deepDiveTopics}
|
suggestions={deepDiveTopics}
|
||||||
depth="detailed"
|
depth="detailed"
|
||||||
|
isLoading={isAiGuideSuggestionsLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -128,6 +130,7 @@ export function AIGuide(props: AIGuideProps) {
|
|||||||
isGuideLoading={!aiGuide}
|
isGuideLoading={!aiGuide}
|
||||||
onUpgrade={() => setShowUpgradeModal(true)}
|
onUpgrade={() => setShowUpgradeModal(true)}
|
||||||
randomQuestions={randomQuestions}
|
randomQuestions={randomQuestions}
|
||||||
|
isQuestionsLoading={isAiGuideSuggestionsLoading}
|
||||||
/>
|
/>
|
||||||
</AITutorLayout>
|
</AITutorLayout>
|
||||||
);
|
);
|
||||||
@@ -137,10 +140,11 @@ type ListSuggestionsProps = {
|
|||||||
title: string;
|
title: string;
|
||||||
suggestions: string[];
|
suggestions: string[];
|
||||||
depth: string;
|
depth: string;
|
||||||
|
isLoading: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ListSuggestions(props: ListSuggestionsProps) {
|
export function ListSuggestions(props: ListSuggestionsProps) {
|
||||||
const { title, suggestions, depth } = props;
|
const { title, suggestions, depth, isLoading } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
@@ -148,21 +152,31 @@ export function ListSuggestions(props: ListSuggestionsProps) {
|
|||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
<ul className="flex flex-col gap-1 p-1">
|
<ul className="flex flex-col gap-1 p-1">
|
||||||
{suggestions?.map((topic) => {
|
{isLoading && (
|
||||||
const url = `/ai/guides?term=${encodeURIComponent(topic)}&depth=${depth}&id=&format=guide`;
|
<>
|
||||||
|
{[1, 2].map((i) => (
|
||||||
|
<div key={i} className="w-full">
|
||||||
|
<div className="h-7 w-full animate-pulse rounded-md bg-gray-200"></div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!isLoading &&
|
||||||
|
suggestions?.map((topic) => {
|
||||||
|
const url = `/ai/guides?term=${encodeURIComponent(topic)}&depth=${depth}&id=&format=guide`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={topic} className="w-full">
|
<li key={topic} className="w-full">
|
||||||
<a
|
<a
|
||||||
href={url}
|
href={url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="block truncate rounded-md px-2 py-1 text-sm hover:bg-gray-100"
|
className="block truncate rounded-md px-2 py-1 text-sm hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
{topic}
|
{topic}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -24,11 +24,18 @@ type AIGuideChatProps = {
|
|||||||
guideSlug?: string;
|
guideSlug?: string;
|
||||||
isGuideLoading?: boolean;
|
isGuideLoading?: boolean;
|
||||||
onUpgrade?: () => void;
|
onUpgrade?: () => void;
|
||||||
|
isQuestionsLoading?: boolean;
|
||||||
randomQuestions?: string[];
|
randomQuestions?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function AIGuideChat(props: AIGuideChatProps) {
|
export function AIGuideChat(props: AIGuideChatProps) {
|
||||||
const { guideSlug, isGuideLoading, onUpgrade, randomQuestions } = props;
|
const {
|
||||||
|
guideSlug,
|
||||||
|
isGuideLoading,
|
||||||
|
onUpgrade,
|
||||||
|
randomQuestions,
|
||||||
|
isQuestionsLoading,
|
||||||
|
} = props;
|
||||||
|
|
||||||
const scrollareaRef = useRef<HTMLDivElement>(null);
|
const scrollareaRef = useRef<HTMLDivElement>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -163,7 +170,18 @@ export function AIGuideChat(props: AIGuideChatProps) {
|
|||||||
html="Hello, how can I help you today?"
|
html="Hello, how can I help you today?"
|
||||||
isIntro
|
isIntro
|
||||||
/>
|
/>
|
||||||
{randomQuestions &&
|
{isQuestionsLoading && (
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
{[1, 2, 3, 4].map((i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className="h-[38px] w-full animate-pulse rounded-lg bg-gray-200"
|
||||||
|
></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!isQuestionsLoading &&
|
||||||
|
randomQuestions &&
|
||||||
randomQuestions.length > 0 &&
|
randomQuestions.length > 0 &&
|
||||||
messages.length === 0 && (
|
messages.length === 0 && (
|
||||||
<>
|
<>
|
||||||
|
@@ -108,7 +108,7 @@ export function GenerateAIGuide(props: GenerateAIGuideProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
onGuideSlugChange?.(guideSlug);
|
onGuideSlugChange?.(guideSlug);
|
||||||
window.history.replaceState(null, '', `/ai/guides/${guideSlug}`);
|
window.history.replaceState(null, '', `/ai/guide/${guideSlug}`);
|
||||||
},
|
},
|
||||||
onLoadingChange: setIsLoading,
|
onLoadingChange: setIsLoading,
|
||||||
onError: setError,
|
onError: setError,
|
||||||
|
@@ -16,7 +16,7 @@ const { slug } = Astro.params as Params;
|
|||||||
briefTitle='AI Tutor'
|
briefTitle='AI Tutor'
|
||||||
description='AI Tutor'
|
description='AI Tutor'
|
||||||
keywords={['ai', 'tutor', 'education', 'learning']}
|
keywords={['ai', 'tutor', 'education', 'learning']}
|
||||||
canonicalUrl={`/ai/document/${slug}`}
|
canonicalUrl={`/ai/guide/${slug}`}
|
||||||
>
|
>
|
||||||
<AIGuide client:load guideSlug={slug} />
|
<AIGuide client:load guideSlug={slug} />
|
||||||
</SkeletonLayout>
|
</SkeletonLayout>
|
@@ -11,7 +11,7 @@ import SkeletonLayout from '../../../layouts/SkeletonLayout.astro';
|
|||||||
briefTitle='AI Tutor'
|
briefTitle='AI Tutor'
|
||||||
description='AI Tutor'
|
description='AI Tutor'
|
||||||
keywords={['ai', 'tutor', 'education', 'learning']}
|
keywords={['ai', 'tutor', 'education', 'learning']}
|
||||||
canonicalUrl='/ai/document'
|
canonicalUrl='/ai/guide'
|
||||||
noIndex={true}
|
noIndex={true}
|
||||||
>
|
>
|
||||||
<AIGuide client:load />
|
<AIGuide client:load />
|
Reference in New Issue
Block a user