mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-13 12:43:59 +02:00
feat: xyflow upgrade (#7803)
* wip * fix: reset the sizes * fix: update zustand * fix: update * fix: add additional width * wip * fix: remove hacky code * wip * wip * wip * wip * wip * fix: try pre-commit * fix: add check pre-commit * fix: remove xyflow * fix: remove unnecessary files * fix: update packages * Update scripts/generate-renderer.sh --------- Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -29,8 +29,3 @@ pnpm-debug.log*
|
|||||||
/playwright/.cache/
|
/playwright/.cache/
|
||||||
tests-examples
|
tests-examples
|
||||||
*.csv
|
*.csv
|
||||||
|
|
||||||
/editor/*
|
|
||||||
!/editor/readonly-editor.tsx
|
|
||||||
!/editor/renderer/renderer.ts
|
|
||||||
!/editor/renderer/index.tsx
|
|
||||||
|
@@ -72,4 +72,9 @@ export default defineConfig({
|
|||||||
}),
|
}),
|
||||||
react(),
|
react(),
|
||||||
],
|
],
|
||||||
|
vite: {
|
||||||
|
ssr: {
|
||||||
|
noExternal: [/^@roadmapsh\/editor.*$/],
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
export function ReadonlyEditor(props: any) {
|
|
||||||
return (
|
|
||||||
<div className="fixed bottom-0 left-0 right-0 top-0 z-[9999] border bg-white p-5 text-black">
|
|
||||||
<h2 className="mb-2 text-xl font-semibold">Private Component</h2>
|
|
||||||
<p className="mb-4">
|
|
||||||
Renderer is a private component. If you are a collaborator and have
|
|
||||||
access to it. Run the following command:
|
|
||||||
</p>
|
|
||||||
<code className="mt-5 rounded-md bg-gray-800 p-2 text-white">
|
|
||||||
npm run generate-renderer
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
export function Renderer(props: any) {
|
|
||||||
return (
|
|
||||||
<div className="fixed bottom-0 left-0 right-0 top-0 z-[9999] border bg-white p-5 text-black">
|
|
||||||
<h2 className="mb-2 text-xl font-semibold">Private Component</h2>
|
|
||||||
<p className="mb-4">
|
|
||||||
Renderer is a private component. If you are a collaborator and have
|
|
||||||
access to it. Run the following command:
|
|
||||||
</p>
|
|
||||||
<code className="mt-5 rounded-md bg-gray-800 p-2 text-white">
|
|
||||||
npm run generate-renderer
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
export function renderFlowJSON(data: any, options?: any) {
|
|
||||||
console.warn("renderFlowJSON is not implemented");
|
|
||||||
console.warn("run the following command to generate the renderer:");
|
|
||||||
console.warn("> npm run generate-renderer");
|
|
||||||
}
|
|
@@ -26,6 +26,7 @@
|
|||||||
"warm:urls": "sh ./scripts/warm-urls.sh https://roadmap.sh/sitemap-0.xml",
|
"warm:urls": "sh ./scripts/warm-urls.sh https://roadmap.sh/sitemap-0.xml",
|
||||||
"compress:images": "tsx ./scripts/compress-images.ts",
|
"compress:images": "tsx ./scripts/compress-images.ts",
|
||||||
"generate:roadmap-content-json": "tsx ./scripts/editor-roadmap-content-json.ts",
|
"generate:roadmap-content-json": "tsx ./scripts/editor-roadmap-content-json.ts",
|
||||||
|
"migrate:editor-roadmaps": "tsx ./scripts/migrate-editor-roadmap.ts",
|
||||||
"test:e2e": "playwright test"
|
"test:e2e": "playwright test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
"@nanostores/react": "^0.8.0",
|
"@nanostores/react": "^0.8.0",
|
||||||
"@napi-rs/image": "^1.9.2",
|
"@napi-rs/image": "^1.9.2",
|
||||||
"@resvg/resvg-js": "^2.6.2",
|
"@resvg/resvg-js": "^2.6.2",
|
||||||
|
"@roadmapsh/editor": "npm:@roadmapsh/dummy-editor@^0.0.5",
|
||||||
"@tanstack/react-query": "^5.59.16",
|
"@tanstack/react-query": "^5.59.16",
|
||||||
"@types/react": "^18.3.11",
|
"@types/react": "^18.3.11",
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
@@ -67,7 +69,6 @@
|
|||||||
"react-resizable-panels": "^2.1.7",
|
"react-resizable-panels": "^2.1.7",
|
||||||
"react-textarea-autosize": "^8.5.7",
|
"react-textarea-autosize": "^8.5.7",
|
||||||
"react-tooltip": "^5.28.0",
|
"react-tooltip": "^5.28.0",
|
||||||
"reactflow": "^11.11.4",
|
|
||||||
"rehype-external-links": "^3.0.0",
|
"rehype-external-links": "^3.0.0",
|
||||||
"remark-parse": "^11.0.0",
|
"remark-parse": "^11.0.0",
|
||||||
"roadmap-renderer": "^1.0.6",
|
"roadmap-renderer": "^1.0.6",
|
||||||
@@ -82,7 +83,7 @@
|
|||||||
"tiptap-markdown": "^0.8.10",
|
"tiptap-markdown": "^0.8.10",
|
||||||
"turndown": "^7.2.0",
|
"turndown": "^7.2.0",
|
||||||
"unified": "^11.0.5",
|
"unified": "^11.0.5",
|
||||||
"zustand": "^4.5.5"
|
"zustand": "^5.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ai-sdk/google": "^1.1.19",
|
"@ai-sdk/google": "^1.1.19",
|
||||||
|
3138
pnpm-lock.yaml
generated
3138
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,14 +0,0 @@
|
|||||||
export function Renderer(props: any) {
|
|
||||||
return (
|
|
||||||
<div className="fixed bottom-0 left-0 right-0 top-0 z-[9999] border bg-white p-5 text-black">
|
|
||||||
<h2 className="mb-2 text-xl font-semibold">Private Component</h2>
|
|
||||||
<p className="mb-4">
|
|
||||||
Renderer is a private component. If you are a collaborator and have
|
|
||||||
access to it. Run the following command:
|
|
||||||
</p>
|
|
||||||
<code className="mt-5 rounded-md bg-gray-800 p-2 text-white">
|
|
||||||
npm run generate-renderer
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
export function renderFlowJSON(data: any, options?: any) {
|
|
||||||
console.warn("renderFlowJSON is not implemented");
|
|
||||||
console.warn("run the following command to generate the renderer:");
|
|
||||||
console.warn("> npm run generate-renderer");
|
|
||||||
}
|
|
@@ -1,7 +1,7 @@
|
|||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import type { Node } from 'reactflow';
|
import type { Node } from '@roadmapsh/editor';
|
||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
||||||
import { slugify } from '../src/lib/slugger';
|
import { slugify } from '../src/lib/slugger';
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import type { Edge, Node } from 'reactflow';
|
import type { Edge, Node } from '@roadmapsh/editor';
|
||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
||||||
import { slugify } from '../src/lib/slugger';
|
import { slugify } from '../src/lib/slugger';
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import type { Node } from 'reactflow';
|
import type { Node } from '@roadmapsh/editor';
|
||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
||||||
import { slugify } from '../src/lib/slugger';
|
import { slugify } from '../src/lib/slugger';
|
||||||
|
@@ -2,33 +2,10 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# ignore cloning if .temp/web-draw already exists
|
# Fetch the latest commit hash from the GitHub repo
|
||||||
if [ ! -d ".temp/web-draw" ]; then
|
LATEST_COMMIT_HASH=$(git ls-remote https://github.com/roadmapsh/web-draw-v2.git refs/heads/main | awk '{print $1}')
|
||||||
mkdir -p .temp
|
|
||||||
git clone git@github.com:roadmapsh/web-draw.git .temp/web-draw
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf editor
|
echo "Latest commit hash: $LATEST_COMMIT_HASH"
|
||||||
mkdir editor
|
|
||||||
|
|
||||||
# copy the files at /src/editor/* to /editor
|
# Install the package using the latest commit hash
|
||||||
# while replacing any existing files
|
pnpm add github:roadmapsh/web-draw#"$LATEST_COMMIT_HASH"\&path:packages/editor
|
||||||
cp -rf .temp/web-draw/src/editor/* editor
|
|
||||||
|
|
||||||
# Add @ts-nocheck to the top of each ts and tsx file
|
|
||||||
# so that the typescript compiler doesn't complain
|
|
||||||
# about the missing types
|
|
||||||
find editor -type f \( -name "*.ts" -o -name "*.tsx" \) -print0 | while IFS= read -r -d '' file; do
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
echo "// @ts-nocheck" > temp
|
|
||||||
cat "$file" >> temp
|
|
||||||
mv temp "$file"
|
|
||||||
echo "Added @ts-nocheck to $file"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
# ignore the worktree changes for the editor directory
|
|
||||||
git update-index --assume-unchanged editor/readonly-editor.tsx || true
|
|
||||||
git update-index --assume-unchanged editor/renderer/index.tsx || true
|
|
||||||
git update-index --assume-unchanged editor/renderer/renderer.ts || true
|
|
||||||
|
76
scripts/migrate-editor-roadmap.ts
Normal file
76
scripts/migrate-editor-roadmap.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import type { Node } from '@roadmapsh/editor';
|
||||||
|
import matter from 'gray-matter';
|
||||||
|
import type { RoadmapFrontmatter } from '../src/lib/roadmap';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
|
// Directory containing the roadmaps
|
||||||
|
const ROADMAP_CONTENT_DIR = path.join(__dirname, '../src/data/roadmaps');
|
||||||
|
const allRoadmaps = await fs.readdir(ROADMAP_CONTENT_DIR);
|
||||||
|
|
||||||
|
const editorRoadmapIds = new Set<string>();
|
||||||
|
for (const roadmapId of allRoadmaps) {
|
||||||
|
const roadmapFrontmatterDir = path.join(
|
||||||
|
ROADMAP_CONTENT_DIR,
|
||||||
|
roadmapId,
|
||||||
|
`${roadmapId}.md`,
|
||||||
|
);
|
||||||
|
const roadmapFrontmatterRaw = await fs.readFile(
|
||||||
|
roadmapFrontmatterDir,
|
||||||
|
'utf-8',
|
||||||
|
);
|
||||||
|
const { data } = matter(roadmapFrontmatterRaw);
|
||||||
|
|
||||||
|
const roadmapFrontmatter = data as RoadmapFrontmatter;
|
||||||
|
if (roadmapFrontmatter.renderer === 'editor') {
|
||||||
|
editorRoadmapIds.add(roadmapId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const roadmapId of editorRoadmapIds) {
|
||||||
|
const roadmapJSONDir = path.join(
|
||||||
|
ROADMAP_CONTENT_DIR,
|
||||||
|
roadmapId,
|
||||||
|
`${roadmapId}.json`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const roadmapJSONRaw = await fs.readFile(roadmapJSONDir, 'utf-8');
|
||||||
|
const roadmapJSON = JSON.parse(roadmapJSONRaw);
|
||||||
|
|
||||||
|
const roadmapNodes = roadmapJSON.nodes as Node[];
|
||||||
|
const updatedNodes = roadmapNodes.map((node) => {
|
||||||
|
const width = +(node?.width || node?.style?.width || 0);
|
||||||
|
const height = +(node?.height || node?.style?.height || 0);
|
||||||
|
|
||||||
|
const ADDITIONAL_WIDTH = 1;
|
||||||
|
// adding one `1px` in width to avoid the node to be cut in half
|
||||||
|
// this is a quick fix to avoid the issue
|
||||||
|
if (node?.style?.width) {
|
||||||
|
node.style.width = width + ADDITIONAL_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node?.width) {
|
||||||
|
node.width = width + ADDITIONAL_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
measured: {
|
||||||
|
width: width + ADDITIONAL_WIDTH,
|
||||||
|
height,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedRoadmapJSON = {
|
||||||
|
...roadmapJSON,
|
||||||
|
nodes: updatedNodes,
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedRoadmapJSONString = JSON.stringify(updatedRoadmapJSON, null, 2);
|
||||||
|
await fs.writeFile(roadmapJSONDir, updatedRoadmapJSONString, 'utf-8');
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
import { ReadonlyEditor } from '../../../editor/readonly-editor';
|
import { ReadonlyEditor } from '@roadmapsh/editor';
|
||||||
import type { RoadmapDocument } from './CreateRoadmap/CreateRoadmapModal';
|
import type { RoadmapDocument } from './CreateRoadmap/CreateRoadmapModal';
|
||||||
import {
|
import {
|
||||||
refreshProgressCounters,
|
refreshProgressCounters,
|
||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
} from '../../lib/resource-progress';
|
} from '../../lib/resource-progress';
|
||||||
import { pageProgressMessage } from '../../stores/page';
|
import { pageProgressMessage } from '../../stores/page';
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import type { Node } from 'reactflow';
|
import type { Node } from '@roadmapsh/editor';
|
||||||
import { type MouseEvent, useCallback, useRef, useState } from 'react';
|
import { type MouseEvent, useCallback, useRef, useState } from 'react';
|
||||||
import { EmptyRoadmap } from './EmptyRoadmap';
|
import { EmptyRoadmap } from './EmptyRoadmap';
|
||||||
import { cn } from '../../lib/classname';
|
import { cn } from '../../lib/classname';
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { cn } from '../../../editor/utils/classname';
|
|
||||||
import { useParams } from '../../hooks/use-params';
|
import { useParams } from '../../hooks/use-params';
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
@@ -13,6 +12,7 @@ import { TeamDashboard } from './TeamDashboard';
|
|||||||
import type { QuestionGroupType } from '../../lib/question-group';
|
import type { QuestionGroupType } from '../../lib/question-group';
|
||||||
import type { GuideFileType } from '../../lib/guide';
|
import type { GuideFileType } from '../../lib/guide';
|
||||||
import type { VideoFileType } from '../../lib/video';
|
import type { VideoFileType } from '../../lib/video';
|
||||||
|
import { cn } from '../../lib/classname';
|
||||||
|
|
||||||
type DashboardPageProps = {
|
type DashboardPageProps = {
|
||||||
builtInRoleRoadmaps?: BuiltInRoadmap[];
|
builtInRoleRoadmaps?: BuiltInRoadmap[];
|
||||||
|
@@ -11,8 +11,6 @@ import {
|
|||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
import { ProgressNudge } from '../FrameRenderer/ProgressNudge';
|
import { ProgressNudge } from '../FrameRenderer/ProgressNudge';
|
||||||
import { getUrlParams } from '../../lib/browser.ts';
|
import { getUrlParams } from '../../lib/browser.ts';
|
||||||
import { cn } from '../../lib/classname.ts';
|
|
||||||
import { getUser } from '../../lib/jwt.ts';
|
|
||||||
|
|
||||||
type EditorRoadmapProps = {
|
type EditorRoadmapProps = {
|
||||||
resourceId: string;
|
resourceId: string;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { useCallback, useEffect, useRef } from 'react';
|
|
||||||
import './EditorRoadmapRenderer.css';
|
import './EditorRoadmapRenderer.css';
|
||||||
|
|
||||||
|
import { lazy, useCallback, useEffect, useRef } from 'react';
|
||||||
import {
|
import {
|
||||||
renderResourceProgress,
|
renderResourceProgress,
|
||||||
updateResourceProgress,
|
updateResourceProgress,
|
||||||
@@ -9,12 +10,17 @@ import {
|
|||||||
} from '../../lib/resource-progress';
|
} from '../../lib/resource-progress';
|
||||||
import { pageProgressMessage } from '../../stores/page';
|
import { pageProgressMessage } from '../../stores/page';
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import type { Edge, Node } from 'reactflow';
|
import type { Edge, Node } from '@roadmapsh/editor';
|
||||||
import { Renderer } from '../../../editor/renderer';
|
|
||||||
import { slugify } from '../../lib/slugger';
|
import { slugify } from '../../lib/slugger';
|
||||||
import { isLoggedIn } from '../../lib/jwt';
|
import { isLoggedIn } from '../../lib/jwt';
|
||||||
import { showLoginPopup } from '../../lib/popup';
|
import { showLoginPopup } from '../../lib/popup';
|
||||||
|
|
||||||
|
const Renderer = lazy(() =>
|
||||||
|
import('@roadmapsh/editor').then((mod) => ({
|
||||||
|
default: mod.Renderer,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
export type RoadmapRendererProps = {
|
export type RoadmapRendererProps = {
|
||||||
resourceId: string;
|
resourceId: string;
|
||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import '../GenerateRoadmap/GenerateRoadmap.css';
|
import '../GenerateRoadmap/GenerateRoadmap.css';
|
||||||
import { renderFlowJSON } from '../../../editor/renderer/renderer';
|
import { renderFlowJSON } from '@roadmapsh/editor';
|
||||||
import { generateAIRoadmapFromText } from '../../../editor/utils/roadmap-generator';
|
import { generateAIRoadmapFromText } from '@roadmapsh/editor';
|
||||||
import {
|
import {
|
||||||
generateAICourseRoadmapStructure,
|
generateAICourseRoadmapStructure,
|
||||||
readAIRoadmapStream,
|
readAIRoadmapStream,
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import './GenerateRoadmap.css';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type FormEvent,
|
type FormEvent,
|
||||||
type MouseEvent,
|
type MouseEvent,
|
||||||
@@ -6,10 +8,8 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import './GenerateRoadmap.css';
|
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import { generateAIRoadmapFromText } from '../../../editor/utils/roadmap-generator';
|
import { generateAIRoadmapFromText, renderFlowJSON } from '@roadmapsh/editor';
|
||||||
import { renderFlowJSON } from '../../../editor/renderer/renderer';
|
|
||||||
import { replaceChildren } from '../../lib/dom';
|
import { replaceChildren } from '../../lib/dom';
|
||||||
import {
|
import {
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
@@ -278,6 +278,10 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
|||||||
width: undefined,
|
width: undefined,
|
||||||
height: undefined,
|
height: undefined,
|
||||||
},
|
},
|
||||||
|
measured: {
|
||||||
|
width: undefined,
|
||||||
|
height: undefined,
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
edges,
|
edges,
|
||||||
},
|
},
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { ChevronDownIcon, StarIcon, User2Icon } from 'lucide-react';
|
import { ChevronDownIcon, StarIcon, User2Icon } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { cn } from '../../../editor/utils/classname';
|
|
||||||
import { markdownToHtml } from '../../lib/markdown';
|
import { markdownToHtml } from '../../lib/markdown';
|
||||||
|
import { cn } from '../../lib/classname';
|
||||||
|
|
||||||
type Review = {
|
type Review = {
|
||||||
name: string;
|
name: string;
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import '../FrameRenderer/FrameRenderer.css';
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
@@ -6,7 +7,6 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { Spinner } from '../ReactIcons/Spinner';
|
import { Spinner } from '../ReactIcons/Spinner';
|
||||||
import '../FrameRenderer/FrameRenderer.css';
|
|
||||||
import type { TeamMember } from './TeamProgressPage';
|
import type { TeamMember } from './TeamProgressPage';
|
||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
import {
|
import {
|
||||||
@@ -15,13 +15,12 @@ import {
|
|||||||
type ResourceType,
|
type ResourceType,
|
||||||
updateResourceProgress,
|
updateResourceProgress,
|
||||||
} from '../../lib/resource-progress';
|
} from '../../lib/resource-progress';
|
||||||
import CloseIcon from '../../icons/close.svg';
|
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import { useAuth } from '../../hooks/use-auth';
|
import { useAuth } from '../../hooks/use-auth';
|
||||||
import { pageProgressMessage } from '../../stores/page';
|
import { pageProgressMessage } from '../../stores/page';
|
||||||
import type { GetRoadmapResponse } from '../CustomRoadmap/CustomRoadmap';
|
import type { GetRoadmapResponse } from '../CustomRoadmap/CustomRoadmap';
|
||||||
import { ReadonlyEditor } from '../../../editor/readonly-editor';
|
import { ReadonlyEditor } from '@roadmapsh/editor';
|
||||||
import type { Node } from 'reactflow';
|
import type { Node } from '@roadmapsh/editor';
|
||||||
import { useKeydown } from '../../hooks/use-keydown';
|
import { useKeydown } from '../../hooks/use-keydown';
|
||||||
import { useOutsideClick } from '../../hooks/use-outside-click';
|
import { useOutsideClick } from '../../hooks/use-outside-click';
|
||||||
import { MemberProgressModalHeader } from './MemberProgressModalHeader';
|
import { MemberProgressModalHeader } from './MemberProgressModalHeader';
|
||||||
|
@@ -20,7 +20,7 @@ import { MemberProgressModalHeader } from './MemberProgressModalHeader';
|
|||||||
import { replaceChildren } from '../../lib/dom.ts';
|
import { replaceChildren } from '../../lib/dom.ts';
|
||||||
import { XIcon } from 'lucide-react';
|
import { XIcon } from 'lucide-react';
|
||||||
import type { PageType } from '../CommandMenu/CommandMenu.tsx';
|
import type { PageType } from '../CommandMenu/CommandMenu.tsx';
|
||||||
import { renderFlowJSON } from '../../../editor/renderer/renderer.ts';
|
import { renderFlowJSON } from '@roadmapsh/editor';
|
||||||
import { getResourceMeta } from '../../lib/roadmap.ts';
|
import { getResourceMeta } from '../../lib/roadmap.ts';
|
||||||
|
|
||||||
export type ProgressMapProps = {
|
export type ProgressMapProps = {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useMemo, useRef, useState, type RefObject } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useOutsideClick } from '../../hooks/use-outside-click';
|
import { useOutsideClick } from '../../hooks/use-outside-click';
|
||||||
import { useKeydown } from '../../hooks/use-keydown';
|
import { useKeydown } from '../../hooks/use-keydown';
|
||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
@@ -7,7 +7,7 @@ import { topicSelectorAll } from '../../lib/resource-progress';
|
|||||||
import { deleteUrlParam, getUrlParams } from '../../lib/browser';
|
import { deleteUrlParam, getUrlParams } from '../../lib/browser';
|
||||||
import { useAuth } from '../../hooks/use-auth';
|
import { useAuth } from '../../hooks/use-auth';
|
||||||
import type { GetRoadmapResponse } from '../CustomRoadmap/CustomRoadmap';
|
import type { GetRoadmapResponse } from '../CustomRoadmap/CustomRoadmap';
|
||||||
import { ReadonlyEditor } from '../../../editor/readonly-editor';
|
import { ReadonlyEditor } from '@roadmapsh/editor';
|
||||||
import { ModalLoader } from './ModalLoader.tsx';
|
import { ModalLoader } from './ModalLoader.tsx';
|
||||||
import { UserProgressModalHeader } from './UserProgressModalHeader';
|
import { UserProgressModalHeader } from './UserProgressModalHeader';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
@@ -173,7 +173,7 @@ export function UserCustomProgressModal(props: ProgressMapProps) {
|
|||||||
variant="modal"
|
variant="modal"
|
||||||
roadmap={roadmap!}
|
roadmap={roadmap!}
|
||||||
className="min-h-[400px]"
|
className="min-h-[400px]"
|
||||||
onRendered={(wrapperRef: RefObject<HTMLDivElement>) => {
|
onRendered={(wrapperRef) => {
|
||||||
const {
|
const {
|
||||||
done = [],
|
done = [],
|
||||||
learning = [],
|
learning = [],
|
||||||
|
@@ -12,7 +12,7 @@ import { ModalLoader } from './ModalLoader.tsx';
|
|||||||
import { UserProgressModalHeader } from './UserProgressModalHeader';
|
import { UserProgressModalHeader } from './UserProgressModalHeader';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import type { AllowedRoadmapRenderer } from '../../lib/roadmap.ts';
|
import type { AllowedRoadmapRenderer } from '../../lib/roadmap.ts';
|
||||||
import { renderFlowJSON } from '../../../editor/renderer/renderer.ts';
|
import { renderFlowJSON } from '@roadmapsh/editor';
|
||||||
|
|
||||||
export type ProgressMapProps = {
|
export type ProgressMapProps = {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
@@ -8,7 +8,7 @@ import {
|
|||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import { replaceChildren } from '../../lib/dom.ts';
|
import { replaceChildren } from '../../lib/dom.ts';
|
||||||
import type { GetUserProfileRoadmapResponse } from '../../api/user.ts';
|
import type { GetUserProfileRoadmapResponse } from '../../api/user.ts';
|
||||||
import { ReadonlyEditor } from '../../../editor/readonly-editor.tsx';
|
import { ReadonlyEditor } from '@roadmapsh/editor';
|
||||||
import { cn } from '../../lib/classname.ts';
|
import { cn } from '../../lib/classname.ts';
|
||||||
|
|
||||||
export type UserProfileRoadmapRendererProps = GetUserProfileRoadmapResponse & {
|
export type UserProfileRoadmapRendererProps = GetUserProfileRoadmapResponse & {
|
||||||
@@ -96,7 +96,7 @@ export function UserProfileRoadmapRenderer(
|
|||||||
edges,
|
edges,
|
||||||
}}
|
}}
|
||||||
className="min-h-[1000px]"
|
className="min-h-[1000px]"
|
||||||
onRendered={(wrapperRef: RefObject<HTMLDivElement>) => {
|
onRendered={(wrapperRef) => {
|
||||||
done?.forEach((topicId: string) => {
|
done?.forEach((topicId: string) => {
|
||||||
topicSelectorAll(topicId, wrapperRef?.current!).forEach(
|
topicSelectorAll(topicId, wrapperRef?.current!).forEach(
|
||||||
(el) => {
|
(el) => {
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
---
|
---
|
||||||
|
import '../styles/global.css';
|
||||||
|
|
||||||
import Analytics from '../components/Analytics/Analytics.astro';
|
import Analytics from '../components/Analytics/Analytics.astro';
|
||||||
import LoginPopup from '../components/AuthenticationFlow/LoginPopup.astro';
|
import LoginPopup from '../components/AuthenticationFlow/LoginPopup.astro';
|
||||||
import Authenticator from '../components/Authenticator/Authenticator.astro';
|
import Authenticator from '../components/Authenticator/Authenticator.astro';
|
||||||
@@ -10,9 +12,9 @@ import { PageProgress } from '../components/PageProgress';
|
|||||||
import { Toaster } from '../components/Toast';
|
import { Toaster } from '../components/Toast';
|
||||||
import { PageSponsors } from '../components/PageSponsors/PageSponsors';
|
import { PageSponsors } from '../components/PageSponsors/PageSponsors';
|
||||||
import { siteConfig } from '../lib/config';
|
import { siteConfig } from '../lib/config';
|
||||||
import '../styles/global.css';
|
|
||||||
import { PageVisit } from '../components/PageVisit/PageVisit';
|
import { PageVisit } from '../components/PageVisit/PageVisit';
|
||||||
import type { ResourceType } from '../lib/resource-progress';
|
import type { ResourceType } from '../lib/resource-progress';
|
||||||
|
import ChangelogBanner from '../components/ChangelogBanner.astro';
|
||||||
import Clarity from '../components/Analytics/Clarity.astro';
|
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';
|
||||||
|
@@ -1,7 +1,28 @@
|
|||||||
|
@import '@roadmapsh/editor/style.css';
|
||||||
|
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The default border color has changed to `currentColor` in Tailwind CSS v4,
|
||||||
|
so we've added these compatibility styles to make sure everything still
|
||||||
|
looks the same as it did with Tailwind CSS v3.
|
||||||
|
|
||||||
|
If we ever want to remove these styles, we need to add an explicit border
|
||||||
|
color utility to any element that depends on these defaults.
|
||||||
|
*/
|
||||||
|
@layer base {
|
||||||
|
*,
|
||||||
|
::after,
|
||||||
|
::before,
|
||||||
|
::backdrop,
|
||||||
|
::file-selector-button {
|
||||||
|
--color-gray-200: oklch(0.928 0.006 264.531);
|
||||||
|
border-color: var(--color-gray-200, currentColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.container {
|
.container {
|
||||||
@apply mx-auto !max-w-[830px] px-4;
|
@apply mx-auto !max-w-[830px] px-4;
|
||||||
|
Reference in New Issue
Block a user