From 857dab3faea5361d84fed4ad83c9f97dd80b2050 Mon Sep 17 00:00:00 2001 From: khushbu-25 Date: Thu, 16 Jul 2026 11:33:57 +0530 Subject: [PATCH 1/2] Added filter/search functionality and course separation (AI-1/AI-2) to the My Notes profile view Added a search/filter to the "My Notes" profile page that filter notes by note text or slide content & Course-based separation (AI-1 / AI-2) --- packages/alea-frontend/pages/my-notes.tsx | 210 +++++++++++++++++++--- packages/comments/src/lib/CommentView.tsx | 26 ++- packages/comments/src/lib/notes-view.tsx | 84 +++++++-- 3 files changed, 273 insertions(+), 47 deletions(-) diff --git a/packages/alea-frontend/pages/my-notes.tsx b/packages/alea-frontend/pages/my-notes.tsx index d7444dd5f..6b96c7ba6 100644 --- a/packages/alea-frontend/pages/my-notes.tsx +++ b/packages/alea-frontend/pages/my-notes.tsx @@ -1,10 +1,26 @@ -import { Box, CircularProgress, Typography } from '@mui/material'; +import { + Box, + CircularProgress, + Typography, + TextField, + Select, + FormControl, + InputLabel, + List, + ListItemButton, + ListItemText, + ListItemIcon, + MenuItem, + useTheme, +} from '@mui/material'; +import type { Theme } from '@mui/material/styles'; +import FolderIcon from '@mui/icons-material/Folder'; +import LibraryBooksIcon from '@mui/icons-material/LibraryBooks'; import { getMyNotesSections } from '@alea/spec'; import { NotesView } from '@alea/comments'; import type { NextPage } from 'next'; import { useEffect, useState } from 'react'; import MainLayout from '../layouts/MainLayout'; -import { SafeFTMLFragment } from '@alea/stex-react-renderer'; export interface NotesSection { uri: string; @@ -20,9 +36,12 @@ interface GroupedNotes { } const MyNotesPage: NextPage = () => { + const theme = useTheme(); const [sections, setSections] = useState([]); const [groupedNotes, setGroupedNotes] = useState({}); const [loading, setLoading] = useState(true); + const [searchQuery, setSearchQuery] = useState(''); + const [selectedCourse, setSelectedCourse] = useState('all'); useEffect(() => { getMyNotesSections() @@ -52,33 +71,176 @@ const MyNotesPage: NextPage = () => { return ( - - {Object.entries(groupedNotes).map(([courseId, instances]) => ( - - {Object.entries(instances).map(([instanceId, sections]) => ( - - - {courseId.toUpperCase()} ({instanceId}) - - {sections.map((section) => ( - - {/* TODO ALeA4-N8: FTMLFragment won't render slides using URI - it uses HTML. This case will be handled later */} - - - - ))} - + + + + Courses + + + setSelectedCourse('all')} + sx={myNotesPageStyles.listItemButton} + > + + + + + All Courses + + } + /> + + {Object.keys(groupedNotes).map((courseId) => ( + setSelectedCourse(courseId)} + sx={myNotesPageStyles.listItemButton} + > + + + + + {courseId.toUpperCase()} + + } + /> + ))} + + + + + + {selectedCourse === 'all' ? 'All Notes' : `${selectedCourse.toUpperCase()} $Notes`} + + + setSearchQuery(e.target.value)} + sx={myNotesPageStyles.searchField(theme)} + /> + + Course + + + + + {Object.entries(groupedNotes) + .filter(([courseId]) => selectedCourse === 'all' || courseId === selectedCourse) + .map(([courseId, instances]) => ( + + {Object.entries(instances).map(([instanceId, sections]) => ( + + + {courseId.toUpperCase()} ({instanceId}) + + {sections.map((section) => ( + + ))} + + ))} + + ))} - ))} + ); }; +const myNotesPageStyles = { + sidebar: { + width: 240, + borderRight: '1px solid', + borderColor: 'divider', + display: { xs: 'none', md: 'block' }, + }, + listItemButton: { + borderRadius: 2, + mb: 1, + '&.Mui-selected': { + bgcolor: 'action.selected', + color: 'primary.main', + '&:hover': { bgcolor: 'action.hover' }, + }, + }, + listItemIcon: { + minWidth: 40, + color: 'text.secondary', + }, + searchField: (theme: Theme) => ({ + '& .MuiOutlinedInput-root': { + borderRadius: 4, + bgcolor: 'background.paper', + boxShadow: theme.shadows[1], + }, + }), + mobileSelect: { + borderRadius: 3, + }, +}; + export default MyNotesPage; diff --git a/packages/comments/src/lib/CommentView.tsx b/packages/comments/src/lib/CommentView.tsx index e8cb8c34a..a7aa768ec 100644 --- a/packages/comments/src/lib/CommentView.tsx +++ b/packages/comments/src/lib/CommentView.tsx @@ -1,5 +1,6 @@ import { Comment } from '@alea/spec'; import { useState } from 'react'; +import { Box } from '@mui/material'; import { CommentLabel } from './CommentLabel'; import { CommentReply } from './CommentReply'; import { EditView } from './EditView'; @@ -14,22 +15,22 @@ export function CommentView({ comment, onUpdate }: { comment: Comment; onUpdate: const [editingComment, setEditingComment] = useState(false); return ( - <> + -
+
{!comment.isDeleted && (
{!editingComment && ( -
+ -
+ )} )}
-
- +
+ ); } + +const commentViewStyles = { + card: { + mb: 1, + p: 0.5, + bgcolor: 'background.default', + borderRadius: 3, + border: '1px solid', + borderColor: 'divider', + transition: 'background-color 0.2s', + '&:hover': { bgcolor: 'action.hover' }, + }, +}; diff --git a/packages/comments/src/lib/notes-view.tsx b/packages/comments/src/lib/notes-view.tsx index 4d645c346..3c7d8ab2d 100644 --- a/packages/comments/src/lib/notes-view.tsx +++ b/packages/comments/src/lib/notes-view.tsx @@ -1,12 +1,12 @@ import { FTML } from '@flexiformal/ftml'; import { Refresh } from '@mui/icons-material'; -import { Box, IconButton } from '@mui/material'; +import { Box, IconButton, Link, Typography, useTheme } from '@mui/material'; +import type { Theme } from '@mui/material/styles'; import { Comment } from '@alea/spec'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import { getPrivateNotes, refreshAllComments } from './comment-store-manager'; import { CommentReply } from './CommentReply'; -import styles from './comments.module.scss'; import { CommentView } from './CommentView'; import { getLocaleObject } from './lang/utils'; import { useCommentRefresh, useCurrentUser } from '@alea/react-utils'; @@ -16,13 +16,20 @@ export function NotesView({ selectedText = undefined, selectedElement = undefined, allNotesMode = false, + searchQuery = '', + courseId = '', + courseTerm = '', }: { uri: FTML.Uri; selectedText?: string; selectedElement?: any; allNotesMode?: boolean; + searchQuery?: string; + courseId?: string; + courseTerm?: string; }) { const t = getLocaleObject(useRouter()); + const theme = useTheme(); const [notes, setNotes] = useState([] as Comment[]); const { refreshKey } = useCommentRefresh(); const { user } = useCurrentUser(); @@ -38,33 +45,45 @@ export function NotesView({ if (!userId) return; getPrivateNotes(uri).then((c) => setNotes(c)); }, [uri, userId, refreshKey]); + const filteredNotes = notes.filter( + (note) => + (courseId === '' || note.courseId === courseId) && + (courseTerm === '' || note.courseTerm === courseTerm) && + (searchQuery === '' || + (note.statement && note.statement.toLowerCase().includes(searchQuery.toLowerCase()))) + ); + if (searchQuery !== '' && filteredNotes.length === 0) return null; if (!userId) return ( - {t.loginForNotes} - + ); return ( -
-
- {notes.length} notes - - refreshNotes()}> - - - -
+ + + + {filteredNotes.length} {filteredNotes.length === 1 ? 'note' : 'notes'}{' '} + + refreshNotes()} + size="small" + sx={{ color: 'text.secondary', bgcolor: 'action.hover' }} + > + + + -
+ {!allNotesMode && ( )} - {notes.map((note) => ( + {filteredNotes.map((note) => ( refreshNotes()} /> ))} -
+ ); } + +const notesViewStyles = { + card: (theme: Theme) => ({ + border: '1px solid', + borderColor: 'divider', + borderRadius: 4, + p: 3, + mb: 3, + boxShadow: theme.shadows[2], + bgcolor: 'background.paper', + transition: 'transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out', + '&:hover': { + transform: 'translateY(-2px)', + boxShadow: theme.shadows[4], + }, + }), + countLabel: { + color: 'text.secondary', + fontWeight: 600, + textTransform: 'uppercase', + letterSpacing: '0.5px', + }, + divider: { + borderBottom: '1px solid', + borderColor: 'divider', + mb: 3, + }, + loginLink: { + textDecoration: 'underline', + }, +}; From 5d076a0dfd88e624f876b75c1481675e89f8b830 Mon Sep 17 00:00:00 2001 From: khushbu-25 Date: Thu, 16 Jul 2026 11:42:32 +0530 Subject: [PATCH 2/2] minor-fixed --- packages/alea-frontend/pages/my-notes.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/alea-frontend/pages/my-notes.tsx b/packages/alea-frontend/pages/my-notes.tsx index 6b96c7ba6..660a41962 100644 --- a/packages/alea-frontend/pages/my-notes.tsx +++ b/packages/alea-frontend/pages/my-notes.tsx @@ -133,7 +133,7 @@ const MyNotesPage: NextPage = () => { mb={4} letterSpacing="-0.02em" > - {selectedCourse === 'all' ? 'All Notes' : `${selectedCourse.toUpperCase()} $Notes`} + {selectedCourse === 'all' ? 'All Notes' : `${selectedCourse.toUpperCase()} Notes`}