mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-10-01 19:36:43 +02:00
Changes to the ai tutor URL
This commit is contained in:
@@ -10,8 +10,8 @@
|
|||||||
'roadmaps',
|
'roadmaps',
|
||||||
'community',
|
'community',
|
||||||
'start-here',
|
'start-here',
|
||||||
|
'ai-roadmaps',
|
||||||
'ai',
|
'ai',
|
||||||
'ai-tutor',
|
|
||||||
'teams',
|
'teams',
|
||||||
'about',
|
'about',
|
||||||
'account',
|
'account',
|
||||||
|
@@ -127,7 +127,7 @@ export function GitHubButton(props: GitHubButtonProps) {
|
|||||||
// For non authentication pages, we want to redirect back to the page
|
// For non authentication pages, we want to redirect back to the page
|
||||||
// the user was on before they clicked the social login button
|
// the user was on before they clicked the social login button
|
||||||
if (!['/login', '/signup'].includes(window.location.pathname)) {
|
if (!['/login', '/signup'].includes(window.location.pathname)) {
|
||||||
const pagePath = ['/respond-invite', '/befriend', '/r', '/ai'].includes(
|
const pagePath = ['/respond-invite', '/befriend', '/r', '/ai-roadmaps'].includes(
|
||||||
window.location.pathname,
|
window.location.pathname,
|
||||||
)
|
)
|
||||||
? window.location.pathname + window.location.search
|
? window.location.pathname + window.location.search
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import {
|
import {
|
||||||
FIRST_LOGIN_PARAM,
|
FIRST_LOGIN_PARAM, setAuthToken
|
||||||
TOKEN_COOKIE_NAME,
|
|
||||||
setAuthToken,
|
|
||||||
} from '../../lib/jwt';
|
} from '../../lib/jwt';
|
||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
import { COURSE_PURCHASE_PARAM } from '../../lib/jwt';
|
import { COURSE_PURCHASE_PARAM } from '../../lib/jwt';
|
||||||
@@ -11,8 +8,7 @@ import { GoogleIcon } from '../ReactIcons/GoogleIcon.tsx';
|
|||||||
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
||||||
import { CHECKOUT_AFTER_LOGIN_KEY } from './CourseLoginPopup.tsx';
|
import { CHECKOUT_AFTER_LOGIN_KEY } from './CourseLoginPopup.tsx';
|
||||||
import {
|
import {
|
||||||
getStoredUtmParams,
|
triggerUtmRegistration
|
||||||
triggerUtmRegistration,
|
|
||||||
} from '../../lib/browser.ts';
|
} from '../../lib/browser.ts';
|
||||||
import { cn } from '../../lib/classname.ts';
|
import { cn } from '../../lib/classname.ts';
|
||||||
|
|
||||||
@@ -132,7 +128,7 @@ export function GoogleButton(props: GoogleButtonProps) {
|
|||||||
'/respond-invite',
|
'/respond-invite',
|
||||||
'/befriend',
|
'/befriend',
|
||||||
'/r',
|
'/r',
|
||||||
'/ai',
|
'/ai-roadmaps',
|
||||||
].includes(window.location.pathname)
|
].includes(window.location.pathname)
|
||||||
? window.location.pathname + window.location.search
|
? window.location.pathname + window.location.search
|
||||||
: window.location.pathname;
|
: window.location.pathname;
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import {
|
import {
|
||||||
FIRST_LOGIN_PARAM,
|
FIRST_LOGIN_PARAM,
|
||||||
COURSE_PURCHASE_PARAM,
|
COURSE_PURCHASE_PARAM, setAuthToken
|
||||||
TOKEN_COOKIE_NAME,
|
|
||||||
setAuthToken,
|
|
||||||
} from '../../lib/jwt';
|
} from '../../lib/jwt';
|
||||||
import { cn } from '../../lib/classname.ts';
|
import { cn } from '../../lib/classname.ts';
|
||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
@@ -131,7 +128,7 @@ export function LinkedInButton(props: LinkedInButtonProps) {
|
|||||||
'/respond-invite',
|
'/respond-invite',
|
||||||
'/befriend',
|
'/befriend',
|
||||||
'/r',
|
'/r',
|
||||||
'/ai',
|
'/ai-roadmaps',
|
||||||
].includes(window.location.pathname)
|
].includes(window.location.pathname)
|
||||||
? window.location.pathname + window.location.search
|
? window.location.pathname + window.location.search
|
||||||
: window.location.pathname;
|
: window.location.pathname;
|
||||||
|
@@ -1,15 +1,6 @@
|
|||||||
import type { UserProgress } from '../TeamProgress/TeamProgressPage';
|
|
||||||
import { DashboardCustomProgressCard } from './DashboardCustomProgressCard';
|
|
||||||
import { DashboardCardLink } from './DashboardCardLink';
|
import { DashboardCardLink } from './DashboardCardLink';
|
||||||
import { useState } from 'react';
|
|
||||||
import { CreateRoadmapModal } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapModal';
|
|
||||||
import { Simulate } from 'react-dom/test-utils';
|
|
||||||
import {
|
import {
|
||||||
ArrowUpRight,
|
BrainCircuit
|
||||||
Bot,
|
|
||||||
BrainCircuit,
|
|
||||||
Map,
|
|
||||||
PencilRuler,
|
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
type DashboardAiRoadmapsProps = {
|
type DashboardAiRoadmapsProps = {
|
||||||
@@ -30,7 +21,7 @@ export function DashboardAiRoadmaps(props: DashboardAiRoadmapsProps) {
|
|||||||
<h2 className="text-xs uppercase text-gray-400">My AI Roadmaps</h2>
|
<h2 className="text-xs uppercase text-gray-400">My AI Roadmaps</h2>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/ai/explore"
|
href="/ai-roadmaps/explore"
|
||||||
className="rounded-full bg-gray-200 px-2.5 py-0.5 text-xs font-medium text-gray-700 hover:bg-gray-300 hover:text-black"
|
className="rounded-full bg-gray-200 px-2.5 py-0.5 text-xs font-medium text-gray-700 hover:bg-gray-300 hover:text-black"
|
||||||
>
|
>
|
||||||
AI Generated Roadmaps
|
AI Generated Roadmaps
|
||||||
@@ -41,7 +32,7 @@ export function DashboardAiRoadmaps(props: DashboardAiRoadmapsProps) {
|
|||||||
<DashboardCardLink
|
<DashboardCardLink
|
||||||
className="mt-0"
|
className="mt-0"
|
||||||
icon={BrainCircuit}
|
icon={BrainCircuit}
|
||||||
href="/ai"
|
href="/ai-roadmaps"
|
||||||
title="Generate Roadmaps with AI"
|
title="Generate Roadmaps with AI"
|
||||||
description="You can generate your own roadmap with AI"
|
description="You can generate your own roadmap with AI"
|
||||||
/>
|
/>
|
||||||
@@ -61,7 +52,7 @@ export function DashboardAiRoadmaps(props: DashboardAiRoadmapsProps) {
|
|||||||
{roadmaps.map((roadmap) => (
|
{roadmaps.map((roadmap) => (
|
||||||
<a
|
<a
|
||||||
key={roadmap.id}
|
key={roadmap.id}
|
||||||
href={`/ai/${roadmap.slug}`}
|
href={`/ai-roadmaps/${roadmap.slug}`}
|
||||||
className="relative truncate rounded-md border bg-white p-2.5 text-left text-sm shadow-sm hover:border-gray-400 hover:bg-gray-50"
|
className="relative truncate rounded-md border bg-white p-2.5 text-left text-sm shadow-sm hover:border-gray-400 hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
{roadmap.title}
|
{roadmap.title}
|
||||||
@@ -70,7 +61,7 @@ export function DashboardAiRoadmaps(props: DashboardAiRoadmapsProps) {
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
className="flex items-center justify-center rounded-lg border border-dashed border-gray-300 bg-white p-2.5 text-sm font-medium text-gray-500 hover:bg-gray-50 hover:text-gray-600"
|
className="flex items-center justify-center rounded-lg border border-dashed border-gray-300 bg-white p-2.5 text-sm font-medium text-gray-500 hover:bg-gray-50 hover:text-gray-600"
|
||||||
href={'/ai'}
|
href={'/ai-roadmaps'}
|
||||||
>
|
>
|
||||||
+ Generate New
|
+ Generate New
|
||||||
</a>
|
</a>
|
||||||
|
@@ -3,13 +3,8 @@ import { DashboardCustomProgressCard } from './DashboardCustomProgressCard';
|
|||||||
import { DashboardCardLink } from './DashboardCardLink';
|
import { DashboardCardLink } from './DashboardCardLink';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { CreateRoadmapModal } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapModal';
|
import { CreateRoadmapModal } from '../CustomRoadmap/CreateRoadmap/CreateRoadmapModal';
|
||||||
import { Simulate } from 'react-dom/test-utils';
|
|
||||||
import {
|
import {
|
||||||
ArrowUpRight,
|
BrainCircuit, PencilRuler
|
||||||
Bot,
|
|
||||||
BrainCircuit,
|
|
||||||
Map,
|
|
||||||
PencilRuler,
|
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
type ListDashboardCustomProgressProps = {
|
type ListDashboardCustomProgressProps = {
|
||||||
@@ -63,7 +58,7 @@ export function ListDashboardCustomProgress(
|
|||||||
<DashboardCardLink
|
<DashboardCardLink
|
||||||
className="mt-0"
|
className="mt-0"
|
||||||
icon={BrainCircuit}
|
icon={BrainCircuit}
|
||||||
href="/ai"
|
href="/ai-roadmaps"
|
||||||
title="Generate Roadmaps with AI"
|
title="Generate Roadmaps with AI"
|
||||||
description="You can generate your own roadmap with AI"
|
description="You can generate your own roadmap with AI"
|
||||||
/>
|
/>
|
||||||
@@ -99,7 +94,7 @@ export function ListDashboardCustomProgress(
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
className="flex min-h-[80px] items-center justify-center rounded-lg border border-dashed border-gray-300 bg-white p-4 text-sm font-medium text-gray-500 hover:bg-gray-50 hover:text-gray-600"
|
className="flex min-h-[80px] items-center justify-center rounded-lg border border-dashed border-gray-300 bg-white p-4 text-sm font-medium text-gray-500 hover:bg-gray-50 hover:text-gray-600"
|
||||||
href={'/ai'}
|
href={'/ai-roadmaps'}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (!isAIGeneratedRoadmaps) {
|
if (!isAIGeneratedRoadmaps) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@@ -26,7 +26,7 @@ export function AIRoadmapsList(props: AIRoadmapsListProps) {
|
|||||||
return (
|
return (
|
||||||
<ul className="mb-4 grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
<ul className="mb-4 grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{roadmaps.map((roadmap) => {
|
{roadmaps.map((roadmap) => {
|
||||||
const roadmapLink = `/ai/${roadmap.slug}`;
|
const roadmapLink = `/ai-roadmaps/${roadmap.slug}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
@@ -12,7 +12,7 @@ export function EmptyRoadmaps() {
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col items-center gap-1 sm:flex-row sm:gap-1.5">
|
<div className="flex flex-col items-center gap-1 sm:flex-row sm:gap-1.5">
|
||||||
<a
|
<a
|
||||||
href="/ai"
|
href="/ai-roadmaps"
|
||||||
className="flex w-full items-center gap-1.5 rounded-md bg-gray-900 px-3 py-1.5 text-xs text-white sm:w-auto sm:text-sm"
|
className="flex w-full items-center gap-1.5 rounded-md bg-gray-900 px-3 py-1.5 text-xs text-white sm:w-auto sm:text-sm"
|
||||||
>
|
>
|
||||||
<Wand2 className="h-4 w-4" />
|
<Wand2 className="h-4 w-4" />
|
||||||
|
@@ -68,7 +68,7 @@ export function AICourse(props: AICourseProps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.href = `/ai-tutor/search?term=${encodeURIComponent(keyword)}&difficulty=${difficulty}&id=${sessionId}`;
|
window.location.href = `/ai/search?term=${encodeURIComponent(keyword)}&difficulty=${difficulty}&id=${sessionId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -63,7 +63,7 @@ export function AICourseActions(props: AICourseActionsType) {
|
|||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div className="absolute right-0 top-8 z-10 w-48 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
|
<div className="absolute right-0 top-8 z-10 w-48 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
|
||||||
<a
|
<a
|
||||||
href={`/ai-tutor/${courseSlug}`}
|
href={`/ai/${courseSlug}`}
|
||||||
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"
|
||||||
>
|
>
|
||||||
<Play className="h-3.5 w-3.5" />
|
<Play className="h-3.5 w-3.5" />
|
||||||
|
@@ -35,7 +35,7 @@ export function AICourseCard(props: AICourseCardProps) {
|
|||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<a
|
<a
|
||||||
href={`/ai-tutor/${course.slug}`}
|
href={`/ai/${course.slug}`}
|
||||||
className="hover:border-gray-3 00 group relative flex 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 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">
|
||||||
|
@@ -189,7 +189,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
|||||||
|
|
||||||
<p className="mt-5 text-sm text-black">
|
<p className="mt-5 text-sm text-black">
|
||||||
<a
|
<a
|
||||||
href="/ai-tutor"
|
href="/ai"
|
||||||
className="font-medium underline underline-offset-2"
|
className="font-medium underline underline-offset-2"
|
||||||
>
|
>
|
||||||
Back to AI Tutor
|
Back to AI Tutor
|
||||||
@@ -201,7 +201,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
|||||||
{(isNotFound || !showUpgradeButton) && (
|
{(isNotFound || !showUpgradeButton) && (
|
||||||
<div className="my-5">
|
<div className="my-5">
|
||||||
<a
|
<a
|
||||||
href="/ai-tutor"
|
href="/ai"
|
||||||
className="rounded-md bg-black px-6 py-2 text-sm font-medium text-white hover:bg-opacity-80"
|
className="rounded-md bg-black px-6 py-2 text-sm font-medium text-white hover:bg-opacity-80"
|
||||||
>
|
>
|
||||||
Create a course with AI
|
Create a course with AI
|
||||||
@@ -222,7 +222,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
|||||||
<div className="border-b border-gray-200 bg-gray-100">
|
<div className="border-b border-gray-200 bg-gray-100">
|
||||||
<div className="flex items-center justify-between px-4 py-2">
|
<div className="flex items-center justify-between px-4 py-2">
|
||||||
<a
|
<a
|
||||||
href="/ai-tutor"
|
href="/ai"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (isViewingLesson) {
|
if (isViewingLesson) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@@ -101,7 +101,7 @@ export function GenerateAICourse(props: GenerateAICourseProps) {
|
|||||||
options;
|
options;
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
if (!isLoggedIn()) {
|
||||||
window.location.href = '/ai-tutor';
|
window.location.href = '/ai';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ export function GetAICourse(props: GetAICourseProps) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoggedIn()) {
|
if (!isLoggedIn()) {
|
||||||
window.location.href = '/ai-tutor';
|
window.location.href = '/ai';
|
||||||
}
|
}
|
||||||
}, [isLoggedIn]);
|
}, [isLoggedIn]);
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ import {
|
|||||||
} from '../../lib/jwt';
|
} from '../../lib/jwt';
|
||||||
import { RoadmapSearch } from './RoadmapSearch.tsx';
|
import { RoadmapSearch } from './RoadmapSearch.tsx';
|
||||||
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
import { Spinner } from '../ReactIcons/Spinner.tsx';
|
||||||
import { Ban, Cog, Download, PenSquare, Save, Wand } from 'lucide-react';
|
import { Ban, Download, PenSquare, Save, Wand } from 'lucide-react';
|
||||||
import { ShareRoadmapButton } from '../ShareRoadmapButton.tsx';
|
import { ShareRoadmapButton } from '../ShareRoadmapButton.tsx';
|
||||||
import { httpGet, httpPost } from '../../lib/http.ts';
|
import { httpGet, httpPost } from '../../lib/http.ts';
|
||||||
import { pageProgressMessage } from '../../stores/page.ts';
|
import { pageProgressMessage } from '../../stores/page.ts';
|
||||||
@@ -199,7 +199,7 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
|||||||
roadmapSlug,
|
roadmapSlug,
|
||||||
},
|
},
|
||||||
'',
|
'',
|
||||||
`${origin}/ai/${roadmapSlug}`,
|
`${origin}/ai-roadmaps/${roadmapSlug}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,7 +473,7 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageUrl = `https://roadmap.sh/ai/${roadmapSlug}`;
|
const pageUrl = `https://roadmap.sh/ai-roadmaps/${roadmapSlug}`;
|
||||||
const canGenerateMore = roadmapLimitUsed < roadmapLimit || isPaidUser;
|
const canGenerateMore = roadmapLimitUsed < roadmapLimit || isPaidUser;
|
||||||
const isGenerateButtonDisabled =
|
const isGenerateButtonDisabled =
|
||||||
isLoadingResults ||
|
isLoadingResults ||
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { ArrowUpRight, Ban, Cog, Telescope, Wand } from 'lucide-react';
|
import { ArrowUpRight, Ban, Telescope, Wand } from 'lucide-react';
|
||||||
import type { FormEvent } from 'react';
|
import type { FormEvent } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { isLoggedIn } from '../../lib/jwt';
|
import { isLoggedIn } from '../../lib/jwt';
|
||||||
@@ -160,7 +160,7 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
|
|||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
<a
|
<a
|
||||||
href="/ai/explore"
|
href="/ai-roadmaps/explore"
|
||||||
className="flex items-center gap-1.5 rounded-full border border-black bg-gray-700 px-2 py-0.5 text-sm text-white transition-colors hover:border-black hover:bg-black"
|
className="flex items-center gap-1.5 rounded-full border border-black bg-gray-700 px-2 py-0.5 text-sm text-white transition-colors hover:border-black hover:bg-black"
|
||||||
>
|
>
|
||||||
Explore AI Roadmaps <Telescope size={17} />
|
Explore AI Roadmaps <Telescope size={17} />
|
||||||
@@ -181,7 +181,7 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
|
|||||||
</p>
|
</p>
|
||||||
<p className="flex flex-col gap-2 text-center text-gray-500 sm:flex-row">
|
<p className="flex flex-col gap-2 text-center text-gray-500 sm:flex-row">
|
||||||
<a
|
<a
|
||||||
href="/ai/explore"
|
href="/ai-roadmaps/explore"
|
||||||
className="flex items-center gap-1.5 rounded-full border border-purple-600 px-2.5 py-0.5 text-sm text-purple-600 transition-colors hover:bg-purple-600 hover:text-white"
|
className="flex items-center gap-1.5 rounded-full border border-purple-600 px-2.5 py-0.5 text-sm text-purple-600 transition-colors hover:bg-purple-600 hover:text-white"
|
||||||
>
|
>
|
||||||
Explore AI Generated Roadmaps <Telescope size={15} />
|
Explore AI Generated Roadmaps <Telescope size={15} />
|
||||||
@@ -210,7 +210,7 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
|
|||||||
|
|
||||||
<p className="flex flex-col gap-2 text-center text-gray-500 sm:flex-row">
|
<p className="flex flex-col gap-2 text-center text-gray-500 sm:flex-row">
|
||||||
<a
|
<a
|
||||||
href="/ai/explore"
|
href="/ai-roadmaps/explore"
|
||||||
className="flex items-center gap-1.5 rounded-full border border-purple-600 px-2.5 py-0.5 text-sm text-purple-600 transition-colors hover:bg-purple-600 hover:text-white"
|
className="flex items-center gap-1.5 rounded-full border border-purple-600 px-2.5 py-0.5 text-sm text-purple-600 transition-colors hover:bg-purple-600 hover:text-white"
|
||||||
>
|
>
|
||||||
Explore AI Roadmaps <Telescope size={15} />
|
Explore AI Roadmaps <Telescope size={15} />
|
||||||
|
@@ -208,7 +208,7 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
|
|||||||
{!isStreaming && (
|
{!isStreaming && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<a
|
<a
|
||||||
href="/ai-tutor"
|
href="/ai"
|
||||||
className="mb-1 mt-2 inline-flex items-center rounded-md bg-yellow-400 px-3 py-2 text-sm font-medium text-gray-800 no-underline hover:bg-yellow-500"
|
className="mb-1 mt-2 inline-flex items-center rounded-md bg-yellow-400 px-3 py-2 text-sm font-medium text-gray-800 no-underline hover:bg-yellow-500"
|
||||||
>
|
>
|
||||||
Dive deeper using AI Tutor
|
Dive deeper using AI Tutor
|
||||||
|
@@ -4,9 +4,7 @@ import {
|
|||||||
Plus,
|
Plus,
|
||||||
Sparkle,
|
Sparkle,
|
||||||
Eye,
|
Eye,
|
||||||
EyeOff,
|
EyeOff, SquareCheckBig
|
||||||
Square,
|
|
||||||
SquareCheckBig,
|
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { ProjectStatusDocument } from '../Projects/ListProjectSolutions.tsx';
|
import type { ProjectStatusDocument } from '../Projects/ListProjectSolutions.tsx';
|
||||||
@@ -145,7 +143,7 @@ export function FavoriteRoadmaps(props: FavoriteRoadmapsProps) {
|
|||||||
<>
|
<>
|
||||||
No AI roadmaps found
|
No AI roadmaps found
|
||||||
<a
|
<a
|
||||||
href="/ai"
|
href="/ai-roadmaps"
|
||||||
className="ml-1.5 inline-flex items-center gap-1 font-medium text-blue-500 underline-offset-2 hover:underline"
|
className="ml-1.5 inline-flex items-center gap-1 font-medium text-blue-500 underline-offset-2 hover:underline"
|
||||||
>
|
>
|
||||||
<SquareCheckBig className="size-3.5" strokeWidth={2.5} />
|
<SquareCheckBig className="size-3.5" strokeWidth={2.5} />
|
||||||
@@ -160,7 +158,7 @@ export function FavoriteRoadmaps(props: FavoriteRoadmapsProps) {
|
|||||||
resourceId={aiRoadmap.id}
|
resourceId={aiRoadmap.id}
|
||||||
resourceType={'roadmap'}
|
resourceType={'roadmap'}
|
||||||
resourceTitle={aiRoadmap.title}
|
resourceTitle={aiRoadmap.title}
|
||||||
url={`/ai/${aiRoadmap.slug}`}
|
url={`/ai-roadmaps/${aiRoadmap.slug}`}
|
||||||
percentageDone={0}
|
percentageDone={0}
|
||||||
allowFavorite={false}
|
allowFavorite={false}
|
||||||
isTrackable={false}
|
isTrackable={false}
|
||||||
@@ -168,7 +166,7 @@ export function FavoriteRoadmaps(props: FavoriteRoadmapsProps) {
|
|||||||
))}
|
))}
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/ai"
|
href="/ai-roadmaps"
|
||||||
className={
|
className={
|
||||||
'flex h-full w-full items-center justify-center gap-1 overflow-hidden rounded-md border border-dashed border-gray-800 p-3 text-sm text-gray-400 hover:border-gray-600 hover:bg-gray-900 hover:text-gray-300'
|
'flex h-full w-full items-center justify-center gap-1 overflow-hidden rounded-md border border-dashed border-gray-800 p-3 text-sm text-gray-400 hover:border-gray-600 hover:bg-gray-900 hover:text-gray-300'
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,6 @@ import { AccountDropdown } from './AccountDropdown';
|
|||||||
import { CourseAnnouncement } from '../SQLCourse/CourseAnnouncement';
|
import { CourseAnnouncement } from '../SQLCourse/CourseAnnouncement';
|
||||||
---
|
---
|
||||||
|
|
||||||
<CourseAnnouncement client:load />
|
|
||||||
|
|
||||||
<div class='bg-slate-900 py-5 text-white sm:py-8'>
|
<div class='bg-slate-900 py-5 text-white sm:py-8'>
|
||||||
<nav class='container flex items-center justify-between'>
|
<nav class='container flex items-center justify-between'>
|
||||||
<div class='flex items-center gap-5'>
|
<div class='flex items-center gap-5'>
|
||||||
@@ -21,7 +19,7 @@ import { CourseAnnouncement } from '../SQLCourse/CourseAnnouncement';
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href='/ai-tutor'
|
href='/ai'
|
||||||
class='group relative inline text-gray-400 hover:text-white sm:hidden'
|
class='group relative inline text-gray-400 hover:text-white sm:hidden'
|
||||||
>
|
>
|
||||||
AI Tutor
|
AI Tutor
|
||||||
@@ -35,7 +33,7 @@ import { CourseAnnouncement } from '../SQLCourse/CourseAnnouncement';
|
|||||||
</a>
|
</a>
|
||||||
<RoadmapDropdownMenu client:load />
|
<RoadmapDropdownMenu client:load />
|
||||||
<a
|
<a
|
||||||
href='/ai-tutor'
|
href='/ai'
|
||||||
class='group relative mr-3 text-blue-300 hover:text-white'
|
class='group relative mr-3 text-blue-300 hover:text-white'
|
||||||
>
|
>
|
||||||
AI Tutor
|
AI Tutor
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
BadgeCheck,
|
BadgeCheck,
|
||||||
HeartHandshake,
|
HeartHandshake,
|
||||||
Telescope,
|
Telescope,
|
||||||
type LucideIcon,
|
type LucideIcon,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { cn } from '../lib/classname';
|
import { cn } from '../lib/classname';
|
||||||
@@ -56,7 +56,7 @@ export function RoadmapAlert(props: RoadmapAlertProps) {
|
|||||||
Community Roadmaps
|
Community Roadmaps
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="/ai/explore"
|
href="/ai-roadmaps/explore"
|
||||||
className="flex items-center gap-1.5 rounded-md border border-yellow-600 px-2 py-1 text-yellow-700 transition-colors hover:bg-yellow-300 hover:text-yellow-800"
|
className="flex items-center gap-1.5 rounded-md border border-yellow-600 px-2 py-1 text-yellow-700 transition-colors hover:bg-yellow-300 hover:text-yellow-800"
|
||||||
>
|
>
|
||||||
<Telescope size={15} />
|
<Telescope size={15} />
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { ChevronDown, Globe, Menu, Sparkles, Map } from 'lucide-react';
|
import { ChevronDown, Globe, Sparkles, Map } from 'lucide-react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import { useOutsideClick } from '../../hooks/use-outside-click';
|
import { useOutsideClick } from '../../hooks/use-outside-click';
|
||||||
import { cn } from '../../lib/classname';
|
import { cn } from '../../lib/classname';
|
||||||
import {
|
import {
|
||||||
@@ -17,7 +17,7 @@ const links = [
|
|||||||
isHighlighted: true,
|
isHighlighted: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
link: '/ai',
|
link: '/ai-roadmaps',
|
||||||
label: 'AI Roadmaps',
|
label: 'AI Roadmaps',
|
||||||
description: 'Generate roadmaps with AI',
|
description: 'Generate roadmaps with AI',
|
||||||
Icon: Sparkles,
|
Icon: Sparkles,
|
||||||
|
@@ -13,7 +13,7 @@ date: 2025-04-03
|
|||||||
|
|
||||||
We have revised the C++ and Java roadmaps and introduced an AI tutor to help you learn anything.
|
We have revised the C++ and Java roadmaps and introduced an AI tutor to help you learn anything.
|
||||||
|
|
||||||
- We just launched an [AI Tutor](https://roadmap.sh/ai-tutor), just give it a topic, pick a difficulty level and it will generate a personalized study plan for you. There is a map view, quizzes an embedded chat to help you along the way.
|
- We just launched an [AI Tutor](https://roadmap.sh/ai), just give it a topic, pick a difficulty level and it will generate a personalized study plan for you. There is a map view, quizzes an embedded chat to help you along the way.
|
||||||
- [C++ roadmap](https://roadmap.sh/cpp) has been revised with improved content
|
- [C++ roadmap](https://roadmap.sh/cpp) has been revised with improved content
|
||||||
- We have also redrawn the [Java roadmap](https://roadmap.sh/java) from scratch, replacing the deprecated items, adding new content and improving the overall structure.
|
- We have also redrawn the [Java roadmap](https://roadmap.sh/java) from scratch, replacing the deprecated items, adding new content and improving the overall structure.
|
||||||
|
|
||||||
|
@@ -131,7 +131,7 @@ export async function generateCourse(options: GenerateCourseOptions) {
|
|||||||
difficulty,
|
difficulty,
|
||||||
},
|
},
|
||||||
'',
|
'',
|
||||||
`${origin}/ai-tutor/${extractedCourseSlug}`,
|
`${origin}/ai/${extractedCourseSlug}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@ import Clarity from '../components/Analytics/Clarity.astro';
|
|||||||
import RedditPixel from '../components/Analytics/RedditPixel.astro';
|
import RedditPixel from '../components/Analytics/RedditPixel.astro';
|
||||||
import GoogleAd from '../components/Analytics/GoogleAd.astro';
|
import GoogleAd from '../components/Analytics/GoogleAd.astro';
|
||||||
import GoogleAdSlot from '../components/Analytics/GoogleAdSlot.astro';
|
import GoogleAdSlot from '../components/Analytics/GoogleAdSlot.astro';
|
||||||
|
import { CourseAnnouncement } from '../components/SQLCourse/CourseAnnouncement';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -165,6 +166,9 @@ const gaPageIdentifier = Astro.url.pathname
|
|||||||
<GoogleAd />
|
<GoogleAd />
|
||||||
</head>
|
</head>
|
||||||
<body class='flex min-h-screen flex-col'>
|
<body class='flex min-h-screen flex-col'>
|
||||||
|
<slot name='course-announcement'>
|
||||||
|
<CourseAnnouncement client:load />
|
||||||
|
</slot>
|
||||||
<slot name='page-header'>
|
<slot name='page-header'>
|
||||||
<Navigation />
|
<Navigation />
|
||||||
</slot>
|
</slot>
|
||||||
|
@@ -7,6 +7,7 @@ const props = Astro.props;
|
|||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout {...props}>
|
<BaseLayout {...props}>
|
||||||
|
<div slot='course-announcement'></div>
|
||||||
<div slot='page-header'></div>
|
<div slot='page-header'></div>
|
||||||
<slot />
|
<slot />
|
||||||
<div slot='page-footer'></div>
|
<div slot='page-footer'></div>
|
||||||
|
@@ -3,7 +3,7 @@ import { ExploreAIRoadmap } from '../../components/ExploreAIRoadmap/ExploreAIRoa
|
|||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title='Explore AI Generated Roadmaps' permalink="/ai/explore">
|
<BaseLayout title='Explore AI Generated Roadmaps' permalink="/ai-roadmaps/explore">
|
||||||
<ExploreAIRoadmap client:load />
|
<ExploreAIRoadmap client:load />
|
||||||
<div slot="changelog-banner" />
|
<div slot="changelog-banner" />
|
||||||
</BaseLayout>
|
</BaseLayout>
|
10
src/pages/ai-roadmaps/index.astro
Normal file
10
src/pages/ai-roadmaps/index.astro
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
import { GenerateRoadmap } from '../../components/GenerateRoadmap/GenerateRoadmap';
|
||||||
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
|
import { CheckSubscriptionVerification } from '../../components/Billing/CheckSubscriptionVerification';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout title='Roadmap AI' permalink='/ai-roadmaps'>
|
||||||
|
<GenerateRoadmap client:load />
|
||||||
|
<CheckSubscriptionVerification client:load />
|
||||||
|
</BaseLayout>
|
@@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
import { AICourse } from '../../components/GenerateCourse/AICourse';
|
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
|
||||||
import { CheckSubscriptionVerification } from '../../components/Billing/CheckSubscriptionVerification';
|
|
||||||
|
|
||||||
const ogImage = 'https://roadmap.sh/og-images/ai-tutor.png';
|
|
||||||
---
|
|
||||||
|
|
||||||
<BaseLayout
|
|
||||||
title='AI Tutor'
|
|
||||||
noIndex={true}
|
|
||||||
ogImageUrl={ogImage}
|
|
||||||
description='Learn anything with AI Tutor. Pick a topic, and the AI will guide you through the learning process.'
|
|
||||||
>
|
|
||||||
<AICourse client:load />
|
|
||||||
<CheckSubscriptionVerification client:load />
|
|
||||||
</BaseLayout>
|
|
@@ -17,8 +17,9 @@ const { courseSlug } = 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-tutor/${courseSlug}`}
|
canonicalUrl={`/ai/${courseSlug}`}
|
||||||
>
|
>
|
||||||
|
<div slot='course-announcement'></div>
|
||||||
<GetAICourse client:load courseSlug={courseSlug} />
|
<GetAICourse client:load courseSlug={courseSlug} />
|
||||||
<CheckSubscriptionVerification client:load />
|
<CheckSubscriptionVerification client:load />
|
||||||
</SkeletonLayout>
|
</SkeletonLayout>
|
@@ -1,10 +1,18 @@
|
|||||||
---
|
---
|
||||||
import { GenerateRoadmap } from '../../components/GenerateRoadmap/GenerateRoadmap';
|
import { AICourse } from '../../components/GenerateCourse/AICourse';
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
import { CheckSubscriptionVerification } from '../../components/Billing/CheckSubscriptionVerification';
|
import { CheckSubscriptionVerification } from '../../components/Billing/CheckSubscriptionVerification';
|
||||||
|
|
||||||
|
const ogImage = 'https://roadmap.sh/og-images/ai-tutor.png';
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title='Roadmap AI' permalink='/ai'>
|
<BaseLayout
|
||||||
<GenerateRoadmap client:load />
|
title='Roadmap AI'
|
||||||
|
noIndex={true}
|
||||||
|
ogImageUrl={ogImage}
|
||||||
|
description='Learn anything with AI Tutor. Pick a topic, choose a difficulty level and the AI will guide you through the learning process.'
|
||||||
|
>
|
||||||
|
<div slot='course-announcement'></div>
|
||||||
|
<AICourse client:load />
|
||||||
<CheckSubscriptionVerification client:load />
|
<CheckSubscriptionVerification client:load />
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
@@ -9,7 +9,8 @@ import { CheckSubscriptionVerification } from '../../components/Billing/CheckSub
|
|||||||
briefTitle='AI Tutor'
|
briefTitle='AI Tutor'
|
||||||
description='AI Tutor'
|
description='AI Tutor'
|
||||||
keywords={['ai', 'tutor', 'education', 'learning']}
|
keywords={['ai', 'tutor', 'education', 'learning']}
|
||||||
canonicalUrl='/ai-tutor/search'
|
canonicalUrl='/ai/search'
|
||||||
|
noIndex={true}
|
||||||
>
|
>
|
||||||
<GenerateAICourse client:load />
|
<GenerateAICourse client:load />
|
||||||
<CheckSubscriptionVerification client:load />
|
<CheckSubscriptionVerification client:load />
|
Reference in New Issue
Block a user