<?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>DEV Community: mismathh</title>
    <description>The latest articles on DEV Community by mismathh (@mismathh).</description>
    <link>https://dev.to/mismathh</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%2F1156613%2Fa9d81f34-28f4-4500-990a-a49ca78d72fa.jpg</url>
      <title>DEV Community: mismathh</title>
      <link>https://dev.to/mismathh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mismathh"/>
    <language>en</language>
    <item>
      <title>Integrating Google Authentication to Chat Application - Progress</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Mon, 11 Dec 2023 08:36:21 +0000</pubDate>
      <link>https://dev.to/mismathh/integrating-google-authentication-to-chat-application-progress-54o8</link>
      <guid>https://dev.to/mismathh/integrating-google-authentication-to-chat-application-progress-54o8</guid>
      <description>&lt;p&gt;As discussed in my last &lt;a href="https://dev.to/mismathh/implementing-alternative-authenticate-feature-3eh8"&gt;post&lt;/a&gt;, my current focus has been on implementing an alternative authentication method to log in into &lt;a href="https://github.com/ShivamMadlani/chatApp"&gt;Chat Application&lt;/a&gt;. In this update, I wanted to share the progress I have made.&lt;/p&gt;

&lt;h2&gt;Integrating OAuth 2.0 and Google API with Passport.js&lt;/h2&gt;

&lt;p&gt;My initial thoughts to this step was that it was going to be more code heavy, but it ended being more to do with acquiring certain values from Google to be able to connect to the API. &lt;/p&gt;

&lt;p&gt;In order to use Google authentication with OAuth 2.0, the relevant "Strategy" library is needed from the &lt;code&gt;passport-google-oauth2&lt;/code&gt; package. With that, we can use &lt;code&gt;passport.use()&lt;/code&gt; to create our Strategy to be used when users log in with Google.&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="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GoogleStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;clientID&lt;/span&gt;&lt;span class="p"&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;GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&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;GOOGLE_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;callbackURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000/auth/google/callback&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="nx"&gt;authenticateGoogleUser&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;p&gt;To connect to the Google API, a &lt;code&gt;clientID&lt;/code&gt; and &lt;code&gt;clientSecret&lt;/code&gt; key is needed. The &lt;a href="https://console.cloud.google.com/apis/credentials"&gt;Google Cloud Platform&lt;/a&gt; is where you can acquire these values after creating a project to link with your application.&lt;/p&gt;

&lt;h3&gt;Front-end User Interface&lt;/h3&gt;

&lt;p&gt;I decided to create a simple button to provide the option for users to login with their Google accounts, and kept the dark tone to match the rest of the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iZjmxDcf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bf0aamlucexcr7fxkail.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZjmxDcf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bf0aamlucexcr7fxkail.JPG" alt="Google Button" width="313" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Back-end Routes&lt;/h3&gt;

&lt;p&gt;Two routes needed to be created to handle Google authentication requests. The &lt;code&gt;/auth/google&lt;/code&gt; route will be called once the user clicks on the button to log/sign in with Google. This will redirect the user to the Google OAuth consent screen where they will need to choose a Google account to log in while accepting that some information from Google will be passed to the app.&lt;/p&gt;

&lt;p&gt;In this case, the &lt;code&gt;scope&lt;/code&gt; is what defines what information we are requesting from Google. There are many other values that may seem important to you, such as &lt;code&gt;email&lt;/code&gt;, etc., but for the purpose of this app, the &lt;code&gt;profile&lt;/code&gt; scope contains a unique &lt;code&gt;id&lt;/code&gt; that we can store in our database to verify the user.&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/google&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google&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;scope&lt;/span&gt;&lt;span class="p"&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;profile&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="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second route will be called after we have verified and retrieved the information back from Google. If it was successful, it will redirect the user to the &lt;code&gt;/&lt;/code&gt; page, and to the &lt;code&gt;/login&lt;/code&gt; page if verifying the user was unsuccessful.&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/google/callback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google&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;successRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;failureRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
 &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;Passport Names&lt;/h3&gt;

&lt;p&gt;One of the hiccups I faced when implementing this alternative authentication, was the functionality of signing in through local &lt;strong&gt;or&lt;/strong&gt; Google authentication, and to have both functional at the same time. Having multiple passport strategies places more importance on the &lt;code&gt;name&lt;/code&gt; of the strategy, and to call the correct one for certain routes. I've only used the &lt;code&gt;passport-local&lt;/code&gt; package in my projects thus far, and when trying to use &lt;code&gt;authenticate()&lt;/code&gt;, the name of the strategy was always local, which made sense at the time. "The package is called passport-local so the name to use should be local." That kind of thought process won't work for passport-google-oauth2. I was planning to use a new name for the Google passport strategy, but I honestly got lucky, as I typed in "google" for the passport name and it worked, but where did this come from?&lt;/p&gt;

&lt;p&gt;I did a little digging and found out that for each of these specific "Strategies" that you download, the default name is set within the strategy (or module) itself. When you require the the module, it exports a Strategy constructor function that sets the default name:&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="c1"&gt;// Inside the passport-google-oauth2 module&lt;/span&gt;
&lt;span class="nx"&gt;OAuth2Strategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, if you are using multiple specific passport Strategies, instead of creating new names, you could also just look for the default name that is set within the module.&lt;/p&gt;

&lt;h2&gt;Pull Request&lt;/h2&gt;

&lt;p&gt;All these changes can be found in my &lt;a href="https://github.com/ShivamMadlani/chatApp/pull/7"&gt;PR&lt;/a&gt;, which currently needs to be reviewed first until it can be merged.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Implementing Alternative Authenticate Feature</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Sat, 09 Dec 2023 03:23:42 +0000</pubDate>
      <link>https://dev.to/mismathh/implementing-alternative-authenticate-feature-3eh8</link>
      <guid>https://dev.to/mismathh/implementing-alternative-authenticate-feature-3eh8</guid>
      <description>&lt;p&gt;As I continue on my open-source journey, I wanted to dive more into issues that revolved around JavaScript and Node.js, and preferably wanted to implement a new feature that I haven't implemented before. I found a project which I was interested in working on called &lt;a href="https://github.com/ShivamMadlani/chatApp"&gt;Chat Application&lt;/a&gt;, which is a chat platform that allows users to send messages in newly created chat rooms and engage in conversations with others in real-time.&lt;/p&gt;

