<?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: Thiago Marinho</title>
    <description>The latest articles on DEV Community by Thiago Marinho (@tgmarinhodev).</description>
    <link>https://dev.to/tgmarinhodev</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%2F121673%2F8e95f65d-e14c-4883-a389-170bad234319.jpeg</url>
      <title>DEV Community: Thiago Marinho</title>
      <link>https://dev.to/tgmarinhodev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tgmarinhodev"/>
    <language>en</language>
    <item>
      <title>Commit Message Patterns: Write Better Git History</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Fri, 21 Feb 2025 13:51:14 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/commit-message-patterns-write-better-git-history-1bb5</link>
      <guid>https://dev.to/tgmarinhodev/commit-message-patterns-write-better-git-history-1bb5</guid>
      <description>&lt;p&gt;Type: What kind of change (see below).&lt;br&gt;
Scope (optional): What’s affected (e.g., auth, ui, docs).&lt;br&gt;
Description: Short, present-tense summary (50-72 chars).&lt;br&gt;
Body (optional): More details, why it’s done.&lt;br&gt;
Footer (optional): Metadata like "Fixes #123" or "BREAKING CHANGE"&lt;/p&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%2Futwchym8qkl6ufbn29a4.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%2Futwchym8qkl6ufbn29a4.png" alt="Image description" width="800" height="674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Types of Commit Messages
&lt;/h2&gt;

&lt;p&gt;Here’s a quick reference table for the most frequently used commit types in Conventional Commits:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;feat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New feature&lt;/td&gt;
&lt;td&gt;&lt;code&gt;feat(ui): add dark mode toggle&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fix&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bug fix&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fix(auth): resolve token expiry&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Documentation updates&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docs(readme): update install steps&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Formatting, no logic change&lt;/td&gt;
&lt;td&gt;&lt;code&gt;style(css): adjust padding&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;refactor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Code cleanup, no behavior change&lt;/td&gt;
&lt;td&gt;&lt;code&gt;refactor(api): simplify fetch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add or update tests&lt;/td&gt;
&lt;td&gt;&lt;code&gt;test(unit): cover login edge cases&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Maintenance (deps, tools)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chore(deps): update lodash&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;perf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Performance improvement&lt;/td&gt;
&lt;td&gt;&lt;code&gt;perf(db): optimize query&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ci&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CI/CD changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ci(pipeline): add lint step&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build system changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;build(webpack): minify output&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;revert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Revert a previous commit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;revert: undo feat(ui)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  How to Use This Table
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type&lt;/strong&gt;: Start your commit with one of these keywords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope&lt;/strong&gt; (optional): Add in parentheses (e.g., &lt;code&gt;ui&lt;/code&gt;, &lt;code&gt;auth&lt;/code&gt;) to specify the area of change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description&lt;/strong&gt;: Keep it short, present tense, and descriptive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cheat Sheet Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Simple Feature
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(api): add user profile endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fix with Details
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix(cart): prevent duplicate items
- Added check for existing item ID
- Fixes #45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Breaking Change
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(auth): switch to JWT tokens
- Replaced session cookies with JWT
BREAKING CHANGE: Old tokens invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Chore
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chore(deps): bump react to 18.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Refactor
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;refactor(utils): extract logger to module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Improves reusability across files&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Scope: Keep it lowercase, short (e.g., ui, server).&lt;/li&gt;
&lt;li&gt;Breaking Changes: Flag with ! after type (e.g., &lt;code&gt;feat(ui)!: redo layout&lt;/code&gt;) or note in footer.&lt;/li&gt;
&lt;li&gt;Tools: Use with semantic versioning or changelog generators (e.g., standard-version).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>development</category>
    </item>
    <item>
      <title>How to Add Blurred Text in React Native</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Thu, 15 Feb 2024 20:19:21 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/how-to-add-blurred-text-in-react-native-4646</link>
      <guid>https://dev.to/tgmarinhodev/how-to-add-blurred-text-in-react-native-4646</guid>
      <description>&lt;p&gt;If you're looking for a stylish way to hide certain information in your React Native app, adding blurred text can be a visually appealing solution. In this tutorial, I'll show you how to integrate blurred text into your components using React Native easily.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Installation
&lt;/h3&gt;

&lt;p&gt;Depending on your development environment, you may need to install the expo-blur package if you're using Expo or react-native-blur for standard React Native projects. You can do this by running the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn add expo-blur


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn add react-native-blur
&lt;span class="nb"&gt;cd &lt;/span&gt;ios &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pod-install



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Step 2: Creating the Component
&lt;/h3&gt;

