<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Seif</title>
    <description>The latest articles on Forem by Seif (@seifzellaban).</description>
    <link>https://forem.com/seifzellaban</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1319819%2Ffe9fa1ba-ca25-47cb-9e76-0005cb741477.jpg</url>
      <title>Forem: Seif</title>
      <link>https://forem.com/seifzellaban</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/seifzellaban"/>
    <language>en</language>
    <item>
      <title>Commercial Organ Plugins Cost $400. Mine Cost a Weekend and Some Math.</title>
      <dc:creator>Seif</dc:creator>
      <pubDate>Sun, 01 Mar 2026 17:58:14 +0000</pubDate>
      <link>https://forem.com/seifzellaban/commercial-organ-plugins-cost-400-mine-cost-a-weekend-and-some-math-136i</link>
      <guid>https://forem.com/seifzellaban/commercial-organ-plugins-cost-400-mine-cost-a-weekend-and-some-math-136i</guid>
      <description>&lt;p&gt;It started because I wanted to hear a pipe organ. There are six in all of Egypt. Six. For a country of 100 million people.&lt;br&gt;
So I built one.&lt;/p&gt;

&lt;p&gt;Three weeks later I have a fully polyphonic synthesizer that generates every sound from pure math in real-time, and a genuine question about why commercial organ plugins cost $400.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not just use samples
&lt;/h2&gt;

&lt;p&gt;Every digital organ you've heard in a plugin, a keyboard workstation, a movie soundtrack, is almost certainly sample-based. Someone recorded a real pipe organ in a cathedral, captured every note on every stop, packaged it into a library. Press a key, play back the matching recording.&lt;/p&gt;

&lt;p&gt;I didn't want to do that because it felt like cheating on the learning objective (and basically impossible in Egypt). But the more I thought about it, the more I realized samples have a real limitation: they capture what a pipe sounds like in steady state. They miss everything that happens in the first 100ms when a note starts.&lt;/p&gt;

&lt;p&gt;Real pipe organs are mechanical. When you press a key, a physical valve opens, wind rushes into the pipe before the pitch stabilizes, and there's a transient called chiff as the pipe "speaks." There's also a tiny mechanical click from the valve mechanism at note onset. These aren't recording artifacts. They're part of what makes an organ sound like an organ.&lt;/p&gt;

&lt;p&gt;Sample libraries try to capture this by recording the attack too, but you can't reshape it afterward. With synthesis, it's just a parameter.&lt;/p&gt;




&lt;h2&gt;
  
  
  How a pipe organ actually makes sound
&lt;/h2&gt;

&lt;p&gt;Every stop is a different harmonic recipe. When air vibrates inside a pipe it produces a fundamental frequency plus harmonics at integer multiples, each at different amplitudes depending on the pipe's shape. What makes a Flute stop sound different from a Principal isn't some mysterious tonal quality. The Flute has almost no overtones because the stopped pipe physically suppresses them. The Principal has a balanced mix of harmonics. A Reed stop has a dense harmonic series that approaches a sawtooth wave, which is why it sounds buzzy.&lt;/p&gt;

&lt;p&gt;So synthesizing these is mostly just: figure out the right harmonic amplitudes for whichever stops are active, spin up oscillators at those frequencies, add them together. That's the whole engine.&lt;/p&gt;

&lt;p&gt;Organum runs up to 18 oscillators per voice, two per drawbar position (9 positions, plus a slightly detuned chorus partner for each). The chorus partner creates the beating pattern characteristic of string stops and adds subtle width to everything else. At 8 simultaneous voices that's potentially 144 oscillators running. On my machine it takes about 45ms to render a 4096-sample block. The budget is 93ms. Fine.&lt;/p&gt;




&lt;h2&gt;
  
  
  The envelope rabbit hole
&lt;/h2&gt;

&lt;p&gt;ADSR envelopes seem like the boring part until you try to implement them without causing clicks.&lt;/p&gt;

&lt;p&gt;A linear attack has a discontinuous derivative at note onset. The slope goes from 0 to some positive value instantaneously, and the ear hears that as a click. The fix is a smoothstep curve, &lt;code&gt;3t² − 2t³&lt;/code&gt;, which has zero slope at both endpoints. The level eases in from silence with no abrupt slope change. No click.&lt;/p&gt;