&lt;h2&gt;Issue&lt;/h2&gt;

&lt;p&gt;The issue is to implement an alternative authenticate feature that allows users to sign-in/log-in with their Google accounts. The issue can be found &lt;a href="https://github.com/ShivamMadlani/chatApp/issues/5"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Approach to Tackling the Issue&lt;/h2&gt;

&lt;h4&gt;Authenticating with Google&lt;/h4&gt;

&lt;p&gt;The owner of the project stated that OAuth 2.0 needed to be used for the authentication, and so the first step to completing this issue is to understand how to integrate OAuth 2.0 authentication with Google for a Node.js server. A quick Google search led me to the use of &lt;code&gt;Passport.js&lt;/code&gt; which I have been exposed to, so I plan start there and work my way up.&lt;/p&gt;

&lt;h4&gt;Front-end &amp;amp; Back-end Changes&lt;/h4&gt;

&lt;p&gt;Along with integrating OAuth 2.0, I'll need to update the back-end to handle the Google requests and authentication tokens and also store the relevant data. I'll also need to update the front-end to display the Google sign-in component so that users can actually use it.&lt;/p&gt;

&lt;h4&gt;Testing&lt;/h4&gt;

&lt;p&gt;Since this is a new feature that will be implemented, thorough testing will be required to ensure that it functions as expected. Over the past few months, I have been exposed to &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; and I'm quite fond of it, and so I plan to write some Jest tests that will test different scenarios.&lt;/p&gt;

&lt;h2&gt;Learning&lt;/h2&gt;

&lt;p&gt;Having only implemented custom local authenticate measures in my projects thus far, progressing with this issue presents an opportunity to explore different variations one can use for user authentication and will broaden my experience with OAuth 2.0.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Contributing to Lumix Pt. 2</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Tue, 28 Nov 2023 04:53:26 +0000</pubDate>
      <link>https://dev.to/mismathh/contributing-to-lumix-pt-2-483l</link>
      <guid>https://dev.to/mismathh/contributing-to-lumix-pt-2-483l</guid>
      <description>&lt;p&gt;Continuing from my &lt;a href="https://dev.to/mismathh/contributing-to-lumix-pt1-c0h"&gt;previous article&lt;/a&gt;, I decided to create two more React components for &lt;a href="https://github.com/Keerat666/Lumix"&gt;Lumix&lt;/a&gt;. Lumix is a React UI library that provides versatile UI elements that can be added to your web development project.&lt;/p&gt;

&lt;h2&gt;Issue - Accordion Component&lt;/h2&gt;

&lt;p&gt;Another &lt;a href="https://github.com/Keerat666/Lumix/issues/43"&gt;issue&lt;/a&gt; that I picked up was to create a reusable component that can open single or multiple accordions and display their content. An accordion in regards to UI web design, is a vertically stacked list of headers that can be triggered to reveal/hide content associated with it.&lt;/p&gt;

&lt;h2&gt;Working on Accordion Component&lt;/h2&gt;

&lt;p&gt;The concept of showing/hiding a &lt;code&gt;div&lt;/code&gt; for the header content was fairly simple in implementing, as my initial plan was to use a &lt;code&gt;useState&lt;/code&gt; variable to act as a toggle for the Accordion component, but it got a little tricky dealing with multiple accordions. When there's multiple accordions, my initial implementation either opened or closed up all of the accordions, which was not the goal here as I needed to provide the functionality to open an accordion without affecting the others. &lt;/p&gt;

&lt;p&gt;My fix to this was to create a &lt;code&gt;useState&lt;/code&gt; variable to hold all of the index values of the &lt;code&gt;opened&lt;/code&gt; accordions and to have a function like &lt;code&gt;handleClick()&lt;/code&gt; to add or remove an accordion index from the useState variable array each time an accordion header is clicked on.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setOpenIndexes&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setOpenIndexes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setOpenIndexes&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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;wrapper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;justifyContent&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;verticalAlignment&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;span class="o"&gt;&amp;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;accordion&lt;/span&gt;&lt;span class="dl"&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;items&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;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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;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;section&lt;/span&gt;&lt;span class="dl"&gt;"&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;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;marginBottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5px&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="o"&gt;&amp;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;title&lt;/span&gt;&lt;span class="dl"&gt;"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
              &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
                &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;space-between&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10px 20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;backgroundColor&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;titleColor&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="na"&gt;fontSize&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;titleSize&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;width&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;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&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;1px solid black&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="p"&gt;,&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;span&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;openIndexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&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;-&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;+&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;/span&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how the Accordion component looks like with default prop values:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HtNDlN1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67ar0nad6xmuewtsa1df.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HtNDlN1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67ar0nad6xmuewtsa1df.JPG" alt="Accordion component" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My PR for this issue can be found &lt;a href="https://github.com/Keerat666/Lumix/pull/69"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Issue - Tabs Component&lt;/h2&gt;

&lt;p&gt;Another &lt;a href="https://github.com/Keerat666/Lumix/issues/42"&gt;issue&lt;/a&gt; that I worked on was to create a reusable component that is able to render multiple tabs and to display content of an active tab.&lt;/p&gt;

&lt;h2&gt;Working on Tabs Component&lt;/h2&gt;

&lt;p&gt;Working on this issue was a bit easier than the Accordion issue, as my initial implementation for that can work here (have a &lt;code&gt;useState&lt;/code&gt; variable act like a toggle to only display a certain tab). Additionally, to better signify that a tab is interactive and can be clicked on, I used the &lt;code&gt;cursor: 'pointer'&lt;/code&gt; style property to display a pointer cursor whenever the user points over a tab.&lt;/p&gt;

