Source: ai-notes-user-data-access.js

/**
 * Class to handle user data access and management using localStorage.
 * Provides methods to get, insert, update, and delete user data.
 */
class UserDataAccess {

	///////////////////////////////////////////////
	// PRIVATE INSTANCE VARIABLES (start with #)
	///////////////////////////////////////////////

	/**
	 * A dummy data array used to populate the localStorage database if it's empty.
	 * @private
	 * @type {Array<{id: number, firstName: string, lastName: string, email: string}>}
	 */
	#dummyData = [
	    {id:1, firstName:"Jane", lastName:"Doe", email:"jdoe@acme.com"},
	    {id:2, firstName:"Tony", lastName:"Thompsom", email:"tony@acme.com"},
	    {id:3, firstName:"Jesse", lastName:"Jones", email:"jesse@acme.com"}
	];

	//////////////////////////////////
	// CONSTRUCTOR
	//////////////////////////////////
	
	/**
	 * Initializes the UserDataAccess instance. Checks if the 'userData' key exists
	 * in localStorage. If not, it initializes it with dummy data.
	 */
	constructor(){
		// check to see if 'userData' key is already in the localStorage database
		// if not, then create it, and populate it with the dummy data
		if(!localStorage.getItem("userData")){
		    localStorage.setItem("userData", JSON.stringify(this.#dummyData));
		}
	}

	//////////////////////////////////
	// PUBLIC METHODS
	//////////////////////////////////

	/**
	 * Retrieves all users from the localStorage database.
	 * @returns {Array<{id: number, firstName: string, lastName: string, email: string}>} The array of users.
	 */
  getAllUsers(){
    const str = localStorage.getItem("userData");
    const users = JSON.parse(str);
    return users;
  }

  /**
   * Retrieves a user by their unique ID.
   * @param {number} id The ID of the user to retrieve.
   * @returns {?{id: number, firstName: string, lastName: string, email: string}} The user object if found, otherwise null.
   */
  getUserById(id){
    const str = localStorage.getItem("userData");
    const users = JSON.parse(str);
    const user = users.find((u) => u.id == id);
    return user || null;
  }

  /**
   * Inserts a new user into the localStorage database.
   * @param {{firstName: string, lastName: string, email: string}} newUser The new user to insert.
   */
  insertUser(newUser){
    // We really should validate newUser before inserting it!
    // Set the new user's id:
    newUser.id = this.#getMaxId() + 1;
    const str = localStorage.getItem("userData");
    const users = JSON.parse(str);
    users.push(newUser);
    localStorage.setItem("userData", JSON.stringify(users));
  }

  /**
   * Updates an existing user in the localStorage database.
   * @param {{id: number, firstName: string, lastName: string, email: string}} updatedUser The user object with updated values.
   */
  updateUser(updatedUser){
    // again, we should validate updatedUser before putting it in the database
    const str = localStorage.getItem("userData");
    const users = JSON.parse(str);
    const indexOfUserToUpdate = users.findIndex(u => updatedUser.id == u.id);
    users[indexOfUserToUpdate] = updatedUser;
    localStorage.setItem("userData", JSON.stringify(users));
  }

  /**
   * Deletes a user by their unique ID from the localStorage database.
   * @param {number} id The ID of the user to delete.
   */
  deleteUser(id){
    const str = localStorage.getItem("userData");
    const users = JSON.parse(str);
    const indexOfUserToRemove = users.findIndex(u => id == u.id);
    users.splice(indexOfUserToRemove, 1);
    localStorage.setItem("userData", JSON.stringify(users));
  }

	//////////////////////////////////
	// PRIVATE METHODS (start with #)
	//////////////////////////////////

  /**
   * Retrieves the maximum ID from the users in localStorage.
   * @private
   * @returns {number} The highest user ID found in the database.
   */
  #getMaxId(){
    const str = localStorage.getItem("userData");
    const users = JSON.parse(str);
    let maxId = 0;
    for(let x = 0; x < users.length; x++){
      if(users[x].id > maxId){
        maxId = users[x].id;
      }
    }
    return maxId;
  }
}