diff --git a/app/package-lock.json b/app/package-lock.json index 42839d7..31010f9 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -52,6 +52,7 @@ "input-otp": "^1.4.2", "lucide-react": "^0.562.0", "next-themes": "^0.4.6", + "prism-react-renderer": "^2.4.1", "react": "^19.2.0", "react-day-picker": "^9.13.0", "react-dom": "^19.2.0", @@ -3398,6 +3399,12 @@ "undici-types": "~7.16.0" } }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz", + "integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.2.7", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", @@ -7191,6 +7198,19 @@ "node": ">= 0.8.0" } }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", diff --git a/app/package.json b/app/package.json index e777077..9f6cc17 100644 --- a/app/package.json +++ b/app/package.json @@ -54,6 +54,7 @@ "input-otp": "^1.4.2", "lucide-react": "^0.562.0", "next-themes": "^0.4.6", + "prism-react-renderer": "^2.4.1", "react": "^19.2.0", "react-day-picker": "^9.13.0", "react-dom": "^19.2.0", diff --git a/app/src/api/content.ts b/app/src/api/content.ts index 82445dc..41c665e 100644 --- a/app/src/api/content.ts +++ b/app/src/api/content.ts @@ -47,11 +47,16 @@ export const getProblemsByTopic = async (topicId: string) => { /** * Fetches every problem in the system, ordered by index. + * When page/limit are provided, returns paginated response. * - * @returns A promise resolving to an array of all problem objects. + * @returns A promise resolving to an array of all problem objects, or a paginated object. */ -export const getAllProblems = async () => { - const response = await axios.get(`${API_BASE_URL}/api/content/problems`); +export const getAllProblems = async (page?: number, limit?: number) => { + const params = new URLSearchParams(); + if (page) params.set('page', String(page)); + if (limit) params.set('limit', String(limit)); + const qs = params.toString(); + const response = await axios.get(`${API_BASE_URL}/api/content/problems${qs ? `?${qs}` : ''}`); return response.data; }; diff --git a/app/src/sections/Notes.tsx b/app/src/sections/Notes.tsx index ef1f5fa..9520564 100644 --- a/app/src/sections/Notes.tsx +++ b/app/src/sections/Notes.tsx @@ -9,12 +9,17 @@ import { X, FileText, Clock, - BookOpen + BookOpen, + Eye, + Code2 } from 'lucide-react'; import { Input } from '@/components/ui/input'; import { toast } from 'sonner'; import { getUserProgress, updateNotes } from '@/api/userActions'; import { getAllProblems } from '@/api/content'; +import ReactMarkdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { Highlight, themes } from 'prism-react-renderer'; import { AlertDialog, AlertDialogContent, @@ -42,6 +47,7 @@ export function Notes() { const [isEditing, setIsEditing] = useState(false); const [isCreating, setIsCreating] = useState(false); const [editForm, setEditForm] = useState({ content: '' }); + const [isPreview, setIsPreview] = useState(false); interface Problem { id: string; @@ -106,6 +112,7 @@ export function Notes() { const handleCreate = () => { setIsCreating(true); setIsEditing(true); + setIsPreview(false); setSelectedNote(null); setEditForm({ content: '' }); setNewNoteProblemId(''); @@ -116,6 +123,7 @@ export function Notes() { setSelectedNote(note); setIsEditing(true); setIsCreating(false); + setIsPreview(false); setEditForm({ content: note.content }); }; @@ -325,6 +333,16 @@ export function Notes() { {isCreating ? 'Create Note' : 'Edit Note'}
+ {tokens.map((line, i) => (
+
+ {line.map((token, key) => (
+
+ ))}
+
+ ))}
+
+ )}
+
+ );
+ }
+ return (
+
+ {children}
+
+ );
+ }
+ }}
+ >
{selectedNote.content}
-