&lt;p&gt;This is how the Tabs component looks like with default prop values:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cEoy2exY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y1nosbuljnpm5oobbhj.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cEoy2exY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y1nosbuljnpm5oobbhj.JPG" alt="Tabs component" width="800" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My PR can be found &lt;a href="https://github.com/Keerat666/Lumix/pull/70"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Learning Outcomes with Lumix&lt;/h2&gt;

&lt;p&gt;Overall, these issues that I have worked on for the Lumix project  enhanced my proficiency in crafting React components with exceptional user interface design. Compared to my contributions in Hacktoberfest23, they weren't necessarily hard to do, but I learned many minor details and concepts that I was able to explore only because I had the freedom to create highly customizable components. Looking forward to contributing to more open-source projects in the future!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ui</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Contributing to Lumix Pt.1</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Tue, 28 Nov 2023 04:27:04 +0000</pubDate>
      <link>https://dev.to/mismathh/contributing-to-lumix-pt1-c0h</link>
      <guid>https://dev.to/mismathh/contributing-to-lumix-pt1-c0h</guid>
      <description>&lt;p&gt;Throughout Hacktoberfest23, I stumbled upon &lt;a href="https://github.com/Keerat666/Lumix"&gt;Lumix&lt;/a&gt;, which is a repository dedicated to providing versatile UI elements to enhance web development projects. Although some of the interesting issues were picked up during Hacktoberfest, there were some that I had an interest in working on. &lt;/p&gt;

&lt;h2&gt;Issue - Date Picker Component&lt;/h2&gt;

&lt;p&gt;One of the &lt;a href="https://github.com/Keerat666/Lumix/issues/26"&gt;issues&lt;/a&gt; I worked on was to design and implement a date picker component that is able to select dates. &lt;/p&gt;

&lt;h2&gt;Working on Issue&lt;/h2&gt;

&lt;p&gt;Apart from creating the core component, the goal here was to provide a high degree of customization capabilities for the component so that the user will be able to make their own changes to the component to fit their own project.&lt;/p&gt;

&lt;p&gt;To create the core date picker component, I decided to implement an input tag with the type of &lt;code&gt;date&lt;/code&gt;. This attribute creates a date input field that the user can select a date either from a drop down calendar or by entering it in the text box.&lt;/p&gt;

&lt;p&gt;To allow users to retrieve the date and possibly perform an action based on the value, I added in a prop that can take in a function which will receive the date value if the date has been changed from within the date picker component.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDate&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="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;handleDateChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;setDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onDateChange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;onDateChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="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;input&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleDateChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;borderWidth&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;borderWidth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;borderColor&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;borderColor&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="na"&gt;height&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;pickerHeight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&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;pickerWidth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontSize&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;fontSize&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 10px&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many of the previous contributions to Lumix worked with &lt;a href="https://www.npmjs.com/package/prop-types"&gt;PropTypes&lt;/a&gt; in order to verify the passed prop value is of the correct datatype. It was my first time using it, but essentially PropTypes can be used to check your values during run-time and although it wasn't necessary in the component, I decided to keep it in there to also provide additional information on the component for people that will read it. To use PropTypes we need to first import it:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&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="s2"&gt;prop-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PropTypes is an object with a key and value pair where the &lt;code&gt;key&lt;/code&gt; is the name of the prop and the &lt;code&gt;value&lt;/code&gt; is the type that is defined.&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="nx"&gt;DatePicker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onDateChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pickerHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pickerWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, with the &lt;code&gt;defaultProps&lt;/code&gt; property, you are able to set the default values of the props within the component. Although I prefer to provide the default values within the function signature, this is an alternative method with PropTypes.&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="nx"&gt;DatePicker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onDateChange&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pickerHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pickerWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how the Date Picker component will look with it's default prop values.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zwg7nGFq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz0ff4l5c8p3ndrlmuml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zwg7nGFq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz0ff4l5c8p3ndrlmuml.png" alt="Date Picker component" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although it has not been reviewed yet, my PR can be found &lt;a href="https://github.com/Keerat666/Lumix/pull/68"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ui</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Creating a Release for my Project</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Fri, 24 Nov 2023 17:55:25 +0000</pubDate>
      <link>https://dev.to/mismathh/creating-a-release-for-my-project-agj</link>
      <guid>https://dev.to/mismathh/creating-a-release-for-my-project-agj</guid>
      <description>&lt;p&gt;I am proud to announce my release for my &lt;a href="https://github.com/mismathh/TILerator"&gt;TILerator&lt;/a&gt; project with &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Process for Creating a Release&lt;/h2&gt;