&lt;p&gt;The more interesting problem is retrigger. What happens when you re-press a key that's already in release?&lt;/p&gt;

&lt;p&gt;If you restart the attack from 0, the level jumps immediately from wherever the release was down to 0, then the attack begins. That's a click. I added a dedicated retrigger stage: a 15ms crossfade using the same smoothstep curve, going from the current release level back up to sustain. The level transition is smooth and the slope is continuous. The voice doesn't restart, oscillator phases are preserved, and the note just resurfaces from wherever it was.&lt;/p&gt;

&lt;p&gt;Completely inaudible when it works. That's the goal.&lt;/p&gt;




&lt;h2&gt;
  
  
  The reverb
&lt;/h2&gt;

&lt;p&gt;A dry pipe organ sounds like a keyboard in a recording booth. The room is doing a huge amount of perceptual work in making it feel like a real instrument.&lt;/p&gt;

&lt;p&gt;The reverb is a stereo pair of Schroeder networks. Each channel runs a pre-delay, then 7 parallel comb filters whose outputs get summed, then 4 allpass filters to smooth the tail. Left and right channels use different prime-offset delay times so their reflections never coincide. If they lined up the stereo image would collapse to mono.&lt;/p&gt;

&lt;p&gt;There are also three tuned sine oscillators simulating room resonance, the standing waves that build up in a large stone building at specific low frequencies. Without them, even a long reverb tail doesn't convey the physical weight of a cathedral. With them, the Gothic Basilica preset is unplayable at fast tempos because the decay from one chord bleeds into the next. Which is historically accurate, actually. Fast repertoire in large cathedrals wasn't common for exactly this reason.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gain problem
&lt;/h2&gt;

&lt;p&gt;When you play one note, gain is 1.0. Two simultaneous notes summed directly are twice as loud. A full chord clips hard.&lt;/p&gt;

&lt;p&gt;The fix is scaling the output by &lt;code&gt;1/√N&lt;/code&gt; where N is the number of active voices. Perceived loudness stays roughly constant as you add notes.&lt;/p&gt;

&lt;p&gt;The naive implementation applies this as a hard scalar at the start of each buffer. The problem: going from 1 voice to 2 voices drops the gain by 30% in a single sample. Audible. Every time you add a note there's a pop.&lt;/p&gt;

&lt;p&gt;The actual fix is ramping the gain linearly across the entire buffer. Going from 1.0 to 0.707 over 4096 samples is completely inaudible. The ear can't track a gradual change that slow. Going from 1.0 to 0.707 in one sample is immediately obvious. So the mixer tracks the previous gain value and interpolates to the new target across every block.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real-time stuff
&lt;/h2&gt;

&lt;p&gt;The audio callback has a hard deadline: produce 4096 samples every 93ms or the sound card glitches. Everything is organized around not missing that.&lt;/p&gt;

&lt;p&gt;The GUI thread never touches audio state directly. All communication goes through a lock-free queue of event objects, note on/off, drawbar changes, stop toggles, room presets. The queue gets drained at the start of each render.&lt;/p&gt;

&lt;p&gt;Everything in the audio path is vectorized numpy. No per-sample Python loops anywhere hot. The thing that made the biggest performance difference was pre-allocating work buffers in the oscillator. A naive implementation was doing roughly 1,000 numpy array allocations per callback. Pre-allocated arrays reused each call dropped that to near-zero.&lt;/p&gt;

&lt;p&gt;The harmonic amplitude calculation is also computed once per block in the mixer and shared across all voices, rather than each voice redundantly recalculating it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it actually sounds like
&lt;/h2&gt;

&lt;p&gt;Good. Genuinely good. The chiff on the reed stops has that breathy quality of real pipes speaking. A low chord through the cathedral reverb hits with physical weight. The Voix Humaine stop with tremulant active sounds like a bad impression of a human voice, which is exactly what the real pipe does too.&lt;/p&gt;

&lt;p&gt;I keep loading the Gothic Basilica preset and playing Bach chorales at 2am. Not ideal for anyone sleeping nearby. Very good for me personally.&lt;/p&gt;

&lt;p&gt;The code is on &lt;a href="https://github.com/seifzellaban/organum" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. &lt;code&gt;uv sync&lt;/code&gt; and &lt;code&gt;uv run python main.py&lt;/code&gt;. If you want to hear what this actually does, pull all the stops with numpad 0, set the room to Gothic Basilica, and play something slow.&lt;/p&gt;