&lt;p&gt;Let's start by creating a component called Blurred. This component will accept two optional parameters: intensity and tint. You can use the following code:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;ReactNode&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BlurView&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;expo-blur&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// or 'react-native-blur' for React Native projects&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;View&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;native-base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BlurredProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;tint&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&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;const&lt;/span&gt; &lt;span class="nx"&gt;Blurred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;intensity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;BlurredProps&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;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;View&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;children&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;BlurView&lt;/span&gt;
        &lt;span class="nx"&gt;intensity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;tint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tint&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;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;absolute&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/View&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;
  
  
  Step 3: Adding it to Your Logic
&lt;/h3&gt;

&lt;p&gt;Now, you can use the Blurred component in your logic as follows:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Promotion&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="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;userCanSeePromo&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;Blurred&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;Typography&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gray.500&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promo&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;/Typography&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;/Blurred&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;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;Typography&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gray.500&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;full_price&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;/Typography&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;p&gt;Feel free to adjust the intensity and tint as needed. This will give you a visually appealing effect like the one shown in the image provided.&lt;/p&gt;

&lt;p&gt;You will have something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fv3vjkxf4qomdztzx750q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fv3vjkxf4qomdztzx750q.jpeg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used it three times in this card to hide some pieces of information.&lt;/p&gt;

&lt;p&gt;You can use it with react-native or even with native-base ui. In my project, I'm using native-base and it works perfectly.&lt;/p&gt;

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

&lt;p&gt;Adding blurred text to your React Native app can enhance its visual appeal and provide a modern touch to your UI. You can just experiment with different intensities and tints to achieve the desired effect in your application.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>blur</category>
      <category>expo</category>
      <category>text</category>
    </item>
    <item>
      <title>Organizing Your Backend: Choosing Between Services and Helpers</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Mon, 15 Jan 2024 20:03:01 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/organizing-your-backend-choosing-between-services-and-helpers-1p5l</link>
      <guid>https://dev.to/tgmarinhodev/organizing-your-backend-choosing-between-services-and-helpers-1p5l</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When it comes to developing a robust backend, code organization plays a crucial role in the maintainability and scalability of the project. In this article, we'll delve into the difference between two key components: "services" and "helpers," and how to effectively organize them within your folder structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service: The Backbone of Business Logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Services are the heart of your backend, responsible for encapsulating application-specific business logic. They handle complex operations, interact with the database, and play a vital role in enforcing domain rules. Let's explore why services are essential:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstraction of Business Logic:&lt;/strong&gt; Services abstract complex operations, providing a clean interface for the rest of the application. This promotes cohesion and makes the code more understandable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Interaction:&lt;/strong&gt; Often, services are directly tied to data persistence. They manage queries, updates, and ensure data integrity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusability and Scalability:&lt;/strong&gt; By encapsulating business logic into services, you create reusable components that can scale as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Helper: Versatile Utilities for Generic Functionality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While services are application-specific, helpers are like Swiss army knives that offer generic and utility functionalities. Let's explore why helpers are crucial in code organization:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generic Functionality:&lt;/strong&gt; Helpers contain functions not directly tied to business logic but essential for common tasks. This includes string manipulation, date formatting, and generic validations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reuse Across Different Contexts:&lt;/strong&gt; Since helpers are independent of business logic, their functions can be reused in various parts of the code. This promotes consistency and reduces code duplication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simplified Maintenance:&lt;/strong&gt; Isolating utility functionalities in helpers makes maintenance easier. If a generic function needs an update, you can do so in a single location.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structuring Your Folders: Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;/src/services:&lt;/strong&gt; Store your services in this folder, organized by entities or specific functionalities. For example, userService.js or orderService.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;/src/helpers:&lt;/strong&gt; Keep your helpers here, grouping them based on functionalities. Examples include stringHelper.js or dateHelper.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion: Deciding When to Use Services or Helpers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When building a backend architecture, the key is to strike a balance between services and helpers. Use services for application-specific business logic and helpers for generic and utility functionalities. This approach not only keeps your code organized but also facilitates maintenance and the sustainable growth of your project. Choose wisely and build a solid, scalable backend.&lt;/p&gt;