&lt;p&gt;The npm &lt;a href="https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry"&gt;documentation&lt;/a&gt; provided substantial information on how to contribute to the registry. These are the steps I took in order to add my project to the npm registry and also the challenges I faced:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This was my first time creating a release and publishing it to npm, so I needed to first create an account on &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Within the terminal I logged into the newly created npm account using &lt;code&gt;npm login&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;One common file between all npm packages is the &lt;code&gt;package.json&lt;/code&gt; file. npm uses this file to describe your package and manage your dependencies, and if you are planning to publish to the npm registry you must have this package.json file. If you are a just starting out with your project, running &lt;code&gt;npm init&lt;/code&gt; and following the instructing will help setup the package.json file for you.&lt;/li&gt;
&lt;li&gt;The prerequisites have been completed and my project is now ready to be &lt;a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging"&gt;tagged&lt;/a&gt; with version number based on &lt;a href="https://semver.org/"&gt;semantic versioning&lt;/a&gt;. Prior to this, my project was at &lt;code&gt;v0.9.1&lt;/code&gt; and since it was ready to be released, I used &lt;code&gt;npm version major&lt;/code&gt; to update it to &lt;code&gt;v1.0.0&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;I then pushed my tags to GitHub using &lt;code&gt;git push --follow-tags&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Finally, it was time to publish to the registry with &lt;code&gt;npm publish --access=public&lt;/code&gt;. If you have been following along with these steps for your own project and everything has been going well up to this point, then congrats! You have successfully managed to publish your package to the npm registry. Unfortuntely, for me, I had to do a little more fixing to my package. After running the publish command, I was faced with an error. 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fVo5X3yg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dvrdhw16t2mzn2iykky.JPG" alt="Error whilst running npm publish" width="800" height="193"&gt;
I was initially quite confused by this error, but a quick Google search showed me that one of the reasons for this error was if there is already a package with the same name as mine on npm. To my surprise, a search on the npm website showed a package called "tilerator" that was published 7 years ago! After reading the npm documentation, I found out that I could &lt;a href="https://docs.npmjs.com/cli/v10/using-npm/scope"&gt;scope&lt;/a&gt; my package to make it unique. You can make your package a scoped package by adding a scope name in between an &lt;code&gt;@&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt;, followed by the name of your project, such as: &lt;code&gt;@scopename/packagename&lt;/code&gt;. I needed to change the name of my project inside the package.json file with my new scoped name, &lt;code&gt;@mismathh/tilerator&lt;/code&gt; and ran &lt;code&gt;npm install&lt;/code&gt; to also update the package.lock file. After repeating steps 4-5, running &lt;code&gt;npm publish --access=public&lt;/code&gt; worked. My release can be found &lt;a href="https://www.npmjs.com/package/@mismathh/tilerator"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;How to Install&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;npm install @mismathh/tilerator -g&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;User Testing&lt;/h2&gt;

&lt;p&gt;User testing went quite well in regards to the main functionality of the package, but it was brought to my attention that I needed to add more details to my README for the optional features. Using the &lt;code&gt;--config&lt;/code&gt; flag was quite difficult to use for them since they didn't know what options to add inside the config file, and also it was noted that I didn't have to use &lt;code&gt;TILerator&lt;/code&gt; in every command, and &lt;code&gt;tilerator&lt;/code&gt; was fine.&lt;/p&gt;

&lt;h2&gt;Learning Outcomes&lt;/h2&gt;

&lt;p&gt;It was a great learning experience to publish my project to the npm registry. Over my programming journey I have used many npm packages for my projects but I never got to experience how those packages are placed into a public registry for developers to use, until now. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>opensource</category>
      <category>npm</category>
      <category>programming</category>
    </item>
    <item>
      <title>Adding Continuous Integration (CI) to my Open Source Project</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Fri, 17 Nov 2023 23:00:36 +0000</pubDate>
      <link>https://dev.to/mismathh/adding-continuous-integration-ci-to-my-open-source-project-4nl</link>
      <guid>https://dev.to/mismathh/adding-continuous-integration-ci-to-my-open-source-project-4nl</guid>
      <description>&lt;p&gt;This week I added Continuous Integration to my open source project, &lt;a href="https://github.com/mismathh/TILerator"&gt;TILerator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;GitHub Actions Workflow&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://docs.github.com/en/actions/learn-github-actions"&gt;GitHub Actions&lt;/a&gt; to set up my CI, which is a great platform you can use on GitHub to automate your builds, tests, and deployment pipeline. I created a &lt;a href="https://github.com/mismathh/TILerator/blob/main/.github/workflows/ci.yml"&gt;ci.yml&lt;/a&gt; file and added a Unit Test job to run my tests with every push or pull request to the main branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b46oCOCp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wv0ks37uoc4h6bgqs4ak.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b46oCOCp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wv0ks37uoc4h6bgqs4ak.JPG" alt="CI workflow" width="591" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Adding Tests to Another Project&lt;/h2&gt;

&lt;p&gt;I also had an opportunity to contribute tests to one of my classmate's project. They also used Jest for their project's testing framework, so it was fairly easy to set up new tests. Since I'm used to JavaScript and their project was built in TypeScript, I needed to brush up on the differences between them to avoid writing poor tests. It was interesting to see that for the tests I wrote for my program, I needed to validate the parameter types, but those kind of tests weren't needed in my classmate's project due to TypeScript being a strongly typed language. After reviewing their files, I found a function that converts Markdown syntax for code blocks into the appropriate HTML tags, and decided to write a few tests for that function. The tests I added can be found in this &lt;a href="https://github.com/seog-jun/til-tool/pull/20"&gt;Pull Request&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Thoughts on CI&lt;/h2&gt;

&lt;p&gt;Now that I have set up CI for my project, I think that it's a great tool to use in your projects to automate tests and error checks. Making it so it checks any push or pull request to your repo for errors prevents any major or minor errors to slip by unnoticed. It was also quite easy setting it up through GitHub Actions, so I plan on adding CI to my future projects.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Implementing a Testing Framework</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Sat, 11 Nov 2023 03:04:38 +0000</pubDate>
      <link>https://dev.to/mismathh/implementing-a-testing-framework-2m0p</link>
      <guid>https://dev.to/mismathh/implementing-a-testing-framework-2m0p</guid>
      <description>&lt;p&gt;This week I managed to add a testing framework to my open source project, &lt;a href="https://github.com/mismathh/TILerator"&gt;TILerator&lt;/a&gt;. Since it's a JavaScript project, I decided to use &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; as my testing framework.&lt;/p&gt;

&lt;h2&gt;What is Jest?&lt;/h2&gt;

&lt;p&gt;Jest is a JavaScript testing framework developed by Facebook, and is widely used for testing JavaScript and React applications. I have been exposed to Jest in other projects and along with having a detailed &lt;a href="https://jestjs.io/docs/getting-started"&gt;documentation&lt;/a&gt;, it is quite easy to install.&lt;/p&gt;

&lt;h3&gt;Setting up Jest&lt;/h3&gt;

&lt;p&gt;Jest is needed only for testing purposes so install it as a dev dependency.&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="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add a test script to your &lt;code&gt;package.json&lt;/code&gt; file to be able to run tests using Jest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest --"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest --watch --"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, create a testing directory to hold all of you tests.&lt;/p&gt;