</description>
      <category>blog</category>
      <category>python</category>
      <category>opensource</category>
      <category>sounddesign</category>
    </item>
    <item>
      <title>How to Add GitHub Contribution Stats to Your React App</title>
      <dc:creator>Seif</dc:creator>
      <pubDate>Tue, 14 Jan 2025 18:30:51 +0000</pubDate>
      <link>https://forem.com/seifzellaban/how-to-add-github-contribution-stats-to-your-react-app-1gl3</link>
      <guid>https://forem.com/seifzellaban/how-to-add-github-contribution-stats-to-your-react-app-1gl3</guid>
      <description>&lt;p&gt;Want to showcase your GitHub activity in your React portfolio? In this tutorial, I'll show you how to create a React component that displays your total GitHub contributions using GitHub's GraphQL API, complete with efficient caching. Let's build something cool! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  What We'll Build
&lt;/h2&gt;

&lt;p&gt;We'll create a React component that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetches your GitHub contributions from 2020 to present&lt;/li&gt;
&lt;li&gt;Includes both public and private contributions&lt;/li&gt;
&lt;li&gt;Implements client-side caching to optimize performance&lt;/li&gt;
&lt;li&gt;Shows a loading state while fetching&lt;/li&gt;
&lt;li&gt;Handles errors gracefully&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start, you'll need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A GitHub Personal Access Token (with &lt;code&gt;read:user&lt;/code&gt; scope)&lt;/li&gt;
&lt;li&gt;A React project set up (using Create React App, Next.js, or your preferred setup)&lt;/li&gt;
&lt;li&gt;Basic knowledge of React hooks and async operations&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Setting Up the GitHub Token
&lt;/h2&gt;

&lt;p&gt;First, create a &lt;code&gt;.env&lt;/code&gt; file in your project root and add your GitHub token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_GITHUB_TOKEN=your_github_token_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Creating the Data Fetching Utility
&lt;/h2&gt;

&lt;p&gt;Create a new file called &lt;code&gt;githubApi.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGithubCommits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GITHUB_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CACHE_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`github-commits-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CACHE_TTL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1 hour in seconds&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No GitHub token found!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GitHub token is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cachedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_KEY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;totalCommits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;startYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
        query($username: String!, $from: DateTime!, $to: DateTime!) {
          user(login: $username) {
            contributionsCollection(from: $from, to: $to) {
              totalCommitContributions
              restrictedContributionsCount
            }
          }
        }
      `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.github.com/graphql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-01-01T00:00:00Z`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-12-31T23:59:59Z`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yearCommits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;contributionsCollection&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;totalCommitContributions&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;contributionsCollection&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;restrictedContributionsCount&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nx"&gt;totalCommits&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;yearCommits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;setCachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalCommits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CACHE_TTL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;totalCommits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error fetching GitHub commits:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setCachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsedItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;parsedItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;parsedItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;parsedItem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;invalidateCommitsCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`github-commits-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Creating the React Component
&lt;/h2&gt;

&lt;p&gt;Create a new file called &lt;code&gt;GitHubStats.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchGithubCommits&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./githubApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GitHubStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCommits&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalCommits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchGithubCommits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setCommits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;totalCommits&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;fetchStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github-stats&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;Contributions&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Total&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt; &lt;span class="nx"&gt;since&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;GitHubStats&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Adding Styles
&lt;/h2&gt;

&lt;p&gt;Let's add some basic styling. Create &lt;code&gt;GitHubStats.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.github-stats&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f6f8fa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.github-stats&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#24292e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.github-stats&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#586069&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Using the Component
&lt;/h2&gt;

&lt;p&gt;Now you can use the component in your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GitHubStats&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./GitHubStats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Developer&lt;/span&gt; &lt;span class="nx"&gt;Portfolio&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GitHubStats&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-github-username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Making it Better: Advanced Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Adding a Refresh Button
&lt;/h3&gt;

&lt;p&gt;Update &lt;code&gt;GitHubStats.js&lt;/code&gt; to include a manual refresh option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchGithubCommits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;invalidateCommitsCache&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./githubApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GitHubStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... previous state declarations ...&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleRefresh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;invalidateCommitsCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github-stats&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;Contributions&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Total&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt; &lt;span class="nx"&gt;since&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleRefresh&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Refreshing...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Refresh Stats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Adding Year-by-Year Breakdown
&lt;/h3&gt;

