@@ -17,7 +17,7 @@ import { push } from "firebase/database";
1717/**
1818 * Firebase configuration and initialization.
1919 * This code connects to Firebase, sets up authentication and allows to save and fetch courses as well as user data.
20- * Data Synchronization and caching are also handled.
20+ * Data Synchronization and caching are also handled.
2121 * The firebase realtime database is used to store courses, user data, and reviews.
2222 * If you would like to reuse this project, make sure to configure rules as shown in firebas_rules.json.
2323 */
@@ -56,17 +56,22 @@ export async function connectToFirebase(model) {
5656 // also save filters to local storage
5757 //
5858 const options = JSON . parse ( localStorage . getItem ( "filterOptions" ) ) ;
59- const search = localStorage . getItem ( "search" ) ;
6059 if ( options ) {
6160 model . setFilterOptions ( options ) ;
6261 }
63- if ( search ) {
64- model . setCurrentSearchText ( search ) ;
62+ if ( ! model ?. currentSearchText ) {
63+ const search = localStorage . getItem ( "search" ) ;
64+ if ( search ) {
65+ model . setCurrentSearchText ( search ) ;
66+ }
6567 }
6668
6769 // automaticaly save filter and search to local storage whenever they change
6870 reaction (
69- ( ) => ( { filterOptions : JSON . stringify ( model . filterOptions ) , search : model . currentSearchText } ) ,
71+ ( ) => ( {
72+ filterOptions : JSON . stringify ( model . filterOptions ) ,
73+ search : model . currentSearchText ,
74+ } ) ,
7075 ( { filterOptions, search } ) => {
7176 localStorage . setItem ( "filterOptions" , filterOptions ) ;
7277 localStorage . setItem ( "search" , search ) ;
@@ -86,7 +91,6 @@ export async function connectToFirebase(model) {
8691 model . setReady ( ) ;
8792 }
8893 } ) ;
89-
9094}
9195
9296// fetches all relevant information to create the model
@@ -112,7 +116,7 @@ async function firebaseToModel(model) {
112116
113117/**
114118 * If the userid, favourites or search changes, sync to firebase.
115- * @param {object } model reactive model object
119+ * @param {object } model reactive model object
116120 */
117121export function syncModelToFirebase ( model ) {
118122 reaction (
@@ -141,9 +145,9 @@ export function syncModelToFirebase(model) {
141145
142146/**
143147 * Synchronizes the scroll position of the container to Firebase / local storage.
144- * @param {object } model
145- * @param {* } containerRef
146- * @returns
148+ * @param {object } model
149+ * @param {* } containerRef
150+ * @returns
147151 */
148152export function syncScrollPositionToFirebase ( model , containerRef ) {
149153 if ( ! containerRef ?. current ) return ;
@@ -228,7 +232,7 @@ async function fetchLastUpdatedTimestamp() {
228232
229233/**
230234 * Admin function to add a course to the database.
231- * @param {Array } course
235+ * @param {Array } course
232236 */
233237export async function addCourse ( course ) {
234238 if ( ! auth . currentUser ) throw new Error ( "User must be authenticated" ) ;
@@ -262,9 +266,9 @@ export async function fetchAllCourses() {
262266
263267/**
264268 * Admin function to upload departments and locations to the database.
265- * @param { } departments
266- * @param {* } locations
267- * @returns
269+ * @param { } departments
270+ * @param {* } locations
271+ * @returns
268272 */
269273export async function uploadDepartmentsAndLocations ( departments , locations ) {
270274 if ( departments ) {
@@ -290,7 +294,7 @@ export async function uploadDepartmentsAndLocations(departments, locations) {
290294
291295/**
292296 * Fetches departments and locations from the database.
293- * @param {object } model
297+ * @param {object } model
294298 * @returns {Array } Array of departments and locations
295299 */
296300export async function fetchDepartmentsAndLocations ( model ) {
@@ -318,7 +322,7 @@ export async function fetchDepartmentsAndLocations(model) {
318322
319323/**
320324 * Try to restore the courses from IndexedDB.
321- * @param {object } model
325+ * @param {object } model
322326 * @returns void
323327 * @throws Error if IndexedDB is not available or no courses are found
324328 */
@@ -396,9 +400,11 @@ export async function addReviewForCourse(courseCode, review) {
396400 try {
397401 const reviewsRef = ref ( db , `reviews/${ courseCode } /${ review . uid } ` ) ;
398402 await set ( reviewsRef , review ) ;
399- const updateCourseAvgRating = httpsCallable ( functions , 'updateCourseAvgRating' ) ;
400- await updateCourseAvgRating ( { courseCode } ) ;
401-
403+ const updateCourseAvgRating = httpsCallable (
404+ functions ,
405+ "updateCourseAvgRating"
406+ ) ;
407+ await updateCourseAvgRating ( { courseCode } ) ;
402408 } catch ( error ) {
403409 console . error (
404410 "Error when adding a course to firebase or updating the average:" ,
@@ -408,10 +414,10 @@ export async function addReviewForCourse(courseCode, review) {
408414}
409415
410416/**
411- * Adding a course triggers a firebase function to update the average rating of the course.
417+ * Adding a course triggers a firebase function to update the average rating of the course.
412418 * This function sets up a listener for the average rating of each course, to update the model onChange.
413419 * It also fetches the initial average ratings if the model is not initialized.
414- * @param {object } model
420+ * @param {object } model
415421 */
416422function startAverageRatingListener ( model ) {
417423 const coursesRef = ref ( db , "reviews" ) ;
@@ -458,9 +464,9 @@ function startAverageRatingListener(model) {
458464}
459465
460466/**
461- * Fetches reviews for a specific course.
462- * @param {string } courseCode
463- * @returns
467+ * Fetches reviews for a specific course.
468+ * @param {string } courseCode
469+ * @returns
464470 */
465471export async function getReviewsForCourse ( courseCode ) {
466472 const reviewsRef = ref ( db , `reviews/${ courseCode } ` ) ;
@@ -489,8 +495,8 @@ export async function addCommentToReview(courseCode, reviewUserId, commentObj) {
489495
490496/**
491497 * Get comments for a specific review
492- * @param {string } courseCode
493- * @param {string } reviewUserId
498+ * @param {string } courseCode
499+ * @param {string } reviewUserId
494500 * @returns {Promise<Array<Object>> } Array of comments: { id, userName, text, timestamp }
495501 */
496502export async function getCommentsForReview ( courseCode , reviewUserId ) {
@@ -501,15 +507,15 @@ export async function getCommentsForReview(courseCode, reviewUserId) {
501507 snapshot . forEach ( ( childSnapshot ) => {
502508 comments . push ( {
503509 id : childSnapshot . key ,
504- ...childSnapshot . val ( )
510+ ...childSnapshot . val ( ) ,
505511 } ) ;
506512 } ) ;
507513 return comments ;
508514}
509515/**
510516 * Delete a review for a course (by userId).
511- * @param {string } courseCode
512- * @param {string } userId
517+ * @param {string } courseCode
518+ * @param {string } userId
513519 */
514520export async function deleteReview ( courseCode , userId ) {
515521 const reviewRef = ref ( db , `reviews/${ courseCode } /${ userId } ` ) ;
@@ -518,32 +524,39 @@ export async function deleteReview(courseCode, userId) {
518524
519525/**
520526 * Delete a specific comment from a review.
521- * @param {string } courseCode
527+ * @param {string } courseCode
522528 * @param {string } reviewUserId - UID of the review's author
523529 * @param {string } commentId - ID of the comment (Firebase push key)
524530 */
525531export async function deleteComment ( courseCode , reviewUserId , commentId ) {
526- const commentRef = ref ( db , `reviews/${ courseCode } /${ reviewUserId } /comments/${ commentId } ` ) ;
532+ const commentRef = ref (
533+ db ,
534+ `reviews/${ courseCode } /${ reviewUserId } /comments/${ commentId } `
535+ ) ;
527536 await set ( commentRef , null ) ;
528537}
529538// Delete a review or comment by its ID
530- export const deleteReviewById = async ( courseCode , commentId , parentId = null ) => {
531- const db = getDatabase ( ) ;
532-
533- if ( ! parentId ) {
534- // Top-level review
535- const reviewRef = ref ( db , `reviews/${ courseCode } /${ commentId } ` ) ;
536- await remove ( reviewRef ) ;
537- } else {
538- // Nested reply - remove it from the parent's replies array
539- const parentRef = ref ( db , `reviews/${ courseCode } /${ parentId } ` ) ;
540- const snapshot = await get ( parentRef ) ;
541- if ( snapshot . exists ( ) ) {
542- const parentData = snapshot . val ( ) ;
543- const replies = parentData . replies || [ ] ;
544-
545- const updatedReplies = replies . filter ( ( r ) => r . id !== commentId ) ;
546- await update ( parentRef , { replies : updatedReplies } ) ;
547- }
548- }
549- } ;
539+ export const deleteReviewById = async (
540+ courseCode ,
541+ commentId ,
542+ parentId = null
543+ ) => {
544+ const db = getDatabase ( ) ;
545+
546+ if ( ! parentId ) {
547+ // Top-level review
548+ const reviewRef = ref ( db , `reviews/${ courseCode } /${ commentId } ` ) ;
549+ await remove ( reviewRef ) ;
550+ } else {
551+ // Nested reply - remove it from the parent's replies array
552+ const parentRef = ref ( db , `reviews/${ courseCode } /${ parentId } ` ) ;
553+ const snapshot = await get ( parentRef ) ;
554+ if ( snapshot . exists ( ) ) {
555+ const parentData = snapshot . val ( ) ;
556+ const replies = parentData . replies || [ ] ;
557+
558+ const updatedReplies = replies . filter ( ( r ) => r . id !== commentId ) ;
559+ await update ( parentRef , { replies : updatedReplies } ) ;
560+ }
561+ }
562+ } ;
0 commit comments