Compare commits

...

5 Commits

Author SHA1 Message Date
kamranahmedse
8506bc1ed2 chore: update dependencies to latest 2025-03-30 00:29:58 +00:00
Kamran Ahmed
0a442493f1 Update sticky course banner 2025-03-28 19:54:54 +00:00
Kamran Ahmed
77b4e78348 Update sticky course banner 2025-03-28 19:52:27 +00:00
Kamran Ahmed
56c9faabe8 Add ai tutor inside ai roadmap topic 2025-03-28 18:15:20 +00:00
Kamran Ahmed
a68ed2e0b8 Remove terms of sale link 2025-03-27 21:21:04 +00:00
5 changed files with 981 additions and 1688 deletions

View File

@@ -29,81 +29,81 @@
"test:e2e": "playwright test"
},
"dependencies": {
"@astrojs/node": "^8.3.4",
"@astrojs/react": "^3.6.2",
"@astrojs/sitemap": "^3.2.0",
"@astrojs/tailwind": "^5.1.2",
"@fingerprintjs/fingerprintjs": "^4.5.0",
"@astrojs/node": "^9.1.3",
"@astrojs/react": "^4.2.2",
"@astrojs/sitemap": "^3.3.0",
"@astrojs/tailwind": "^6.0.2",
"@fingerprintjs/fingerprintjs": "^4.6.1",
"@microsoft/clarity": "^1.0.0",
"@nanostores/react": "^0.8.0",
"@nanostores/react": "^0.8.4",
"@napi-rs/image": "^1.9.2",
"@resvg/resvg-js": "^2.6.2",
"@tanstack/react-query": "^5.59.16",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"astro": "^4.16.1",
"@tanstack/react-query": "^5.70.0",
"@types/react": "^19.0.12",
"@types/react-dom": "^19.0.4",
"astro": "^5.5.5",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"dom-to-image": "^2.6.0",
"dracula-prism": "^2.1.16",
"gray-matter": "^4.0.3",
"htm": "^3.1.1",
"image-size": "^1.1.1",
"jose": "^5.9.4",
"image-size": "^2.0.1",
"jose": "^6.0.10",
"js-cookie": "^3.0.5",
"lucide-react": "^0.452.0",
"luxon": "^3.5.0",
"markdown-it-async": "^2.0.0",
"nanoid": "^5.0.7",
"nanostores": "^0.11.3",
"node-html-parser": "^6.1.13",
"npm-check-updates": "^17.1.3",
"playwright": "^1.48.0",
"prismjs": "^1.29.0",
"react": "^18.3.1",
"react-calendar-heatmap": "^1.9.0",
"react-confetti": "^6.1.0",
"react-dom": "^18.3.1",
"react-textarea-autosize": "^8.5.7",
"lucide-react": "^0.485.0",
"luxon": "^3.6.0",
"markdown-it-async": "^2.2.0",
"nanoid": "^5.1.5",
"nanostores": "^0.11.4",
"node-html-parser": "^7.0.1",
"npm-check-updates": "^17.1.16",
"playwright": "^1.51.1",
"prismjs": "^1.30.0",
"react": "^19.1.0",
"react-calendar-heatmap": "^1.10.0",
"react-confetti": "^6.4.0",
"react-dom": "^19.1.0",
"react-textarea-autosize": "^8.5.8",
"react-tooltip": "^5.28.0",
"reactflow": "^11.11.4",
"rehype-external-links": "^3.0.0",
"remark-parse": "^11.0.0",
"roadmap-renderer": "^1.0.6",
"sanitize-html": "^2.13.1",
"satori": "^0.11.2",
"roadmap-renderer": "^1.0.7",
"sanitize-html": "^2.15.0",
"satori": "^0.12.2",
"satori-html": "^0.3.2",
"sharp": "^0.33.5",
"shiki": "^3.1.0",
"shiki": "^3.2.1",
"slugify": "^1.6.6",
"tailwind-merge": "^2.5.3",
"tailwindcss": "^3.4.13",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.17",
"tiptap-markdown": "^0.8.10",
"turndown": "^7.2.0",
"unified": "^11.0.5",
"zustand": "^4.5.5"
"zustand": "^5.0.3"
},
"devDependencies": {
"@ai-sdk/google": "^1.1.19",
"@playwright/test": "^1.48.0",
"@tailwindcss/typography": "^0.5.15",
"@ai-sdk/google": "^1.2.3",
"@playwright/test": "^1.51.1",
"@tailwindcss/typography": "^0.5.16",
"@types/dom-to-image": "^2.6.7",
"@types/js-cookie": "^3.0.6",
"@types/luxon": "^3.4.2",
"@types/prismjs": "^1.26.4",
"@types/react-calendar-heatmap": "^1.6.7",
"@types/prismjs": "^1.26.5",
"@types/react-calendar-heatmap": "^1.9.0",
"@types/react-slick": "^0.23.13",
"@types/sanitize-html": "^2.13.0",
"@types/sanitize-html": "^2.15.0",
"@types/turndown": "^5.0.5",
"ai": "^4.1.51",
"csv-parser": "^3.0.0",
"gh-pages": "^6.2.0",
"ai": "^4.2.8",
"csv-parser": "^3.2.0",
"gh-pages": "^6.3.0",
"js-yaml": "^4.1.0",
"markdown-it": "^14.1.0",
"openai": "^4.67.3",
"prettier": "^3.3.3",
"openai": "^4.90.0",
"prettier": "^3.5.3",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.6.8",
"tsx": "^4.19.1"
"prettier-plugin-tailwindcss": "^0.6.11",
"tsx": "^4.19.3"
}
}