&lt;p&gt;We can modify the component to show contributions per year:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GitHubStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;yearlyStats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setYearlyStats&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
  &lt;span class="c1"&gt;// ... other state declarations ...&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchYearlyStats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchGithubCommits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nf"&gt;setYearlyStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github-stats&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;Contributions&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yearlyStats&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="nx"&gt;commits&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Tips
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Caching Strategy&lt;/strong&gt;: The current implementation caches data for an hour. Adjust the &lt;code&gt;CACHE_TTL&lt;/code&gt; based on your needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Boundaries&lt;/strong&gt;: Consider wrapping the component in an Error Boundary to handle unexpected errors gracefully.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loading States&lt;/strong&gt;: Add a skeleton loader instead of a simple "Loading..." text for better UX.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Issues and Solutions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CORS Issues&lt;/strong&gt;: Make sure you're using the correct GitHub API endpoint and headers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Permissions&lt;/strong&gt;: Ensure your GitHub token has the required permissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting&lt;/strong&gt;: Handle GitHub's API rate limits by checking the remaining rate limit in the response headers.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;You now have a fully functional GitHub stats component in your React app! This implementation provides a solid foundation that you can build upon. Some ideas for enhancement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add more GitHub statistics (like stars, PRs, issues)&lt;/li&gt;
&lt;li&gt;Create visual representations using charts&lt;/li&gt;
&lt;li&gt;Add animations for loading and updates&lt;/li&gt;
&lt;li&gt;Implement more detailed error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember to keep your GitHub token secure and never commit it to your repository. Happy coding! 🎉&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>graphql</category>
    </item>
    <item>
      <title>React Stack 2025</title>
      <dc:creator>Seif</dc:creator>
      <pubDate>Sun, 05 Jan 2025 04:09:14 +0000</pubDate>
      <link>https://forem.com/seifzellaban/react-stack-2025-7g2</link>
      <guid>https://forem.com/seifzellaban/react-stack-2025-7g2</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Modern React Tech Stack for Building the Future:&lt;/strong&gt; Building on Vishwas Gopinath’s insightful blog post, &lt;a href="https://www.builder.io/blog/react-ai-stack" rel="noopener noreferrer"&gt;React + AI Stack&lt;/a&gt;, I’ve reworked some ideas to reflect my own perspective. While AI is undoubtedly transformative, I believe beginners should focus on mastering foundational concepts before diving into AI-driven development.&lt;/p&gt;