&lt;p&gt;PS. Although I'm explaining the difference between service and helper, mainly in the MVC pattern. I advocate using &lt;a href="https://softwareengineering.stackexchange.com/questions/338597/folder-by-type-or-folder-by-feature#:~:text=Folder-by-feature%20is%20superior,file%20you%20are%20looking%20for"&gt;folder by feature&lt;/a&gt; instead of by type, but there is a lot of legacy codebase using by type. So this is a post to explain when to use services or helpers.&lt;/p&gt;

&lt;p&gt;Read:&lt;br&gt;
&lt;a href="https://softwareengineering.stackexchange.com/questions/338597/folder-by-type-or-folder-by-feature#:~:text=Folder-by-feature%20is%20superior,file%20you%20are%20looking%20for"&gt;folder by feature&lt;/a&gt; &lt;/p&gt;

</description>
      <category>backend</category>
      <category>api</category>
      <category>services</category>
      <category>helper</category>
    </item>
    <item>
      <title>Using for await...of to Iterate Over Synchronous and Asynchronous Arrays in JavaScript</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Mon, 31 Jul 2023 15:35:19 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/using-for-awaitof-to-iterate-over-synchronous-and-asynchronous-arrays-in-javascript-31n2</link>
      <guid>https://dev.to/tgmarinhodev/using-for-awaitof-to-iterate-over-synchronous-and-asynchronous-arrays-in-javascript-31n2</guid>
      <description>&lt;p&gt;👋🏻 Asynchronous programming is essential in JavaScript when dealing with time-consuming operations like fetching data from APIs, reading files, or handling delays. ES6 introduced Promises to handle asynchronous tasks more elegantly. &lt;/p&gt;

&lt;p&gt;Subsequently, ES2018 introduced the for await...of loop, which further simplified handling asynchronous data when working with async iterable like Promises or Generators. &lt;/p&gt;

&lt;p&gt;In this blog post, we will explore how to use for await...of to iterate over both synchronous and asynchronous arrays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Asynchronous Array&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider an example where we have an array of delays, and we want to execute asynchronous tasks for each delay in the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function delay(ms) {
  return new Promise(resolve =&amp;gt; setTimeout(resolve, ms));
}

const createDelays = [1000, 2000, 500, 3000, 5000, 10000, 100].map(ms =&amp;gt; delay(ms));

const asyncIterable = createDelays;