&lt;h2&gt;Writing Tests&lt;/h2&gt;

&lt;p&gt;For my first test, I decided to test out a function that receives a string and checks if a certain &lt;code&gt;regex&lt;/code&gt; pattern can be matched, and if it can, it adds an HTML &lt;code&gt;&amp;lt;b&amp;gt;&amp;lt;/b&amp;gt;&lt;/code&gt; tags to the string. I wrote 5 tests to check on the function's behaviour with certain inputs.&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="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;markdownToHTML tests&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return a string with &amp;lt;b&amp;gt; tags if part of string is encompassed between **&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdownToHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**sentence 1**  sentence 2  **sentence 3**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;b&amp;gt;sentence 1&amp;lt;/b&amp;gt;  sentence 2  &amp;lt;b&amp;gt;sentence 3&amp;lt;/b&amp;gt;&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to test out the core functionality of the program, I also wrote 3 tests to confirm if the correct output would be returned. There was one hiccup when writing these tests, as within the core functions, I used &lt;code&gt;process.exit()&lt;/code&gt; to exit the program on certain conditions, and if it is called within a Jest test, it will immediately stop the test runner which could lead to incomplete test results.&lt;/p&gt;

&lt;p&gt;After reading the documentation to combat this, I found out about  &lt;code&gt;mock functions&lt;/code&gt; and &lt;code&gt;spyOn()&lt;/code&gt;. Using mock functions and &lt;code&gt;mockImplmentation()&lt;/code&gt;, we can define the default implementation of a mock function, and the spyOn() function can be used to monitor the behaviour of the function. Combining these functions resulted in being able to monitor &lt;code&gt;process.exit()&lt;/code&gt; to check the exit code that was outputted while not actually exiting the process.&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="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should exit with exit code -1 and error message if invalid file path is given&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockStdErr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spyOn&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;mockImplementation&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;mockExit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;mockImplementation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The testing commit can be found here: &lt;a href="https://github.com/mismathh/TILerator/commit/fc128e073795b80cf1ce7474c14c60aaedb530f2"&gt;fc128e0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Learning Outcomes&lt;/h2&gt;

&lt;p&gt;Despite working with Jest before in other JavaScript projects, there was still a lot that I learned on the capabilities of Jest. Additionally, from writing all those tests, I improved my understanding of TILerator. Testing should be a fundamental process that is used within your project to not only identify bugs, but to also create reliable software. If you have a JavaScript project that needs a testing framework, try out Jest!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Recap of my First Hacktoberfest</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Wed, 01 Nov 2023 03:49:32 +0000</pubDate>
      <link>https://dev.to/mismathh/recap-of-my-first-hacktoberfest-2pdj</link>
      <guid>https://dev.to/mismathh/recap-of-my-first-hacktoberfest-2pdj</guid>
      <description>&lt;p&gt;October 31st. That means it's Halloween 🎃, but it also marks the end of Hacktoberfest23. I had the privilege of taking part in Hacktoberfest 2023 this year and it was an intimidating, yet rewarding experience, learning about how to contribute to open-source projects and improving my knowledge as a developer. I will be recapping my progress for my first Hacktoberfest!&lt;/p&gt;

&lt;h2&gt;PRs&lt;/h2&gt;

&lt;p&gt;#1 - &lt;a href="https://github.com/X-Evolve/Python_Hunt"&gt;Python Hunt&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/X-Evolve/Python_Hunt/issues/10"&gt;Issue&lt;/a&gt;, &lt;a href="https://github.com/X-Evolve/Python_Hunt/pull/29"&gt;PR&lt;/a&gt;, &lt;a href="https://dev.to/mismathh/first-pull-request-in-hacktoberfest23-4j8d"&gt;Blog Post&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my first issue, I worked on creating a webpage in a Django project that describes key Python variables, for Python beginners. The webpage primarily was built with JavaScript, but Python was used elsewhere and I needed to understand how to set up the route for my created webpage. Despite it being my first time working with Python and Django, the Django documentation was well written and I was able to learn what I needed to in order to implement this feature.&lt;/p&gt;

&lt;p&gt;#2 - &lt;a href="https://github.com/Leo5661/Starwar-Archive"&gt;Starwar Archive&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Leo5661/Starwar-Archive/issues/3"&gt;Issue&lt;/a&gt;, &lt;a href="https://github.com/Leo5661/Starwar-Archive/pull/13"&gt;PR&lt;/a&gt;, &lt;a href="https://dev.to/mismathh/2nd-pull-request-in-hacktoberfest23-3gmj"&gt;Blog Post&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my second issue, I dived into React and worked on creating a page that displayed detailed information of a Star Wars character. This was probably my most challenging issue that I worked on this Hacktoberfest, as I needed to learn how to use &lt;a href="https://tanstack.com/query/v4/docs/react/reference/useQuery"&gt;useQuery&lt;/a&gt; and &lt;a href="https://tanstack.com/query/v4/docs/react/reference/useQueries"&gt;useQueries&lt;/a&gt; and majority of my time went into this. Additionally, adding in the necessary CSS tags to make an ideal page layout took a lot of trial and error. It was a great issue to work on and I definitely gained some experience with React apps.&lt;/p&gt;

&lt;p&gt;#3 - &lt;a href="https://github.com/mgreiler/se-unlocked"&gt;Software Engineering Unlocked Podcast&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mgreiler/se-unlocked/issues/197"&gt;Issue&lt;/a&gt;, &lt;a href="https://github.com/mgreiler/se-unlocked/pull/198"&gt;PR&lt;/a&gt;, &lt;a href="https://dev.to/mismathh/3rd-pull-request-in-hacktoberfest23-34gf"&gt;Blog Post&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my third issue, I worked on improving a transcript for a podcast episode. This issue was the one that shocked me the most as I went into this issue thinking it wouldn't take much time, but I had to rewind the recording multiple times for each section to make sure everything matched between the recording and transcript. Although this wasn't a code related issue, I learned a lot by having to research the terms used and just by listening to the recording, as the episode was quite informational.&lt;/p&gt;