&lt;p&gt;React has been a cornerstone of front-end development for years, and its ecosystem continues to evolve. While AI is making waves in the tech world, let’s focus on the core tools and technologies that make up a robust React tech stack in 2025. Whether you're starting a new project or upgrading an existing one, this breakdown will help you stay ahead of the curve.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Core: React + TypeScript&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq6wwkgekov1agnz5sl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq6wwkgekov1agnz5sl1.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
React and TypeScript have become an inseparable duo in modern web development. TypeScript brings type safety to your React projects, catching errors early, simplifying refactoring, and enhancing your IDE’s autocomplete capabilities. It also serves as built-in documentation for your team, making onboarding new developers smoother. If you haven’t adopted TypeScript yet, now’s the time.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Meta Framework: Next.js&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3dffdjf0vnxkgpkh65t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3dffdjf0vnxkgpkh65t.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Next.js remains the go-to meta framework for React developers. It offers full support for React 19, integrated routing, API management, and built-in performance optimizations like server-side rendering (SSR) and static site generation (SSG). While alternatives like Remix and Tanstack Start are worth exploring, Next.js stands out for its versatility and comprehensive feature set.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Styling: Tailwind CSS + shadcn/ui&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0losrj3xoz4q5waa1rc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0losrj3xoz4q5waa1rc.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Tailwind CSS has revolutionized how developers approach styling. Its utility-first approach allows for rapid prototyping and consistent designs. Pair it with shadcn/ui, and you get a library of accessible, pre-built components that integrate seamlessly with Tailwind. This combination keeps your bundle size optimized and your development process efficient.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Client-State Management: Zustand&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For managing client-side state, Zustand is a lightweight and powerful solution. It eliminates boilerplate code, has a minimal bundle size, and offers a straightforward API. With Zustand, you can create a store in just a few lines of code, making it an excellent choice for both small and large applications.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Server-State Management: TanStack Query&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;TanStack Query (formerly React Query) simplifies server-state management. It handles data fetching, caching, and real-time updates with ease. Features like auto-refreshing data, optimistic updates, and built-in devtools make it indispensable for modern React applications.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Animation: Framer Motion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Framer Motion is the top choice for animations in React. Its declarative API makes it easy to create smooth, interactive animations. With support for gestures, shared layout animations, and advanced motion design, Framer Motion is perfect for everything from simple transitions to complex user experiences.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Testing: Vitest, React Testing Library, &amp;amp; Playwright&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A robust testing strategy is essential for any React project. Vitest is a fast and modern alternative to Jest, offering native ES modules support. React Testing Library ensures your components are tested in a way that mirrors user interactions, while Playwright excels at end-to-end testing with support for multiple browsers, visual testing, and mobile device emulation.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Tables: TanStack Table&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For handling complex tables, TanStack Table is a must-have. It provides type-safe tables, virtual scrolling for large datasets, and flexible column configurations. Its performance and ease of use make it ideal for applications that rely heavily on tabular data.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Forms: React Hook Form&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Forms in React have never been easier thanks to React Hook Form. It’s fast, lightweight, and works seamlessly with TypeScript. Paired with validation libraries like Zod, it simplifies form management and ensures a smooth user experience.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Database: Supabase&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Supabase has grown into a full-featured backend solution. It offers real-time subscriptions, edge functions, and a user-friendly SQL interface. While it’s not AI-focused, its robust feature set makes it a great choice for modern React applications.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Mobile Development: React Native&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For cross-platform mobile development, React Native remains the powerhouse. It allows you to write code once and deploy it across iOS and Android while maintaining native performance. With a vast ecosystem of libraries and tools, React Native is the go-to solution for mobile apps.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Component Development: Storybook&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Storybook is essential for building and testing components in isolation. It supports component-driven development, provides a built-in testing environment, and generates documentation automatically. Its collaboration features make it a favorite among designers and developers alike.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Hosting: Vercel&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Vercel is the ideal hosting platform for React apps, especially those built with Next.js. It offers seamless deployment, edge functions for improved performance, built-in analytics, and a global CDN to ensure your app is fast everywhere.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Wrapping Up&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This modern React tech stack is designed to help you build scalable, performant, and maintainable applications. While it’s packed with powerful tools, remember that the best stack is the one that works for your team and project. Start small, experiment with these tools, and gradually integrate what fits your needs. The future of React development is bright, and with this stack, you’ll be well-equipped to tackle it head-on.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Orbit: A Journey Through the Solar System</title>
      <dc:creator>Seif</dc:creator>
      <pubDate>Thu, 02 Jan 2025 22:06:58 +0000</pubDate>
      <link>https://forem.com/seifzellaban/orbit-a-journey-through-the-solar-system-1kbk</link>
      <guid>https://forem.com/seifzellaban/orbit-a-journey-through-the-solar-system-1kbk</guid>
      <description>&lt;p&gt;Last October, my team &lt;strong&gt;Masons&lt;/strong&gt; embarked on an exciting journey to create something truly out of this world for the &lt;strong&gt;NASA Space Apps Cairo 2024&lt;/strong&gt; hackathon. Our project, &lt;strong&gt;Orbit&lt;/strong&gt;, is an interactive 3D web application that simulates the solar system and tracks Near-Earth Objects (NEOs). Built with &lt;strong&gt;Next.js&lt;/strong&gt;, &lt;strong&gt;Three.js&lt;/strong&gt;, and a &lt;strong&gt;Golang&lt;/strong&gt; backend, Orbit is designed to educate, inspire, and provide real-time insights into the cosmos. Today, I’m thrilled to share the story behind this project and how we brought it to life.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What is Orbit?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Orbit is more than just a web app—it’s a gateway to the universe. It allows users to explore the solar system in stunning 3D, track NEOs, and learn about the celestial bodies that surround us. By leveraging NASA’s open-source datasets, we’ve created a platform that combines education, science, and cutting-edge technology to make space exploration accessible to everyone.&lt;/p&gt;

