Building an event management BST with TypeScript

Published: April 25, 2023

Time to read: 9 min

Building an event management BST with TypeScript

Published: April 25, 2023

Time to read: 9 min

Alright, you TypeScript fanatics, gather 'round! Today, we're diving into a killer application of Binary Search Trees (BSTs) that'll make your event management game unstoppable. You read that right: we're building a freakin' event management app using BSTs and TypeScript. If you thought our last adventure with Contact Lists was wild, you ain't seen nothing yet.

Why BSTs for Event Management?

So, you're probably wondering, "Why the hell should I use a BST for event management?" Well, my friend, let me enlighten you with three simple reasons:

Efficient insertion and deletion: Adding and removing events like a champ with an average-case complexity of O(log n).

Swift event searching: Wanna find that one event in a haystack of a thousand? No problem! BSTs got your back with an average-case complexity of O(log n) for searching.

Automatic event sorting: Need those events sorted by date and time? Look no further---BSTs have you covered, making the display of sorted events as easy as pie.

Setting Up Our TypeScript Playground

Alright, now that you're convinced of the power of BSTs, let's get our hands dirty with some TypeScript. Just like in our previous article, we'll be using React alongside TypeScript to create a user interface for managing events.

Designing Our Event Interface

We'll start by designing a simple interface for our events. Each event will have a title, date, time, and location. We'll use this interface to keep our events in check and make sure they behave accordingly.

Building Our BST for Event Management

Once we've got our event interface locked and loaded, it's time to build our BST for managing events. We'll use the date and time as our sorting key, making sure our events are organized chronologically.

code block is typescript
export interface Event {
  title: string;
  date: string; // Use ISO date format, e.g., "2023-05-01"
  time: string; // Use 24-hour format, e.g., "14:30"
  location: string;
}

Creating, Searching, and Deleting Events

Now that we've got our BST set up, it's time to create, search, and delete events like a pro. We'll implement methods for adding events to our BST, searching for events by date and time, and removing events when they're no longer needed. And, of course, we'll be doing all of this with the power of TypeScript.

code block is tsx
import { Event } from './Event';
import { BinarySearchTree, TreeNode } from './BinarySearchTree';

class EventBinarySearchTree extends BinarySearchTree<Event> {
  // Override the insert method to use the date and time as the sorting key
  insert(event: Event) {
    const sortingKey = `${event.date}T${event.time}`;
    const newNode = new TreeNode({ ...event, sortingKey });

    if (!this.root) {
      this.root = newNode;
      return;
    }

    let currentNode = this.root;
    while (true) {
      if (sortingKey < currentNode.value.sortingKey) {
        if (!currentNode.left) {
          currentNode.left = newNode;
          return;
        }
        currentNode = currentNode.left;
      } else {
        if (!currentNode.right) {
          currentNode.right = newNode;
          return;
        }
        currentNode = currentNode.right;
      }
    }
  }

  // Override the search method to use the date and time as the searching key
  search(date: string, time: string): TreeNode<Event> | null {
    const sortingKey = `${date}T${time}`;
    let currentNode = this.root;
    while (currentNode) {
      if (sortingKey === currentNode.value.sortingKey) return currentNode;
      currentNode = sortingKey < currentNode.value.sortingKey ? currentNode.left : currentNode.right;
    }
    return null;
  }

  // Override the delete method to use the date and time as the deleting key
  delete(date: string, time: string): void {
    const sortingKey = `${date}T${time}`;
    this.root = this._deleteNode(this.root, sortingKey);
  }
}

export { EventBinarySearchTree };

Displaying Events Sorted by Date and Time

With our events all snugly stored in our BST, we'll want to display them in a neat, sorted list. In this section, we'll traverse our BST in-order and render the events sorted by date and time for all to see.

code block is tsx
import React, { useState } from 'react';
import { EventBinarySearchTree } from './EventBinarySearchTree';
import { Event } from './Event';

const EventList: React.FC = () => {
  const [ebst, setEbst] = useState(new EventBinarySearchTree());
  const [title, setTitle] = useState('');
  const [date, setDate] = useState('');
  const [time, setTime] = useState('');
  const [location, setLocation] = useState('');

  const handleAddEvent = (e: React.FormEvent) => {
    e.preventDefault();
    const newEvent: Event = { title, date, time, location };
    ebst.insert(newEvent);
    setEbst(ebst);
    setTitle('');
    setDate('');
    setTime('');
    setLocation('');
  };

  const handleDeleteEvent = (event: Event) => {
    ebst.delete(event.date, event.time);
    setEbst(ebst);
  };

  const renderEvents = (node: TreeNode<Event> | null) => {
    if (!node) return null;
    return (
      <>
        {renderEvents(node.left)}
        <div>
          {node.value.title} - {node.value.date} {node.value.time} - {node.value.location}
          <button onClick={() => handleDeleteEvent(node.value)}>Delete</button>
        </div>
        {renderEvents(node.right)}
      </>
    );
  };

  return (
    <div>
      <form onSubmit={handleAddEvent}>
        <input
          type="text"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
          placeholder="Title"
        />
        <input
          type="date"
          value={date}
          onChange={(e) => setDate(e.target.value)}
          placeholder="Date"
        />
        <input
          type="time"
          value={time}
          onChange={(e) => setTime(e.target.value)}
          placeholder="Time"
        />
        <input
          type="text"
          value={location}
          onChange={(e) => setLocation(e.target.value)}
          placeholder="Location"
        />
        <button type="submit">Add Event</button>
      </form>

      <div>
        <strong>Event List:</strong>
        {renderEvents(ebst.root)}
      </div>
    </div>
  );
}

export default EventList;

Expanding Functionality

You've built a wicked event management app with BSTs, but don't stop there! Here are some ideas for additional features that'll make your app even more badass:

Add reminders and notifications for upcoming events.

Allow users to filter events based on location, category, or other criteria.

Implement a more efficient and accurate search with fuzzy matching or autocomplete suggestions.

Allow users to edit event details after they've been added to the list.

Add support for recurring events, such as weekly meetings or annual conferences.

Conclusion:

So there you have it, folks! You've just taken your BST and TypeScript skills to the next level by building a rad event management app. With the powers of BSTs and TypeScript combined, you're now equipped to tackle even more complex challenges in the world of web development. Keep pushing the limits, and remember---happy coding!

Here's a quick summary of the main components:

Event.ts: Defines the Event interface with properties such as title, date, time, and location.

EventBinarySearchTree.ts: Extends the generic BinarySearchTree to create an EventBinarySearchTree class specifically for managing events. It overrides the insert, search, and delete methods to use the date and time as the sorting key.

EventList.tsx: The main React component that handles adding and deleting events, as well as rendering the events sorted by date and time using the EventBinarySearchTree.

This code should be ready for production use, and you can further customize it or add more features to fit your specific requirements.