&lt;p&gt;#4 - Back to &lt;a href="https://github.com/Leo5661/Starwar-Archive"&gt;Starwar Archive&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Leo5661/Starwar-Archive/issues/5"&gt;Issue&lt;/a&gt;, &lt;a href="https://github.com/Leo5661/Starwar-Archive/pull/14"&gt;PR&lt;/a&gt;, &lt;a href="https://dev.to/mismathh/4th-pull-request-in-hacktoberfest23-4f0j"&gt;Blog Post&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my fourth and final Hacktoberfest issue, I went back to a project that I worked on earlier in the month (#2). This time I worked on a issue to create a page for each starship that can be pulled from &lt;a href="https://swapi.dev/documentation"&gt;SWAPI&lt;/a&gt;. What was interesting to see while working on this issue was that I needed to improve the changes I made from PR #2 in order to add my changes to this issue. &lt;/p&gt;

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

&lt;p&gt;Contributing to open-source projects was quite daunting for me initially, but participating in Hacktoberfest 2023 was an amazing experience and it really helped boost my confidence as a developer. If you had told me a few months before today, that I would be able to successfully complete four pull requests for multiple open-source projects, I would've said you were crazy, but here I am 🤩! My only regret was that I was unable to sequentially find issues that gradually increased in difficulty, but this only pushes me further to continue to find issues that will help me improve my developer skills.&lt;/p&gt;

&lt;p&gt;Although my Hacktoberfest23 journey comes to an end, I hope that my open-source journey continues for a long time. Looking forward to Hacktoberfest24 and seeing you on my next blog post!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>hacktoberfest23</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>4th Pull Request in Hacktoberfest23</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Wed, 01 Nov 2023 02:00:09 +0000</pubDate>
      <link>https://dev.to/mismathh/4th-pull-request-in-hacktoberfest23-4f0j</link>
      <guid>https://dev.to/mismathh/4th-pull-request-in-hacktoberfest23-4f0j</guid>
      <description>&lt;p&gt;For my 4th pull request for Hacktoberfest23, I decided to head back to a previous project that I had worked on during this month, &lt;a href="https://github.com/Leo5661/Starwar-Archive"&gt;Starwar Archive&lt;/a&gt;. This project is a React application that pulls character information from &lt;a href="https://swapi.dev/documentation"&gt;SWAPI&lt;/a&gt; and displays key information for each character as a list.&lt;/p&gt;

&lt;h2&gt;The Issue&lt;/h2&gt;

&lt;p&gt;I found an open issue that I was interested in working on which was to &lt;a href="https://github.com/Leo5661/Starwar-Archive/issues/5"&gt;add starships details&lt;/a&gt;, but the description was missing. I requested for more information from the owner under the issue. My &lt;a href="https://github.com/Leo5661/Starwar-Archive/issues/3"&gt;previous issue&lt;/a&gt; that I worked on in this project was to create a description page that would be able to list out detailed information about a character. Like my previous issue, I proposed to create a new page to describe each starship. I did not receive a reply and I was a bit hesitant to start without a reply, but I decided to make my proposed changes and submit a PR and ask the owner if the changes were adequate.&lt;/p&gt;

&lt;h2&gt;Process&lt;/h2&gt;

&lt;p&gt;Since I have already forked the repository for an earlier issue, I just needed to create a new branch for this new issue that I planned to work on.&lt;/p&gt;

&lt;h3&gt;Implementing Changes&lt;/h3&gt;

&lt;p&gt;Since the only place that displays the name of a starship is within the person description page, I decided to attach a link to the starship name to redirect users to the starship description page. The starship name will be highlighted once the user hovers over the starship name to signify that it's a link.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F3gUKewR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u080ma7cnx7185sy4a2a.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F3gUKewR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u080ma7cnx7185sy4a2a.JPG" alt="Person Description Page" width="800" height="825"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What was also interesting to see was that in order to implement my changes for this issue, I needed to improve my changes I made to the API fetch method from my previous issue. If the information of a person can be found from within a separate endpoint of SWAPI, it would just provide the URL instead of the information.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WMqypP7e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xbg36ciljjqa9ut988l.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WMqypP7e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xbg36ciljjqa9ut988l.JPG" alt="Sample fetch from SWAPI" width="541" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And so in my earlier implementation, I decided to just send the URL to the fetch call to receive the data.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EXMUr6i5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5me2gg4q4avz7he197ut.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EXMUr6i5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5me2gg4q4avz7he197ut.JPG" alt="Old implementation of Starship API fetch" width="568" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the Starship page, I needed the &lt;code&gt;id&lt;/code&gt; of the starship which is found at the end of the URL, and so I decided to edit the fetch call so that it also just requires the &lt;code&gt;id&lt;/code&gt; to make everything consistent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WTpVYoCz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d2mgech34jtilcjtfj47.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WTpVYoCz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d2mgech34jtilcjtfj47.JPG" alt="New implementation of Starship API fetch" width="800" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final result looks like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FsY6FAp9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzrklcdt81zaed9o57na.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FsY6FAp9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzrklcdt81zaed9o57na.JPG" alt="Starship Description Page" width="800" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After sending a friendly reminder to the owner, my &lt;a href="https://github.com/Leo5661/Starwar-Archive/pull/14"&gt;PR&lt;/a&gt; was approved and my contributions were merged.&lt;/p&gt;

&lt;h2&gt;Learning Outcomes&lt;/h2&gt;