&lt;p&gt;Our goal was to build a tool that not only visualizes the solar system but also highlights the potential threats posed by NEOs and Potentially Hazardous Asteroids (PHAs). Post-hackathon, we’ve decided to keep Orbit open-source, inviting the community to contribute and help us refine and expand its features.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Key Features of Orbit&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Interactive 3D Solar System&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At the heart of Orbit is a fully interactive 3D orrery built with &lt;strong&gt;Three.js&lt;/strong&gt;. Users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explore the Solar System:&lt;/strong&gt; Zoom, rotate, and pan to view planets, moons, and asteroids in real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control Time:&lt;/strong&gt; Speed up, slow down, or reverse time to see how celestial bodies move over days, months, or even years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First-Person View:&lt;/strong&gt; Experience the solar system from a first-person perspective, as if you’re flying through space.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Near-Earth Object (NEO) Tracking&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Orbit integrates with NASA’s &lt;strong&gt;Small Body Database&lt;/strong&gt; to provide up-to-date information on NEOs and PHAs. Users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;View NEO Orbits:&lt;/strong&gt; See the trajectories of NEOs and understand their paths relative to Earth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detailed Information:&lt;/strong&gt; Access detailed pages for each NEO, including Keplerian parameters like eccentricity, semi-major axis, and inclination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personalized Dashboard:&lt;/strong&gt; Save and manage favorite NEOs for quick access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. AI-Powered Chatbot&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We integrated the &lt;strong&gt;Gemini API&lt;/strong&gt; to create an AI chatbot that answers user questions about space, NEOs, and the solar system. Whether you’re curious about the position of a specific asteroid or want to learn more about orbital mechanics, the chatbot is there to help.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Complex Astronomical Computations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using &lt;strong&gt;Claude&lt;/strong&gt;, we handle complex orbital calculations in the background. This ensures that the app runs smoothly while providing accurate predictions of future NEO positions and potential threats to Earth.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Tech Stack&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js for a responsive and intuitive user interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3D Rendering:&lt;/strong&gt; Three.js for the interactive solar system and NEO visualizations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Golang for API management, data retrieval, and session tracking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Integration:&lt;/strong&gt; Gemini API for the chatbot and Claude for complex computations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Source:&lt;/strong&gt; NASA’s Small Body Database for real-time NEO data.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Our Hackathon Journey&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Planning and Ideation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We started by brainstorming ideas that aligned with NASA’s themes and datasets. We wanted to create something that was both educational and visually engaging. After reviewing NASA’s Small Body Database, we decided to focus on NEOs and the solar system, combining real-time data with an interactive 3D experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Development&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We split into two teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;frontend team&lt;/strong&gt; worked on the UI and 3D orrery using Next.js and Three.js.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;backend team&lt;/strong&gt; built the API with Golang, integrated NASA’s database, and implemented session tracking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Challenges and Solutions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the biggest challenges was rendering real-time data updates in the 3D visualization without compromising performance. We also had to optimize the AI chatbot’s response time and ensure that complex orbital calculations didn’t slow down the app. By leveraging Claude for intensive computations and implementing efficient caching strategies, we were able to overcome these hurdles.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Testing and Optimization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We tested Orbit across multiple devices and browsers to ensure a seamless experience. The 3D orrery was optimized for smooth interactions, and the app was made responsive for both desktop and mobile users.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Impact of Orbit&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Orbit is more than just a hackathon project—it’s a tool that brings the wonders of space to everyone. Whether you’re a student, a space enthusiast, or just curious about the universe, Orbit provides a unique way to explore and learn. By highlighting the potential threats posed by NEOs, we hope to raise awareness and inspire a deeper interest in space science.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What’s Next for Orbit?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Post-hackathon, we’re committed to keeping Orbit open-source and continuing its development. We’re excited to incorporate community feedback and explore new features, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiplayer Mode:&lt;/strong&gt; Allow users to explore the solar system together in real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Augmented Reality (AR):&lt;/strong&gt; Bring the 3D orrery into the real world with AR technology.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Educational Modules:&lt;/strong&gt; Add interactive lessons and quizzes to make learning about space even more engaging.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How to Get Involved&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Orbit is open-source, and we welcome contributions from the community! Whether you’re a developer, designer, or space enthusiast, there’s a place for you in this project. Check out our &lt;a href="https://github.com/TheGrandMasons/orbit/" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; to get started.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Working on Orbit with Team Masons was an unforgettable experience. We pushed the boundaries of what we thought was possible, learned new technologies, and created something we’re truly proud of. We hope Orbit inspires others to explore the cosmos and continue pushing the frontiers of space science and technology.&lt;/p&gt;

