@@ -106,254 +106,6 @@ <h2 id="modalNoteTitle"></h2>
106106
107107 <!-- JavaScript -->
108108 < script src ="../scripts/script.js "> </ script >
109-
110- < script >
111- document . addEventListener ( 'DOMContentLoaded' , ( ) => {
112- // DOM Elements
113- const notesGrid = document . getElementById ( 'notesGrid' )
114- const loadingMessage = document . getElementById ( 'loadingMessage' )
115- const noNotesMessage = document . getElementById ( 'noNotesMessage' )
116- const searchInput = document . getElementById ( 'searchInput' )
117- const branchFilter = document . getElementById ( 'branchFilter' )
118- const semesterFilter = document . getElementById ( 'semesterFilter' )
119- const resetFiltersBtn = document . getElementById ( 'resetFilters' )
120- const noteDetailModal = document . getElementById ( 'noteDetailModal' )
121- const closeModalButton = noteDetailModal . querySelector ( '.close-button' )
122-
123- // Modal Elements
124- const modalElements = {
125- title : document . getElementById ( 'modalNoteTitle' ) ,
126- branch : document . getElementById ( 'modalNoteBranch' ) ,
127- semester : document . getElementById ( 'modalNoteSemester' ) ,
128- description : document . getElementById ( 'modalNoteDescription' ) ,
129- uploader : document . getElementById ( 'modalNoteUploader' ) ,
130- uploadDate : document . getElementById ( 'modalNoteUploadDate' ) ,
131- downloadButton : document . getElementById ( 'modalDownloadButton' ) ,
132- }
133-
134- let allNotes = [ ]
135- let branches = new Set ( )
136- let semesters = new Set ( )
137-
138- // Initialize Page
139- async function init ( ) {
140- await fetchNotes ( )
141- populateFilters ( )
142- setupEventListeners ( )
143- }
144-
145- // Fetch Notes From JSON File
146- async function fetchNotes ( ) {
147- loadingMessage . style . display = 'block'
148- noNotesMessage . style . display = 'none'
149- notesGrid . innerHTML = ''
150-
151- try {
152- const response = await fetch ( '../data/notes.json' )
153- if ( ! response . ok ) throw new Error ( 'Network response was not ok' )
154-
155- allNotes = await response . json ( )
156-
157- // Notes Filter
158- allNotes . forEach ( ( note ) => {
159- branches . add ( note . branch )
160- semesters . add ( note . semester )
161- } )
162-
163- displayNotes ( allNotes )
164- } catch ( error ) {
165- console . error ( 'Error fetching notes:' , error )
166- showErrorMessage ( 'Failed to load notes. Please try again later.' )
167- } finally {
168- loadingMessage . style . display = 'none'
169- }
170- }
171-
172- // Filter Dropdown
173- function populateFilters ( ) {
174- // Clear Existing Filter (Default - All)
175- while ( branchFilter . options . length > 1 ) branchFilter . remove ( 1 )
176- while ( semesterFilter . options . length > 1 ) semesterFilter . remove ( 1 )
177-
178- // Add Branches
179- const sortedBranches = Array . from ( branches ) . sort ( )
180- sortedBranches . forEach ( ( branch ) => {
181- const option = document . createElement ( 'option' )
182- option . value = branch
183- option . textContent = branch
184- branchFilter . appendChild ( option )
185- } )
186-
187- // Add Semesters
188- const sortedSemesters = Array . from ( semesters ) . sort ( ( a , b ) => {
189- // Extract Numbers From Semester String For Proper Sorting
190- const numA = parseInt ( a )
191- const numB = parseInt ( b )
192- return numA - numB
193- } )
194- sortedSemesters . forEach ( ( semester ) => {
195- const option = document . createElement ( 'option' )
196- option . value = semester
197- option . textContent = semester
198- semesterFilter . appendChild ( option )
199- } )
200- }
201-
202- // Display Notes (Grid Layout)
203- function displayNotes ( notes ) {
204- notesGrid . innerHTML = ''
205-
206- if ( notes . length === 0 ) {
207- noNotesMessage . style . display = 'block'
208- return
209- }
210-
211- noNotesMessage . style . display = 'none'
212-
213- notes . forEach ( ( note ) => {
214- const noteCard = createNoteCard ( note )
215- notesGrid . appendChild ( noteCard )
216- } )
217- }
218-
219- // Create Note Card Element
220- function createNoteCard ( note ) {
221- const noteCard = document . createElement ( 'div' )
222- noteCard . classList . add ( 'note-card' )
223- noteCard . setAttribute ( 'data-note-id' , note . _id )
224-
225- noteCard . innerHTML = `
226- <h3>${ note . title } </h3>
227- <p><strong>Branch:</strong> ${ note . branch } </p>
228- <p><strong>Semester:</strong> ${ note . semester } </p>
229- <p><strong>Uploaded By:</strong> ${ note . uploader } </p>
230- <div class="actions">
231- <button class="view-button"><i class="fas fa-eye"></i> View</button>
232- <a class="download-button" href="${
233- note . filePath || '#'
234- } " download="${ getDownloadFilename ( note ) } ">
235- <i class="fas fa-download"></i> Download
236- </a>
237- </div>
238- `
239-
240- // Event listener ("View" Button)
241- noteCard
242- . querySelector ( '.view-button' )
243- . addEventListener ( 'click' , ( ) => openNoteDetailModal ( note ) )
244- return noteCard
245- }
246-
247- // Generate Download Filename
248- function getDownloadFilename ( note ) {
249- return `${ note . title . replace ( / \s / g, '_' ) } .pdf`
250- }
251-
252- // Open Note Modal
253- function openNoteDetailModal ( note ) {
254- modalElements . title . textContent = note . title
255- modalElements . branch . textContent = note . branch
256- modalElements . semester . textContent = note . semester
257- modalElements . description . textContent =
258- note . description || 'No description available'
259- modalElements . uploader . textContent = note . uploader
260- modalElements . uploadDate . textContent = note . uploadDate
261- ? new Date ( note . uploadDate ) . toLocaleDateString ( )
262- : 'Unknown date'
263-
264- if ( note . filePath ) {
265- modalElements . downloadButton . href = note . filePath
266- modalElements . downloadButton . setAttribute (
267- 'download' ,
268- getDownloadFilename ( note )
269- )
270- modalElements . downloadButton . style . display = 'inline-flex'
271- } else {
272- modalElements . downloadButton . style . display = 'none'
273- }
274-
275- noteDetailModal . style . display = 'flex'
276- document . body . style . overflow = 'hidden' // No Scrolling (Modal Open)
277- }
278-
279- // Close Note Modal
280- function closeNoteDetailModal ( ) {
281- noteDetailModal . style . display = 'none'
282- document . body . style . overflow = 'auto' // Enable Scrolling (Modal Close)
283- }
284-
285- // Show Error Message
286- function showErrorMessage ( message ) {
287- const errorElement = document . createElement ( 'p' )
288- errorElement . className = 'error-message'
289- errorElement . textContent = message
290- notesGrid . appendChild ( errorElement )
291- }
292-
293- // Filter Notes Based On All Active Filters
294- function filterNotes ( ) {
295- const searchQuery = searchInput . value . toLowerCase ( ) . trim ( )
296- const selectedBranch = branchFilter . value
297- const selectedSemester = semesterFilter . value
298-
299- const filteredNotes = allNotes . filter ( ( note ) => {
300- // Text Search (Title & Uploader)
301- const matchesSearch =
302- searchQuery === '' ||
303- note . title . toLowerCase ( ) . includes ( searchQuery ) ||
304- ( note . uploader &&
305- note . uploader . toLowerCase ( ) . includes ( searchQuery ) )
306-
307- // Branch Filter
308- const matchesBranch =
309- selectedBranch === '' || note . branch === selectedBranch
310-
311- // Semester Filter
312- const matchesSemester =
313- selectedSemester === '' || note . semester === selectedSemester
314-
315- return matchesSearch && matchesBranch && matchesSemester
316- } )
317-
318- displayNotes ( filteredNotes )
319- }
320-
321- // Reset All Filters
322- function resetAllFilters ( ) {
323- searchInput . value = ''
324- branchFilter . value = ''
325- semesterFilter . value = ''
326- filterNotes ( )
327- }
328-
329- // Setup Event Listeners
330- function setupEventListeners ( ) {
331- // Search Input
332- searchInput . addEventListener ( 'input' , filterNotes )
333-
334- // Filter Dropdown
335- branchFilter . addEventListener ( 'change' , filterNotes )
336- semesterFilter . addEventListener ( 'change' , filterNotes )
337-
338- // Reset Filters Button
339- resetFiltersBtn . addEventListener ( 'click' , resetAllFilters )
340-
341- // Modal Close Button
342- closeModalButton . addEventListener ( 'click' , closeNoteDetailModal )
343-
344- // Close Modal When Clicking Outside Or Pressing Escape
345- window . addEventListener ( 'click' , ( e ) => {
346- if ( e . target === noteDetailModal ) closeNoteDetailModal ( )
347- } )
348-
349- window . addEventListener ( 'keydown' , ( e ) => {
350- if ( e . key === 'Escape' ) closeNoteDetailModal ( )
351- } )
352- }
353-
354- // Initialize The Page
355- init ( )
356- } )
357- </ script >
109+ < script src ="../scripts/notes.js "> </ script >
358110 </ body >
359111</ html >
0 commit comments