&lt;p&gt;Overall, I enjoyed working on this issue and further improving a project that I had previously worked on. It was interesting to see that my initial implementation of certain features needed to be improved on in order to implement a new feature. It reminds me that the structure you build your code in may be ideal for the current situation at hand, but it may not be so for future features, and creating a code structure that makes it easy for future features to be implemented will improve the efficiency and maintainability of your project.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>opensource</category>
      <category>react</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>3rd Pull Request in Hacktoberfest23</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Tue, 31 Oct 2023 21:33:15 +0000</pubDate>
      <link>https://dev.to/mismathh/3rd-pull-request-in-hacktoberfest23-34gf</link>
      <guid>https://dev.to/mismathh/3rd-pull-request-in-hacktoberfest23-34gf</guid>
      <description>&lt;p&gt;For my next project to contribute to for Hacktoberfest23, I decided to work on &lt;a href="https://github.com/mgreiler/se-unlocked"&gt;Software Engineering Unlocked&lt;/a&gt;, which is a repository that holds transcripts for the &lt;a href="https://www.software-engineering-unlocked.com/"&gt;Software Engineering Unlocked Podcast&lt;/a&gt; to make it more accessible. The podcast provides a sneak peek into how software companies around the world develop software and developers from small startups to large companies come to talk about their useful experiences.&lt;/p&gt;

&lt;h2&gt;The Issue&lt;/h2&gt;

&lt;p&gt;There wasn't an issue that was open at the time I found the repo, but I noticed that within the README, it said that if we could find a transcript that needed to be improved, we could create an issue for it. After skimming through a few transcripts, I found that Episode #58 featuring Cat Hicks needed to be improved on, and so I created an &lt;a href="https://github.com/mgreiler/se-unlocked/issues/197"&gt;issue&lt;/a&gt; for it.&lt;/p&gt;

&lt;h2&gt;Process&lt;/h2&gt;

&lt;p&gt;There was no setup needed to work on this issue, as it just required me to make my changes within the markdown transcript file. There were a few general formatting questions I had, but I noticed that there were many other issues that were created prior to mine which were also about "improving an episode" and I was able to find the answers based on the questions they had asked the owner of the repo. Also, after reading the &lt;code&gt;Transcription_Guidelines.md&lt;/code&gt; file, I had a good sense of the changes I needed to make, and forked the repo and created a new branch to work on. &lt;/p&gt;

&lt;h2&gt;Implementing Changes&lt;/h2&gt;

&lt;p&gt;I initially went into this issue thinking that it wouldn't take much time to find errors and fix the transcript, but I was quite wrong. While I was editing the transcript, there were numerous times where I had to rewind the podcast recording to make sure I was hearing the words right and making the appropriate changes. There were also times where the auto-generated transcript had incorrectly spelled tech terms and I needed to do external research on the guest speaker to accurately understand the terms used.&lt;/p&gt;

&lt;p&gt;The list of changes that I made to the transcript were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spelling and punctuation fixes&lt;/li&gt;
&lt;li&gt;Addition of missing dialogue&lt;/li&gt;
&lt;li&gt;Addition of relevant non-text audio in parentheses&lt;/li&gt;
&lt;li&gt;Syncing timestamps&lt;/li&gt;
&lt;li&gt;Maintaining &amp;lt;= 80 character limit per line&lt;/li&gt;
&lt;li&gt;Removal of duplicated filler words&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After sending the owner a friendly reminder, the &lt;a href="https://github.com/mgreiler/se-unlocked/pull/198"&gt;PR&lt;/a&gt; that I submitted was approved and successfully merged.&lt;/p&gt;

&lt;h2&gt;Learning Outcomes&lt;/h2&gt;

&lt;p&gt;Prior to my open-source journey, I thought I needed to work on code-specific issues to actually provide valuable contributions to a project, but I'm glad I got to contribute to &lt;a href="https://www.software-engineering-unlocked.com/"&gt;Software Engineering Unlocked&lt;/a&gt;. Listening to the podcast recording was quite valuable to myself as I got to learn some new tech terms and got to hear about the experiences of a senior developer. This was a lesson for me that open-source contributions can come in many forms and issues such as just improving a markdown file is just as important to a project's success. Looking forward to the next project to contribute to!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>beginners</category>
      <category>markdown</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>2nd Pull Request in Hacktoberfest23</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Thu, 26 Oct 2023 23:42:35 +0000</pubDate>
      <link>https://dev.to/mismathh/2nd-pull-request-in-hacktoberfest23-3gmj</link>
      <guid>https://dev.to/mismathh/2nd-pull-request-in-hacktoberfest23-3gmj</guid>
      <description>&lt;p&gt;For my next project to contribute to for Hacktoberfest23, I decided to work on a React project to gain more experience and exposure to the different techniques used in React. I stumbled upon the &lt;a href="https://github.com/Leo5661/Starwar-Archive"&gt;Starwar Archive&lt;/a&gt; project, which is a React application that pulls data from an open Star Wars API called &lt;a href="https://swapi.dev/documentation"&gt;SWAPI&lt;/a&gt; to display information of each character.&lt;/p&gt;

&lt;h2&gt;The Issue&lt;/h2&gt;

&lt;p&gt;The issue I planned to work on was to create a &lt;a href="https://github.com/Leo5661/Starwar-Archive/issues/3"&gt;person description page&lt;/a&gt;. This page needed to show detailed information of a character once their character card was clicked on the homepage.&lt;/p&gt;

&lt;h2&gt;Process&lt;/h2&gt;

&lt;p&gt;To get started, I forked the repository, created a new branch and got to work. There wasn't much to setup beforehand as I just needed to install the package modules with &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Implementing Changes&lt;/h3&gt;

&lt;p&gt;The first thing I needed to decide on was the layout and overall color scheme of the page. As, the only page available was the home page, I decided to stay as close as possible to it and so I took some of the icons and the color scheme of the home page.&lt;/p&gt;