&lt;p&gt;Thank you to NASA Space Apps for this incredible opportunity, and to everyone who supported us along the way. The universe is vast, and with Orbit, we’re just getting started.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NASA Small Body Database&lt;/strong&gt;: &lt;a href="https://ssd.jpl.nasa.gov/tools/sbdb_query.html" rel="noopener noreferrer"&gt;NASA SBD&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini API&lt;/strong&gt;: Used for the AI chatbot functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude AI&lt;/strong&gt;: Used for complex astronomical computations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt;: Framework for frontend development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three.js&lt;/strong&gt;: Library for rendering 3D graphics and the interactive orrery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Golang&lt;/strong&gt;: Backend for API management and data retrieval.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>threejs</category>
      <category>javascript</category>
      <category>go</category>
    </item>
    <item>
      <title>Revolutionizing Wireless Energy Transfer</title>
      <dc:creator>Seif</dc:creator>
      <pubDate>Sat, 02 Mar 2024 16:02:49 +0000</pubDate>
      <link>https://forem.com/seifzellaban/revolutionizing-wireless-energy-transfer-4d3i</link>
      <guid>https://forem.com/seifzellaban/revolutionizing-wireless-energy-transfer-4d3i</guid>
      <description>&lt;p&gt;In a world driven by electricity, the quest for efficient and accessible power solutions has never been more crucial. Enter Tesla coils – the unsung heroes of wireless energy transfer. In this blog post, we'll delve into the fascinating realm of Tesla coils, exploring their applications, history, and potential to revolutionize the way we harness electricity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Promise of Wireless Power
&lt;/h3&gt;

&lt;p&gt;Imagine a world where electricity flows freely, unbound by wires and cables. That's the vision of Tesla coils – devices that generate a high electromagnetic field capable of wirelessly transmitting power over vast distances. With applications ranging from space station repairs to street lighting, the potential impact of this technology is boundless.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Legacy of Nikola Tesla
&lt;/h3&gt;

&lt;p&gt;At the heart of the Tesla coil revolution lies the visionary genius of Nikola Tesla. Born in 1856 in what is now Croatia, Tesla emigrated to the United States in 1884 and soon began working with Thomas Edison. However, their differing views on electrical systems led to a bitter rivalry. Despite setbacks, Tesla's persistence and ingenuity propelled him to the forefront of electrical engineering.&lt;/p&gt;

&lt;p&gt;Tesla's life story is a testament to the power of dreams and imagination. From his pioneering work in AC motors to his ambitious plans for wireless power transmission, Tesla's legacy continues to inspire generations of innovators. His dream of wireless power transmission, though ahead of its time, remains a beacon of possibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dreamer and the Dream
&lt;/h3&gt;

&lt;p&gt;What set Tesla apart from his contemporaries was his ability to dream – to envision a future shaped by technology. Tesla's inventions, fueled by his boundless imagination, laid the groundwork for modern electrical systems. His dream of wireless power transmission, though initially met with skepticism, has since captured the imagination of scientists and engineers around the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Rise of Wireless Power
&lt;/h3&gt;

&lt;p&gt;In the age of electrification, Tesla coils represent a bold step forward in the quest for efficient power solutions. By harnessing the principles of resonance and induction, Tesla coils enable the wireless transmission of electricity, paving the way for a more connected and sustainable future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Applications Across Industries
&lt;/h3&gt;

&lt;p&gt;From space station repairs to urban infrastructure, the applications of Tesla coils are as diverse as they are transformative. Imagine a world where streetlights are powered without the need for cumbersome cables, or where remote locations receive electricity effortlessly. With Tesla coils, these visions are within reach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Towards a Sustainable Future
&lt;/h3&gt;

&lt;p&gt;As we strive to make Tesla coils more efficient and cost-effective, we are inching closer to realizing Tesla's vision of a wireless world. By harnessing the power of technology and innovation, we can unlock new opportunities for growth and prosperity, while reducing our reliance on traditional energy sources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the Revolution
&lt;/h3&gt;