(async () =&amp;gt; {
  for await (const delayTime of asyncIterable) {
    console.log(`Waited for ${delayTime} milliseconds.`);
  }
  console.log("All delays processed.");
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we define the delay function that returns a Promise, simulating an asynchronous delay. We then create an asynchronous array createDelays, containing Promises that resolve after different delays. Using for await...of, we can iterate over the asyncIterable and await each Promise's resolution before moving to the next item. This ensures that each delay is processed sequentially.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Synchronous Array&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's consider an example where we have an array of delays and want to execute synchronous tasks for each delay in the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function delay(ms) {
  return new Promise(resolve =&amp;gt; setTimeout(resolve, ms));
}

async function processDelays(delays) {
  for await (const delayTime of delays) {
    await delay(delayTime);
    console.log(`Waited for ${delayTime} milliseconds.`);
  }
  console.log("All delays processed.");
}

const delaysArray = [1000, 2000, 500, 3000, 5000, 10000, 100];
processDelays(delaysArray);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we define the delay function similarly to the previous example. The function processDelays takes an array of delays and iterates over them using for await...of. Although the array is synchronous, the loop becomes asynchronous due to the await inside it. This allows us to handle each delay asynchronously, one after the other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Mixed Array with Asynchronous Operations&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fetchData(data) {
  return new Promise(resolve =&amp;gt; {
    setTimeout(() =&amp;gt; {
      resolve(`Data: ${data}`);
    }, Math.random() * 5000); // Simulate a random delay up to 5000 ms (5 seconds).
  });
}

async function processArrayWithAsyncOperations(dataArray) {
  for (const data of dataArray) {
    const result = await fetchData(data);
    console.log(result);
  }
  console.log("All operations processed.");
}

const dataArray = [1, 2, 3, 4, 5];
processArrayWithAsyncOperations(dataArray);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we define the fetchData function, which simulates fetching data asynchronously with a random delay. The function processArrayWithAsyncOperations iterates over the dataArray using for await...of. Even though the data fetching itself is asynchronous, the loop processes each item sequentially due to the await statement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We covered the usage of &lt;strong&gt;for await...of&lt;/strong&gt; to iterate over both synchronous and asynchronous arrays. This loop allows us to handle asynchronous data elegantly, ensuring sequential processing of each item. Whether you're working with pure asynchronous data, pure synchronous data, or a mix of both, for await...of provides a powerful tool for handling asynchronous tasks with ease in modern JavaScript.&lt;/p&gt;

&lt;p&gt;You can see the code in action the &lt;a href="https://replit.com/@tgmarinho/for-await-test#index.js"&gt;replit.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👨🏻‍💻 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>for</category>
      <category>async</category>
      <category>sync</category>
    </item>
    <item>
      <title>Mastering Conventional Commits: A Hands-On Guide</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Tue, 30 May 2023 01:55:33 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/mastering-conventional-commits-a-hands-on-guide-4n35</link>
      <guid>https://dev.to/tgmarinhodev/mastering-conventional-commits-a-hands-on-guide-4n35</guid>
      <description>&lt;p&gt;When you're working with a team, it's great to use meaningful messages for your commits. &lt;/p&gt;

&lt;p&gt;We have something called Conventional Commits, a guidelines for writing commit messages in software development projects. &lt;/p&gt;

&lt;p&gt;Which includes 11 words and their meanings that you can use. It helps everyone understand your changes better!&lt;/p&gt;

&lt;p&gt;Words and definition:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;feat: Signifies a new feature or enhancement added to the codebase.&lt;/li&gt;
&lt;li&gt;fix: Indicates a bug fix or resolving an issue in the code.&lt;/li&gt;
&lt;li&gt;docs: Refers to changes or additions to documentation.&lt;/li&gt;
&lt;li&gt;style: Denotes changes in code formatting, such as indentation, whitespace, etc., which do not affect the code's functionality.&lt;/li&gt;
&lt;li&gt;refactor: Represents code changes that neither fix a bug nor add a feature but improve the code's structure or readability.&lt;/li&gt;
&lt;li&gt;test: Indicates additions, modifications, or improvements to tests or testing-related code.&lt;/li&gt;
&lt;li&gt;chore: Refers to changes in build scripts, package management, or other project-related tasks.&lt;/li&gt;
&lt;li&gt;build: Denotes changes related to the build system or external dependencies.&lt;/li&gt;
&lt;li&gt;ci: Represents changes to the Continuous Integration (CI) configuration or pipeline.&lt;/li&gt;
&lt;li&gt;perf: Indicates code changes that improve performance.&lt;/li&gt;
&lt;li&gt;revert: Signifies reverting a previous commit or changeset.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An actual example of using Conventional Commits for a TODO app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;feat: Add ability to set due dates for tasks&lt;/li&gt;
&lt;li&gt;fix: Resolve the issue with task deletion not working properly&lt;/li&gt;
&lt;li&gt;docs: Update user guide with instructions on organizing tasks into categories&lt;/li&gt;
&lt;li&gt;style: Adjust font size and color for task titles&lt;/li&gt;
&lt;li&gt;refactor: Reorganize code structure for improved task filtering&lt;/li&gt;
&lt;li&gt;test: Add test cases for task prioritization functionality&lt;/li&gt;
&lt;li&gt;chore: Update dependencies for better performance&lt;/li&gt;
&lt;li&gt;build: Fix build configuration for smoother deployment&lt;/li&gt;
&lt;li&gt;ci: Integrate automated testing into the continuous integration pipeline&lt;/li&gt;
&lt;li&gt;perf: Optimize loading speed for large task lists&lt;/li&gt;
&lt;li&gt;revert: Revert the previous commit that introduced a bug in task sorting.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, you can apply these concepts in your codebase 🚀&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>team</category>
      <category>commit</category>
    </item>
    <item>
      <title>AbortController manage memory efficiently to ensure optimal performance</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Sat, 06 May 2023 22:00:10 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/abortcontroller-manage-memory-efficiently-to-ensure-optimal-performance-2j82</link>
      <guid>https://dev.to/tgmarinhodev/abortcontroller-manage-memory-efficiently-to-ensure-optimal-performance-2j82</guid>
      <description>&lt;p&gt;In modern React applications, it's essential to manage memory efficiently to ensure optimal performance. One common issue developers face is memory leaks that can occur during asynchronous fetch operations. &lt;/p&gt;

&lt;p&gt;The AbortController is a powerful utility that can help mitigate memory leaks in these scenarios.&lt;/p&gt;

&lt;p&gt;The AbortController allows developers to cancel ongoing fetch requests, which is particularly useful when dealing with components that might unmount before the fetch request has completed. By canceling fetch requests when a component is no longer needed, developers can prevent memory leaks and enhance overall application stability.&lt;/p&gt;

&lt;p&gt;Here's a simple example of how to implement the AbortController in a React project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from 'react';

const FetchDataComponent = () =&amp;gt; {
  const [data, setData] = useState(null);

  useEffect(() =&amp;gt; {
    const controller = new AbortController();
    const signal = controller.signal;

    const fetchData = async () =&amp;gt; {
      try {
        const response = await fetch('https://api.example.com/data', { signal });
        const data = await response.json();

        if (!signal.aborted) {
          setData(data);
        }
      } catch (error) {
        if (error.name !== 'AbortError') {
          console.error('Fetch error:', error);
        }
      }
    };

    fetchData();

    return () =&amp;gt; {
      controller.abort();
    };
  }, []);

  return (
    &amp;lt;div&amp;gt;
      {data ? &amp;lt;pre&amp;gt;{JSON.stringify(data, null, 2)}&amp;lt;/pre&amp;gt; : 'Loading...'}
    &amp;lt;/div&amp;gt;
  );
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we create an instance of AbortController and use its signal property to link it to the fetch request. If the component is unmounted before the fetch request is complete, the cleanup function in the useEffect hook will be invoked, aborting the ongoing request and preventing potential memory leaks.&lt;/p&gt;

&lt;p&gt;By incorporating the AbortController into your React project, you can efficiently manage asynchronous fetch operations, mitigate memory leaks, and ensure a smoother user experience.&lt;/p&gt;

&lt;p&gt;learn more: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController"&gt;https://developer.mozilla.org/en-US/docs/Web/API/AbortController&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>web</category>
      <category>javascript</category>
      <category>dom</category>
    </item>
    <item>
      <title>How to validate ship address in the USA using ReactJS</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Thu, 04 May 2023 21:13:44 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/how-to-validate-ship-address-in-the-usa-using-reactjs-2g5g</link>
      <guid>https://dev.to/tgmarinhodev/how-to-validate-ship-address-in-the-usa-using-reactjs-2g5g</guid>
      <description>&lt;p&gt;To validate a shipping address in the USA using React and the Google Maps Geocoding API, follow these steps:&lt;/p&gt;

&lt;p&gt;Sign up for a &lt;a href="https://developers.google.com/maps/gmp-get-started#create-project"&gt;Google Maps API&lt;/a&gt; key: &lt;/p&gt;

&lt;p&gt;Install the &lt;code&gt;@googlemaps/google-maps-services-js&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @googlemaps/google-maps-services-js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new React component for your address validation form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// AddressValidationForm.js
import React, { useState } from 'react';
import { Client } from '@googlemaps/google-maps-services-js';

const AddressValidationForm = () =&amp;gt; {
  const [address, setAddress] = useState('');
  const [validationMessage, setValidationMessage] = useState('');

  const validateAddress = async () =&amp;gt; {
    const client = new Client();
    try {
      const response = await client.geocode({
        params: {
          address: address,
          components: 'country:US',
          key: 'YOUR_API_KEY',
        },
      });

      if (response.data.status === 'OK') {
        const formattedAddress = response.data.results[0].formatted_address;
        setValidationMessage(`Valid address: ${formattedAddress}`);
      } else {
        setValidationMessage('Invalid address');
      }
    } catch (error) {
      console.error(error);
      setValidationMessage('Error occurred while validating the address');
    }
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input
        type="text"
        placeholder="Enter address"
        value={address}
        onChange={(e) =&amp;gt; setAddress(e.target.value)}
      /&amp;gt;
      &amp;lt;button onClick={validateAddress}&amp;gt;Validate Address&amp;lt;/button&amp;gt;
      &amp;lt;p&amp;gt;{validationMessage}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default AddressValidationForm;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace 'YOUR_API_KEY' with the API key you got from Google Cloud Platform.&lt;/p&gt;

&lt;p&gt;Import the AddressValidationForm component in your main React component and include it in your JSX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import AddressValidationForm from './AddressValidationForm';

const App = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Address Validation&amp;lt;/h1&amp;gt;
      &amp;lt;AddressValidationForm /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your React application has a simple form that validates a shipping address in the USA using the Google Maps Geocoding API.&lt;/p&gt;

&lt;p&gt;If you want to use React + React Hook Form + Zod:&lt;/p&gt;

&lt;p&gt;Install the required packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add zod react-hook-form

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new Zod schema for the address validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// validation.js
import { z } from 'zod';

const AddressValidationSchema = z.object({
  street: z.string().nonempty('Street is required'),
  city: z.string().nonempty('City is required'),
  state: z.string().nonempty('State is required'),
  zip: z
    .string()
    .nonempty('Zip code is required')
    .regex(/^\d{5}(-\d{4})?$/, 'Zip code is invalid'),
});

export default AddressValidationSchema;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new React component for your address validation form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// AddressValidationForm.js
import React from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import AddressValidationSchema from './validation';

const AddressValidationForm = () =&amp;gt; {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(AddressValidationSchema),
  });

  const onSubmit = (data) =&amp;gt; {
    // Perform address validation or submit data
    console.log(data);
  };

  return (
    &amp;lt;form onSubmit={handleSubmit(onSubmit)}&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor="street"&amp;gt;Street:&amp;lt;/label&amp;gt;
        &amp;lt;input id="street" type="text" {...register('street')} /&amp;gt;
        {errors.street &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{errors.street.message}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor="city"&amp;gt;City:&amp;lt;/label&amp;gt;
        &amp;lt;input id="city" type="text" {...register('city')} /&amp;gt;
        {errors.city &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{errors.city.message}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor="state"&amp;gt;State:&amp;lt;/label&amp;gt;
        &amp;lt;input id="state" type="text" {...register('state')} /&amp;gt;
        {errors.state &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{errors.state.message}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label htmlFor="zip"&amp;gt;Zip:&amp;lt;/label&amp;gt;
        &amp;lt;input id="zip" type="text" {...register('zip')} /&amp;gt;
        {errors.zip &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{errors.zip.message}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;button type="submit"&amp;gt;Validate Address&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

export default AddressValidationForm;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the AddressValidationForm component in your main React component and include it in your JSX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import AddressValidationForm from './AddressValidationForm';

const App = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Address Validation&amp;lt;/h1&amp;gt;
      &amp;lt;AddressValidationForm /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your React application has a form that validates the user's input for the shipping address using Zod schema and react-hook-form.&lt;/p&gt;

&lt;p&gt;Keep in mind that using the Google Maps API might incur costs depending on your usage. There are also other APIs available that you can use to validate shipping addresses, such as the USPS Web Tools API, SmartyStreets, or EasyPost. Make sure to review their respective documentation and pricing to find the best fit for your needs. &lt;/p&gt;

&lt;p&gt;Think about GDPL too ;)&lt;/p&gt;

&lt;p&gt;Article generated by ChatGPT(OpenAI) reviewed by me ;)&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>react</category>
      <category>reacthookform</category>
      <category>zod</category>
    </item>
    <item>
      <title>how to validate ship address in the USA using JavaScript</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Thu, 04 May 2023 21:05:14 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/how-to-validate-ship-address-in-the-usa-using-javascript-4k5e</link>
      <guid>https://dev.to/tgmarinhodev/how-to-validate-ship-address-in-the-usa-using-javascript-4k5e</guid>
      <description>&lt;p&gt;To validate a shipping address in the USA using JavaScript, you can use the Google Maps Geocoding API or other similar APIs. Here's an example using the Google Maps Geocoding API:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First, you'll need to sign up for a Google Maps API key: &lt;a href="https://developers.google.com/maps/gmp-get-started#create-project"&gt;https://developers.google.com/maps/gmp-get-started#create-project&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include the Google Maps API script in your HTML file:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&amp;amp;callback=initMap"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- Add your HTML content here --&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace YOUR_API_KEY with the key you got from Google Cloud Platform.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a function to validate the shipping address:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function validateShippingAddress(address, callback) {
  const geocoder = new google.maps.Geocoder();

  geocoder.geocode({ address: address, componentRestrictions: { country: 'US' } }, function (results, status) {
    if (status === google.maps.GeocoderStatus.OK) {
      const formattedAddress = results[0].formatted_address;
      const location = results[0].geometry.location;
      callback(true, formattedAddress, location);
    } else {
      callback(false);
    }
  });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Use the validateShippingAddress function to validate user input:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userAddress = '1600 Amphitheatre Parkway, Mountain View, CA';

validateShippingAddress(userAddress, function (isValid, formattedAddress, location) {
  if (isValid) {
    console.log('Valid address:', formattedAddress);
    console.log('Latitude:', location.lat());
    console.log('Longitude:', location.lng());
  } else {
    console.log('Invalid address');
  }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that using the Google Maps API might incur costs depending on your usage. There are also other APIs available that you can use to validate shipping addresses, such as the USPS Web Tools API, SmartyStreets, or EasyPost. Make sure to review their respective documentation and pricing to find the best fit for your needs.&lt;/p&gt;

&lt;p&gt;Article created by ChatGPT4 (OpenAI).&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>javascript</category>
      <category>validation</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to share envs in a monorepo with vite and nextjs apps</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Thu, 04 May 2023 19:11:09 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/how-to-share-envs-in-a-monorepo-with-vite-and-nextjs-apps-9f</link>
      <guid>https://dev.to/tgmarinhodev/how-to-share-envs-in-a-monorepo-with-vite-and-nextjs-apps-9f</guid>
      <description>&lt;p&gt;To share environment variables between two projects in a monorepo, with specific prefixes for each project, you can create a &lt;code&gt;.env.shared&lt;/code&gt; file with common environment variables and then use scripts to create specific .env files for each project. Here's how to do that:&lt;/p&gt;

&lt;p&gt;Create a .env.shared file at the root of the monorepo with the common environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SECRET_KEY=your_secret_key
API_URL=your_api_url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a script to generate specific .env files for each project. In the example below, we will create a generate-env.js file at the root of the monorepo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// generate-env.js
const fs = require('fs');
const path = require('path');

const envShared = path.join(__dirname, '.env.shared');
const envVite = path.join(__dirname, 'vite-project', '.env');
const envNext = path.join(__dirname, 'next-project', '.env');

const sharedVars = fs.readFileSync(envShared, 'utf-8').split('\n');

const viteVars = sharedVars.map((line) =&amp;gt; {
  if (line.startsWith('SECRET_KEY') || line.startsWith('API_URL')) {
    return `VITE_PUBLIC_${line}`;
  }
  return line;
});

const nextVars = sharedVars.map((line) =&amp;gt; {
  if (line.startsWith('SECRET_KEY') || line.startsWith('API_URL')) {
    return `NEXT_PUBLIC_${line}`;
  }
  return line;
});

fs.writeFileSync(envVite, viteVars.join('\n'), 'utf-8');
fs.writeFileSync(envNext, nextVars.join('\n'), 'utf-8');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the generate-env.js script to generate the specific .env files for each project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node generate-env.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create an .env file in the vite-project folder with environment variables prefixed with &lt;code&gt;VITE_PUBLIC_&lt;/code&gt; and an .env file in the next-project folder with environment variables prefixed with &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, each project will have its own .env file with the correctly prefixed environment variables. Be sure to add the generated .env files to your .gitignore rules to prevent committing sensitive information to the repository.&lt;/p&gt;

&lt;p&gt;Remember to run the &lt;code&gt;generate-env.js&lt;/code&gt; script whenever you make changes to the .env.shared file to update the specific project .env files. You can also add this script as a step in your build or deployment process.&lt;/p&gt;

</description>
      <category>monorepo</category>
      <category>shared</category>
      <category>envs</category>
    </item>
    <item>
      <title>How to learn quick</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Sat, 18 Mar 2023 12:30:00 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/how-to-learn-quick-g4o</link>
      <guid>https://dev.to/tgmarinhodev/how-to-learn-quick-g4o</guid>
      <description>&lt;p&gt;Learning quickly requires effective use of time and efficient study techniques. Here are some tips that can help you learn quickly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Set clear goals: Before starting to learn something, define specific and achievable goals that can be measured and monitored.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn actively: Instead of simply reading and highlighting, actively engage with the material by taking notes, summarizing, and teaching the concepts to others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Focus on what's important: Identify the most important information to learn and focus your time and energy on that. Avoid getting distracted by irrelevant details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use visual aids: Use diagrams, mind maps, and other visual aids to help you remember information better. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take breaks: Taking short breaks can help you recharge and maintain your focus during your learning sessions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get enough sleep: Lack of sleep can affect your ability to learn and retain information, so make sure you get enough rest to improve your learning capacity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Practice regularly: Regular practice is essential to consolidate information and develop skills. Dedicate time every day to practice what you're learning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exercise regularly: Regular exercise can improve your cognitive function and help you learn faster and better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get enough sleep: Lack of sleep can affect your ability to learn and retain information, so make sure you get enough rest to improve your learning capacity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eliminate distractions: Turn off notifications on your phone and avoid multitasking to avoid distractions that can slow down your learning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extra: Use the Chat GPT-3/4 🤫&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep in mind, learning quickly doesn't mean you will learn everything in a short period of time. It's important to use effective techniques and set realistic goals to optimize your learning process.&lt;/p&gt;

&lt;p&gt;Never stop learning 🚀&lt;/p&gt;

</description>
      <category>learn</category>
      <category>quick</category>
      <category>study</category>
      <category>techniques</category>
    </item>
    <item>
      <title>How to publish React App (CRA) on Github Pages using Github Actions with Turborepo</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Thu, 16 Mar 2023 13:37:00 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/how-to-publish-react-app-cra-on-github-pages-using-github-actions-with-turborepo-1j94</link>
      <guid>https://dev.to/tgmarinhodev/how-to-publish-react-app-cra-on-github-pages-using-github-actions-with-turborepo-1j94</guid>
      <description>&lt;p&gt;Create a &lt;code&gt;.yml&lt;/code&gt; file inside of the &lt;code&gt;.github/workflows/&lt;/code&gt;&lt;br&gt;
give any semantic name, like &lt;code&gt;publish-app.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to GitHub Pages&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check out code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pnpm/action-setup@v2.0.1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;6.32.2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js environment&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;pnpm'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pnpm install&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pnpm build&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JamesIves/github-pages-deploy-action@4.1.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gh-pages&lt;/span&gt;
          &lt;span class="na"&gt;folder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/web/build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Steps: &lt;/p&gt;

&lt;p&gt;Every &lt;code&gt;push&lt;/code&gt; on branch &lt;code&gt;main&lt;/code&gt;, will run the job on ubuntu virtual machine, install the pnpm as node package manager, and setup the node.js with the version 16.&lt;/p&gt;

&lt;p&gt;Then will install the dependencies of the project, do the build.&lt;/p&gt;

&lt;p&gt;Finally, will do the deploy on github pages using the scripts from &lt;a href="https://github.com/JamesIves/github-pages-deploy-action" rel="noopener noreferrer"&gt;JamesIves/github-pages-deploy-action&lt;/a&gt;, and create a branch &lt;code&gt;gh-pages&lt;/code&gt; with the code from &lt;code&gt;apps/web/build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, you need to go to the GitHub repository settings page:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://github.com/&amp;lt;username|org&amp;gt;/&amp;lt;repository&amp;gt;/settings/pages&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And do this settings: &lt;/p&gt;

&lt;p&gt;Source: Deploy from a branch&lt;br&gt;
Branch: gh-pages&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fykys3neu9ea0e9llw44s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fykys3neu9ea0e9llw44s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done, your site is live at &lt;code&gt;https://username|org.github.io/your-repository&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🚀&lt;/p&gt;

</description>
      <category>react</category>
      <category>turborepo</category>
      <category>github</category>
      <category>actions</category>
    </item>
    <item>
      <title>What is Technical debt</title>
      <dc:creator>Thiago Marinho</dc:creator>
      <pubDate>Thu, 09 Mar 2023 14:47:00 +0000</pubDate>
      <link>https://dev.to/tgmarinhodev/what-is-technical-debt-2d3h</link>
      <guid>https://dev.to/tgmarinhodev/what-is-technical-debt-2d3h</guid>
      <description>&lt;p&gt;Technical debt is a term used in the software industry to describe the long-term cost of making decisions that speed up software delivery in the short term, but may lead to technical problems in the future. Technical debt refers to the need to do additional work in the future to correct problems that are created by taking shortcuts or not following good engineering practices.&lt;/p&gt;

&lt;p&gt;For example, there may be a tight deadline to deliver a new feature in software and to meet the deadline, the development team may decide not to invest in extensive testing or refactoring the code to make it more readable and maintainable. While this may allow the team to deliver the new feature on time, it may also create technical problems and make the software more difficult to maintain and evolve in the future, increasing the technical burden.&lt;/p&gt;

&lt;p&gt;Technical debit is not something inherently bad, as it can be a conscious and justified decision in some cases. However, it is important that development teams are aware of the costs and risks involved in taking shortcuts and ensure that technical debt is managed to minimize its long-term impact.&lt;/p&gt;

</description>
      <category>dev</category>
      <category>technical</category>
      <category>software</category>
      <category>engineering</category>
    </item>
  </channel>
</rss>