&lt;p&gt;The next issue that I had to deal with was retrieving the data from SWAPI. Initially, &lt;a href="https://tanstack.com/query/v4/docs/react/reference/useQuery"&gt;useQuery&lt;/a&gt; was used to fetch data from SWAPI. It was my first time dealing with useQuery and so I needed to do some research on how to use it. I found that useQuery is a cool custom hook within React Query that is used to fetch data in a React application. Under the hood, useQuery manages things such as caching data after the initial fetch and re-fetching data in the background. A useQuery hook requires two arguments. The first one is a key for the query, and the second one is a function to fetch the data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q0nOpKlJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwi9fg5o03tn0sq0yrs9.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q0nOpKlJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwi9fg5o03tn0sq0yrs9.JPG" alt="useQuery Example" width="660" height="30"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, what I found interesting with SWAPI, is that if some of the information of person can be found from within a different endpoint of the API, it would instead just provide the URL to it and not the actual information. An example response for a person would be like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vXCclCuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9tbenngg59dbv9bg5ey.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vXCclCuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9tbenngg59dbv9bg5ey.JPG" alt="Example response from SWAPI" width="541" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And so, one of the issues that came up was how to use useQuery for an array of URLs? After looking at the useQuery documentation again, I found another hook called &lt;a href="https://tanstack.com/query/v4/docs/react/reference/useQueries"&gt;useQueries&lt;/a&gt; which can be used to fetch from multiple URLs. There was a lot of trial and error with the structure of useQueries as it's slightly different from useQuery, but I was able to successfully fetch multiple queries from SWAPI for the data I needed. The final page looks like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0dPnStUt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0np0h5ckcbdvdj4ql1uk.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0dPnStUt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0np0h5ckcbdvdj4ql1uk.JPG" alt="Final result of page" width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After submitting my &lt;a href="https://github.com/Leo5661/Starwar-Archive/pull/13"&gt;PR&lt;/a&gt; with my changes, the owner quickly approved and merged my contributions.&lt;/p&gt;

&lt;h3&gt;Learning Outcomes&lt;/h3&gt;

&lt;p&gt;Overall, it was great working on a React project and learning about some new hooks that I will definitely implement in my future projects. Looking forward to the next project to contribute to!&lt;/p&gt;

</description>
      <category>hacktoberfest23</category>
      <category>react</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>First Pull Request in Hacktoberfest23</title>
      <dc:creator>mismathh</dc:creator>
      <pubDate>Mon, 09 Oct 2023 16:18:29 +0000</pubDate>
      <link>https://dev.to/mismathh/first-pull-request-in-hacktoberfest23-4j8d</link>
      <guid>https://dev.to/mismathh/first-pull-request-in-hacktoberfest23-4j8d</guid>
      <description>&lt;p&gt;As I dive into the 2nd month of my open-source journey, it just so happens to also be the month of  &lt;a href="https://hacktoberfest.com/"&gt;Hacktoberfest&lt;/a&gt;! This is my first time participating in Hacktoberfest and I wanted to share the process of my first &lt;a href="https://github.com/X-Evolve/Python_Hunt/pull/29"&gt;Hacktoberfest PR&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Looking for Issues&lt;/h2&gt;

&lt;p&gt;For my first contribution, I wanted to work on a small issue to start off, and gradually work my way up to more challenging issues. It was initially quite overwhelming to see all the different types of issues that were available, but using labels such as &lt;code&gt;label:hacktoberfest&lt;/code&gt;, &lt;code&gt;label:"good first issue"&lt;/code&gt;, and sorting by &lt;code&gt;Least Commented&lt;/code&gt; helped greatly.&lt;/p&gt;

&lt;p&gt;Through my search, I stumbled upon the &lt;a href="https://github.com/X-Evolve/Python_Hunt"&gt;Python_Hunt&lt;/a&gt; repository, which is a web-based project that revolves around providing summarized notes on key topics on the Python programming language to help make learning Python easier for newcomers. The project currently uses &lt;code&gt;Django&lt;/code&gt;, which is an open-source Python-based web framework that allows you to quickly develop secure and maintainable websites.&lt;/p&gt;

&lt;h2&gt;The Issue&lt;/h2&gt;

&lt;p&gt;The issue I decided to request to work on was to &lt;a href="https://github.com/X-Evolve/Python_Hunt/issues/10"&gt;create a webpage for "Tuples in Python"&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;Process&lt;/h2&gt;

&lt;p&gt;After getting approval, I forked the issue, created a new branch and prepared to setup my local system.&lt;/p&gt;

&lt;h3&gt;Setup&lt;/h3&gt;

&lt;p&gt;There was not much that I needed to setup, but since this was my first time working with this web framework, I needed to install Python and Django. After that, I needed to run a &lt;code&gt;python manage.py migrate&lt;/code&gt; command to create database tables and a &lt;code&gt;python manage.py runserver&lt;/code&gt; to start the server.&lt;/p&gt;

&lt;h3&gt;Implementing Changes&lt;/h3&gt;

&lt;p&gt;Essentially, this issue required me to create a &lt;code&gt;.html&lt;/code&gt; page that described what a &lt;code&gt;Tuple&lt;/code&gt; is in Python, and to provide some examples. I also needed to add in the correct routes so that users will be able to navigate to the newly created page. This was my first time using Django, so I needed to do a little bit of research to understand how routes worked on Django. To summarize, Django uses a function called &lt;code&gt;path()&lt;/code&gt; which accepts two parameters: a &lt;code&gt;URL&lt;/code&gt; (&lt;em&gt;the URL for the webpage&lt;/em&gt;) and a &lt;code&gt;View&lt;/code&gt; function (&lt;em&gt;will hold the logic to render the page&lt;/em&gt;). Once the URL entered in the browser matches a URL described within &lt;code&gt;path()&lt;/code&gt; it will then invoke the &lt;code&gt;View&lt;/code&gt; function to render the page.&lt;/p&gt;

&lt;h2&gt;Learning Outcomes&lt;/h2&gt;

&lt;p&gt;Overall, submitting this PR was a great learning experience for me as I got to interact with the community and contribute to another open-source project. It was also interesting to work on a project that involved Django. Looking forward to contributing to other projects during Hacktoberfest!&lt;/p&gt;

</description>
      <category>hacktoberfest23</category>
      <category>html</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