&lt;p&gt;The journey towards wireless power has only just begun, and we invite you to be a part of it. Whether you're a researcher, engineer, or simply curious about the potential of Tesla coils, there's never been a better time to get involved. Together, we can shape a future where electricity knows no bounds.&lt;/p&gt;

&lt;p&gt;To learn more about our groundbreaking work and ongoing research, visit &lt;a href="https://drive.google.com/file/d/10dVNI0DO2mPxJV0CHy8A2zNN4Rw2l1OD/view?usp=sharing" rel="noopener noreferrer"&gt;us here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introducing the Life Support ExoSuit</title>
      <dc:creator>Seif</dc:creator>
      <pubDate>Sat, 02 Mar 2024 15:58:28 +0000</pubDate>
      <link>https://forem.com/seifzellaban/introducing-the-life-support-exosuit-2i1l</link>
      <guid>https://forem.com/seifzellaban/introducing-the-life-support-exosuit-2i1l</guid>
      <description>&lt;p&gt;Imagine a world where disabilities are no longer barriers to living life to the fullest. At the heart of this vision lies the Life Support ExoSuit (LSE), a groundbreaking innovation designed to empower individuals with disabilities to lead lives of independence and freedom. In this blog post, we'll delve into the intricacies of the LSE and explore how it is poised to revolutionize accessibility for millions worldwide.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Inspiration
&lt;/h3&gt;

&lt;p&gt;The genesis of the Life Support ExoSuit stemmed from a simple yet profound goal: to provide universal access to safe, inclusive, and green public spaces, particularly for marginalized groups such as women, children, older persons, and individuals with disabilities. Recognizing the vast spectrum of disabilities and the challenges they pose, our team set out to develop a solution that would enable people to live life on their own terms, regardless of their physical limitations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unveiling the Life Support ExoSuit (LSE)
&lt;/h3&gt;

&lt;p&gt;At the core of the LSE is an exoskeleton meticulously engineered to support and mobilize the entire body. Powered by hydraulic cylinders and motors, the exosuit works in tandem with the wearer's brain cortex, which serves as the main control center. Through a sophisticated network of sensors and artificial intelligence (AI), the LSE interprets the wearer's intentions, translating eye movements and blinks into seamless movements and actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;The integration of cutting-edge technologies such as eye tracking and AI is key to the functionality of the LSE. By employing an eye tracker, the system accurately detects the wearer's gaze and blinks, enabling intuitive control and interaction. Meanwhile, AI algorithms enable object detection and provide real-time feedback, enhancing the wearer's autonomy and confidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leveraging LiDAR and Drones
&lt;/h3&gt;

&lt;p&gt;In addition to its internal components, the LSE harnesses the power of LiDAR technology and drones to further augment its capabilities. LiDAR-equipped drones facilitate precise mapping of the surrounding environment, enabling the LSE to navigate and interact with its surroundings with unparalleled accuracy and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Powering the Future
&lt;/h3&gt;

&lt;p&gt;A crucial aspect of the LSE's design is its reliance on sustainable and efficient power sources. By leveraging modified Tesla coils, the system generates a high electromagnetic field, enabling wireless power exchange between devices. This innovative approach not only enhances convenience but also reduces reliance on traditional power sources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact and Future Prospects
&lt;/h3&gt;

&lt;p&gt;With over a billion individuals worldwide experiencing some form of disability, the potential impact of the Life Support ExoSuit is immense. By providing newfound mobility and independence, the LSE has the power to transform lives and break down barriers to inclusion. As we continue to refine and expand upon our technology, our ultimate goal remains clear: to empower individuals to live life without limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In a world where physical limitations often dictate one's quality of life, the Life Support ExoSuit stands as a beacon of hope and possibility. By combining cutting-edge technology with a commitment to accessibility and empowerment, we are forging a path towards a more inclusive and equitable future for all. With the Life Support ExoSuit, the possibilities are limitless, and the journey towards universal accessibility has only just begun.&lt;/p&gt;

&lt;p&gt;To learn more about our groundbreaking work and ongoing research, &lt;a href="https://docs.google.com/presentation/d/1wu4vsU1MBwapE1Scyr7-KfJ6mx7TMyRckqYDb_-lWJs/edit?usp=sharing" rel="noopener noreferrer"&gt;visit us here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Join us as we redefine what it means to live with purpose and dignity, one step at a time.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
