Decoding the codebase: Reflections on my first big open source project.

Decoding the codebase: Reflections on my first big open source project.

Reflections on navigating hurdles

Picture this: you're in Ghana, on the vibrant West Coast of Africa, where recent power outages have stirred up quite the storm. With temperatures soaring to a steamy 30°C (86°F), the last thing anyone needs is a 12-hour power cut. It's a frustrating plot twist in our day-to-day lives, stifling productivity, and leaving us sweating it out in the sweltering heat. But in the midst of all this frustration, there's a silver lining: communities are rallying together, getting creative to tackle these blackout blues.

So, let's rewind to where it all began: with a simple tweet.

And boom! Before we could even say "dum," plans were already brewing.

So basically, a project was upon us - "Dumsor" Tracker. (Yep, "Dumsor" is our go-to term for power outages. "DUM" meaning off, and "SOR", on. You get the idea). The big idea? Keep tabs on these blackout episodes across the nation(Phase 1) and cook up some fancy algorithms to predict them(Phase 2). Because who doesn't love a heads-up before being left fumbling for candles and flashlights? Software engineers, data geeks, and all-around advocates flooded the timeline with ideas on how to make this app a reality.

Now, about me? Just your average sophomore in computer engineering, trying to pass off my coding skills as legit. But hey, enthusiasm counts for something, right? So sign me up for this rollercoaster ride! I hit topboyasante up on X telling him straight up: "I WANT IN". At that time, I was knee-deep in an internship, learning a lot from my supervisors. So, joining this project seemed like the logical next step to getting my hands dirty. Fast forward, and we've got a crew of six (which soon swelled in numbers), all geared up to engineer this app.

I joined several google meets as we hashed out project requirements and plotted our course forward. And guess what? Yours truly found himself teamed up with software engineers on the frontend. Talk about a coding dream team- LOL! Best part? It's all open source. So, you know it's gonna be good.

Now, here's the kicker: what do I even know about tackling the frontend of an application? Sure, I've got some React and Tailwind CSS under my belt, and I've tinkered around with a few personal projects. But is it enough? Doubt creeps in, and hello, Imposter Syndrome. But then, a good lesson from my internship floats back to me: start before you're ready. I mean, how many times have I procrastinated on a project because I wanted to watch just one more tutorial? Too many. So, I decided to dive in headfirst. And you know what? I recently broke free from tutorial hell(a win for me, actually!) and stumbled upon a better way to learn: reading. Reading docs and articles, even cracking open coding books - they've all been my guiding light in this coding journey.

Remember I said start before you are ready?

The frontend was built using Next.js, while the backend employed Node.js, Express, and Supabase for database management and authentication. We opted for PostgreSQL to leverage its geospatial capabilities. Now, Next.js posed a bit of a challenge for me initially – it felt rather complex (perhaps a skill issue), likely due to my lack of experience with it. But I was confident. The first issue I picked up was Logs : Create A Page to Create Logs #14. Essentially, we needed a page where users could log their location and the time their power went off. I used Zod validation and tested the API with Postman to ensure accurate form details. Utilizing ShadcnUI components, I crafted a custom input component with TypeScript. It was a simple task. I created a pull request and boom, it got merged. Did it feel good? Yes. Did it also boost my confidence? Also, yes!

From there, I wanted to dive even deeper. I enhanced the log feed page to display recent logs with a search functionality for an optimal user experience. I discussed features in our Discord Server, read more on Next.js, and took on my next task. This time, I wasn't just picking up an issue; I was tasked with reproducing a hydration error and resolving bugs. It appeared that someone had pushed a bug into the upstream, and Husky (a pre-commit hook) failed to catch it.

Unhandled Runtime Error
 Error: Hydration failed because the initial UI does not match what was rendered on the server

Initially, I considered passing suppressHydrationWarning as a prop to my top-level component, but that didn't work. So, I went through each component, testing, console logging, and commenting out code to narrow down the error. It turned out to be a simple issue: putting a lucide-react icon inside a hover card component. There was a mismatch between the server-rendered HTML and the client-side components during hydration. This error popped up because I was using elements that rely on client-side interactivity, such as event listeners or state changes. It became clear that the hover component was not fully compatible with SSR: Server Side Rendering.

Solving that bug taught me a lot. I transitioned from tackling minor tasks to implementing logic and consuming the API. I progressed from being inexperienced to writing and distinguishing between server and client components. Here's a simple GET request to our getLogs endpoint in a server component:

// logs.actions.tsx

async function getLogs() {
  const url = new URL(`${BASE_URL}/logs`);
  const response = await fetch(url, {
    method: "GET",
  });

  if (!response.ok) {
    const msg = await response.text();
    throw new Error(msg);
  }

  return response.json();
}

export { getLogs };

And here is a little implementation:

// page.tsx

export default async function Home() {
  const response = await getLogs();
  return (
    <main>
      <div className="fixed bottom-5 right-5 p-5">
        <Link href={`/logs/new`}>
          <Button size={"icon"} className="rounded-full">
            <PlusIcon />
          </Button>
        </Link>
      </div>
      <div className="max-w-screen-lg mx-auto min-h-screen p-6">
        <div>
          <h2>Are your lights out?</h2>
          <p className="text-neutral-500">
            View logs of power outages across the country
          </p>
        </div>
        <div className="py-6">
          <Search placeholder="Search Posts" />
        </div>
        <div className="w-full h-full border-l-2 border-dashed">
          <div className="ml-4">
            <LogList data={response.data.logs} />
          </div>
        </div>
      </div>
    </main>
  );
}

The logs data gets passed on as a prop to the Log Feed component, which essentially displays the timeline of logs (posts).

As we near the completion of Phase 1, the GitHub repository stands as a testament to our collective effort and dedication. Each line of code represents a step forward, a problem solved, and a lesson learned. While there's still work to be done, there's also an open invitation for others to join in the journey. Whether you're a seasoned developer or just starting out(like me), there's room for everyone to contribute and make a difference.

With the release date fast approaching, anticipation bubbles within me. I can't wait to see the impact this project will have once it's out in the world. Knowing that something I've helped create will be in the hands of users, making their lives a little easier or more enjoyable, is an incredibly rewarding feeling.

For me, this project has been more than just lines of code. It's been a journey of personal growth and discovery. From tackling bugs to implementing new features, each challenge has pushed me to expand my skills and push beyond my comfort zone. And through it all, my confidence has soared.

So, as we countdown to launch day, I encourage you to dive into the repository, explore the codebase, and maybe even lend a hand. Because together, we're not just building an app – we're building a community, one line of code at a time.