2532
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
import { useKeydown } from '../../hooks/use-keydown';
import { useOutsideClick } from '../../hooks/use-outside-click';
import { markdownToHtml } from '../../lib/markdown';
import { Ban, Contact, FileText, X } from 'lucide-react';
import { Ban, Contact, FileText, X, ArrowRight } from 'lucide-react';
import { Spinner } from '../ReactIcons/Spinner';
import type { RoadmapNodeDetails } from './GenerateRoadmap';
import { isLoggedIn, removeAuthToken } from '../../lib/jwt';
@@ -35,6 +35,7 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
const [topicHtml, setTopicHtml] = useState('');
const [isStreaming, setIsStreaming] = useState(false);
const topicRef = useRef<HTMLDivElement>(null);
@@ -90,10 +91,14 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
}
setIsLoading(false);
setIsStreaming(true);
await readAIRoadmapContentStream(reader, {
onStream: async (result) => {
setTopicHtml(markdownToHtml(result, false));
},
onStreamEnd(roadmap) {
setIsStreaming(false);
},
});
onTopicContentGenerateComplete?.();
};
@@ -149,8 +154,7 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
className="rounded-xl border border-current px-1.5 py-0.5 text-left text-sm font-medium text-blue-500 sm:text-center"
onClick={onConfigureOpenAI}
>
Need to generate more?{' '}
<span className="font-semibold">Click here.</span>
Need more? <span className="font-semibold">Click here.</span>
</button>
</div>
)}
@@ -200,6 +204,18 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
id="topic-content"
dangerouslySetInnerHTML={{ __html: topicHtml }}
/>
{!isStreaming && (
<div className="mt-4">
<a
href="/ai-tutor"
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
<ArrowRight className="ml-2 h-4 w-4" />
</a>
</div>
)}
</div>
) : (
<div className="flex h-[calc(100%-38px)] flex-col items-center justify-center">

View File

@@ -1,15 +1,22 @@
import { Database, X } from 'lucide-react';
import { useEffect, useState } from 'react';
import { useState, useEffect } from 'react';
import { cn } from '../../lib/classname';
export function CourseAnnouncement() {
const [isVisible, setIsVisible] = useState(true);
const [isVisible, setIsVisible] = useState(false);
if (!isVisible) {
return null;
}
useEffect(() => {
const timer = setTimeout(() => setIsVisible(true), 1700);
return () => clearTimeout(timer);
}, []);
return (
<div className="sticky top-0 z-[91]">
<div
className={cn(
'sticky top-0 z-[91] h-0 overflow-hidden transition-[height] duration-300',
isVisible ? 'sm:h-[36px] h-[30px]' : 'h-0',
)}
>
<a href="/courses/sql" className="flex items-center bg-yellow-400 py-1.5">
<span className="container mx-auto flex items-center justify-start gap-2 text-center sm:justify-center sm:gap-4">
<span className="flex items-center gap-1.5 text-xs font-medium text-black md:text-base">

View File

@@ -426,10 +426,6 @@ export function SQLCoursePage() {
Terms of Use
</a>
<span className="mx-4 hidden md:block">&middot;</span>
<a href="/terms-of-sale" target="_blank" className="text-zinc-500">
Terms of Sale
</a>
<span className="mx-4 hidden md:block">&middot;</span>
<a href="/privacy" target="_blank" className="text-zinc-500">
Privacy Policy
</a>