<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alish Giri</title>
    <description>The latest articles on Forem by Alish Giri (@wootcot).</description>
    <link>https://forem.com/wootcot</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%2F1562696%2Fb22da089-00e2-49c2-b76c-0994e702a2f4.png</url>
      <title>Forem: Alish Giri</title>
      <link>https://forem.com/wootcot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wootcot"/>
    <language>en</language>
    <item>
      <title>A better architecture</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Tue, 05 May 2026 18:15:00 +0000</pubDate>
      <link>https://forem.com/wootcot/a-better-architecture-cno</link>
      <guid>https://forem.com/wootcot/a-better-architecture-cno</guid>
      <description>&lt;p&gt;If you have not understood by now then let me remind you the time you or your team went down through all those codes you wrote few months or years ago and now you have to do that all over again.&lt;/p&gt;

&lt;p&gt;This is a very common pattern with established systems. Improvement work is either done or skipped due to higher risk rate. And only selected portion of the work is pushed forward.&lt;/p&gt;

&lt;p&gt;This is a where most systems go down the rabbit hole!&lt;/p&gt;

&lt;p&gt;Every client I have worked with in the past wants to get things done fast. And until it's too late they will keep pushing. Technology changes fast so keeping up with it is the only way to progress otherwise we already know how fast things deprecate. And messy code cannot be upgraded without adding more messy code 🤮. This is what happened to a client of mine from Norway.&lt;/p&gt;

&lt;p&gt;The only solution to this I have come up with is "A better architecture". If the foundation is strong then only few changes are required to make the upgrade. I do this in practice all the time and have been successful at doing this because of my constant need for improvement.&lt;/p&gt;

&lt;p&gt;In two of my past projects I rewrote the entire code because I found something better 😅. Most will call me stupid and they will not be wrong. But the backbone on which I do these changes is rigorous integration testing. I write tests and this becomes my single source of truth for the quality I expect from my code. But now that I have all these experiences, even the major upgrade requires minor tweaks surprisingly due to better architectural understanding.&lt;/p&gt;

&lt;p&gt;However, the most important factor we want from the code is higher flexibility. Because things will change. And we want to keep all of our hair intact.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>discuss</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Who cares about speed?</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Mon, 04 May 2026 18:15:00 +0000</pubDate>
      <link>https://forem.com/wootcot/who-cares-about-speed-1pl1</link>
      <guid>https://forem.com/wootcot/who-cares-about-speed-1pl1</guid>
      <description>&lt;p&gt;After 8 years of software engineering, the one thing I am good at is something that nobody really cares about. This reality has hit me hard many times. Who cares about performance if it costs you slightly more investment. Who cares about architecture if it costs you more. Who cares about 0.35 second of improvement or even 2 seconds of faster load time for that matter.&lt;/p&gt;

&lt;p&gt;This was a very strange reality I came across when I began the journey of building products few years back. If you don't find a way to exchange value within few weeks then you really need to start restructuring your path. People in business they are looking for ways to reduce cost and improve their time management. Noting else matters.&lt;/p&gt;

&lt;p&gt;The speed and performance is added benefit that is invisible to the users. Slow  load times is only a problem when they are fully invested in the system but before getting to a point where your app/system becomes a thing the speed and performance are irrelevant.&lt;/p&gt;

&lt;p&gt;However, if the same product is already out there and have proven its worth in the market then now you can present your version of the system specifically focusing on the performance and speed. Because now you are solving problem in the industry that is not just app specific, it is performance and speed specific.&lt;/p&gt;

&lt;p&gt;Why did I bring this up? You wonder.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google wasn't the first search engine; it was just faster and more relevant.&lt;/li&gt;
&lt;li&gt;Slack wasn't the first chat app; it was just more integrated and performant.&lt;/li&gt;
&lt;li&gt;Stripe wasn't the first payment gateway; it was just the first one that didn't make developers want to quit their jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nobody cares until the performance and speed becomes a visible problem and that will only happen when the product has already been proven in the market.&lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>performance</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>One Intelligent Platform</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Mon, 04 May 2026 13:30:21 +0000</pubDate>
      <link>https://forem.com/wootcot/one-intelligent-platform-2ppa</link>
      <guid>https://forem.com/wootcot/one-intelligent-platform-2ppa</guid>
      <description>&lt;p&gt;Every big organisation in some way utilizes technology but end up with a mess anyway. The solution they choose mostly just covers few problems with multiple systems and leaves out the rest in the hands of their team members. Now the team members are responsible for utilising the system to make the operation smooth.&lt;/p&gt;

&lt;p&gt;But is your operation smooth right now?&lt;/p&gt;

&lt;p&gt;That's the thing with systems. They are complex! The learning curve, the transition cost and the repetitive work is most of the time avoided and the long term pain is accepted because this is how traditionally we were working right?!&lt;/p&gt;

&lt;p&gt;Soon this will evolve. The AI integration is making software intelligent. Not just static code and systems where human interaction was mandatory. The AI will independently work as an employee and will be able to manage your operation effectively.&lt;/p&gt;

&lt;p&gt;I manage an AI employee (the early version one) and working on improving it. It's a lot of work and the learning curve is steep but no mountain is big if you are willing to take the first step and look at the subsequent next.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Two tutorials to master Riverpod!</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Fri, 03 Oct 2025 08:51:28 +0000</pubDate>
      <link>https://forem.com/wootcot/two-videos-to-master-riverpod-55pp</link>
      <guid>https://forem.com/wootcot/two-videos-to-master-riverpod-55pp</guid>
      <description>&lt;p&gt;These two YouTube tutorials are all you need to learn how to use Riverpod in Flutter.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.youtube.com/watch?v=fU15nxFKInA&amp;amp;list=PLJDAe6L3tk1up4gebuvNn3xxW8u5kmpoV&amp;amp;index=1&amp;amp;pp=gAQBiAQB" rel="noopener noreferrer"&gt;Part 2&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.youtube.com/watch?v=gbHj1EkpuIQ&amp;amp;list=PLJDAe6L3tk1up4gebuvNn3xxW8u5kmpoV&amp;amp;index=3&amp;amp;pp=gAQBiAQB0gcJCfsJAYcqIYzv" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt;
&lt;/h2&gt;

</description>
      <category>flutter</category>
      <category>riverpod</category>
    </item>
    <item>
      <title>Flutter + AI: Build an AI Trainer App (2025 Tutorial)</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Sun, 01 Jun 2025 04:58:22 +0000</pubDate>
      <link>https://forem.com/wootcot/flutter-ai-build-an-ai-trainer-app-2025-tutorial-1ffg</link>
      <guid>https://forem.com/wootcot/flutter-ai-build-an-ai-trainer-app-2025-tutorial-1ffg</guid>
      <description>&lt;p&gt;Do you want to build your own personal trainer using the power of AI?? Then rest assure I have got you covered!!! 💪🏻&lt;/p&gt;

&lt;p&gt;Drop and give me 5 before you start!!! 😄&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/smjWX2swwv8"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>ai</category>
    </item>
    <item>
      <title>Flutter High Level Simplified Architecture with Riverpod</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Sat, 24 May 2025 02:52:28 +0000</pubDate>
      <link>https://forem.com/wootcot/flutter-high-level-simplified-architecture-with-riverpod-4g74</link>
      <guid>https://forem.com/wootcot/flutter-high-level-simplified-architecture-with-riverpod-4g74</guid>
      <description>&lt;p&gt;If you have always wanted to switch to Riverpod, then I have got you covered.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gbHj1EkpuIQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I was using Provider for state management for a very long time in Flutter and honestly I was not happy with it. The setup always gave me a nightmare especially if I wanted to have multiple provider's state in a single screen. Furthermore, utilizing one provider in multiple places also required some additional setup that was getting quite annoying.&lt;/p&gt;

&lt;p&gt;Despite these issues, I never dared to use Riverpod in production code. I attempted to understand it a few times and was surprised to find out how complex it felt at first. It was not until very recently and after several months of trials and errors that I finally cracked the code and wanted to share this setup with you guys.&lt;/p&gt;

&lt;p&gt;I have also attached the entire demo project on the video description so that you can save it for later on. I did not add the link here because watching at least first three chapters is crucial to understanding how Riverpod works.&lt;/p&gt;

&lt;p&gt;I hope it helps!&lt;/p&gt;

</description>
      <category>flutter</category>
    </item>
    <item>
      <title>No one talks about GraphQL anymore!</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Sun, 06 Apr 2025 12:59:04 +0000</pubDate>
      <link>https://forem.com/wootcot/no-one-talks-about-graphql-anymore-2bbp</link>
      <guid>https://forem.com/wootcot/no-one-talks-about-graphql-anymore-2bbp</guid>
      <description>&lt;p&gt;Let me jump right in, the perfect analogy for describing GraphQL is equivalent to what Typescript is to Javascript. In the REST API, payload and end-points are not typed whereas in GraphQL request and response are pre-determined using specified types and we all know the benefits of having typed languages. This is the core principle of GraphQL with other added benefits.&lt;/p&gt;

&lt;p&gt;So why is no one talking about GraphQL anymore?&lt;/p&gt;

&lt;p&gt;As you can see in the Postman report below, since the release of GraphQL in 2015 the popularity has just grown significantly. And every developer currently has interacted with GraphQL in one way or another. Due to this, almost all of the experienced developers nowadays find GraphQL as part of their career making it no longer a HOT topic of discussion.&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%2F4qa9u7vop01amu1x5eps.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%2F4qa9u7vop01amu1x5eps.png" alt="Postman report on API archetecture" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, like the way Typescript has become a mandatory thing for most Javascript projects. It is sensible to claim that having typed request/response API is going to be a permanent thing in the future.&lt;/p&gt;

&lt;p&gt;Now the question is, will GraphQL be the leader in this space or a new technology will emerge, with much simpler implementation than GraphQL?&lt;/p&gt;

&lt;p&gt;Learn more about GraphQL in this post -&amp;gt; &lt;a href="https://dev.to/wootcot/why-would-you-choose-graphql-over-rest-api-2bl8"&gt;Why choose GraphQL over REST API?&lt;/a&gt;&lt;/p&gt;

</description>
      <category>graphql</category>
    </item>
    <item>
      <title>One script, one window, multiple attached commands</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Sat, 29 Mar 2025 08:40:08 +0000</pubDate>
      <link>https://forem.com/wootcot/one-script-one-window-multiple-attached-commands-3321</link>
      <guid>https://forem.com/wootcot/one-script-one-window-multiple-attached-commands-3321</guid>
      <description>&lt;p&gt;Every time I started working on a project I had open up two to three different Terminal windows to start development work 🙄.&lt;/p&gt;

&lt;p&gt;One to start the Docker, other to start the server and finally one more to run the frontend. And viewing logs on all these terminal one after the other was also getting annoying so I did some research and found something incredible 🚀.&lt;/p&gt;

&lt;p&gt;You can create one script and chain different commands using &lt;code&gt;&amp;amp;&lt;/code&gt; to run multiple attached sessions as shown below.&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="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;scripts:&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"run:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker-compose up &amp;amp; (cd path/to/server &amp;amp;&amp;amp; ./run/server) &amp;amp; yarn start"&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="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;The benefits of using this is just out of this world. You will be using one terminal window to view logs from multiple different projects.&lt;/p&gt;

&lt;p&gt;And to kill the previous processes in the chain use the following syntax. &lt;code&gt;Ctrl + C&lt;/code&gt; will only close the later one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="c"&gt;# To list all the running processes. Explore how the name works.&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep&lt;/span&gt; &amp;lt;app_name&amp;gt;

pkill &amp;lt;app_name&amp;gt; &lt;span class="c"&gt;# For MacOS &amp;amp; Linux&lt;/span&gt;

taskkill &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-im&lt;/span&gt; mac-server &lt;span class="c"&gt;# For Windows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>react</category>
      <category>reactnative</category>
      <category>node</category>
    </item>
    <item>
      <title>Flutter Integration Test: Model Driven Architecture</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Mon, 24 Feb 2025 07:47:36 +0000</pubDate>
      <link>https://forem.com/wootcot/model-driven-flutter-integration-test-masterclass-3p3k</link>
      <guid>https://forem.com/wootcot/model-driven-flutter-integration-test-masterclass-3p3k</guid>
      <description>&lt;h3&gt;
  
  
  tl;dr
&lt;/h3&gt;

&lt;p&gt;Please scroll to the last paragraph to get the link to the free video guides to start writing integration test for your Flutter project.&lt;/p&gt;

&lt;p&gt;You know how sometimes we end up making changes to our code, and those changes affect parts of the project we didn’t even think about? Well, I’ve been there too. It happened to me when I launched my first commercial app in 2021.&lt;/p&gt;

&lt;p&gt;Features change all the time, and it’s tough to make sure everything works after major or minor code changes. And even with unit and widget tests, they weren’t enough to help. It was getting really frustrating to keep the project and the tests in sync. There were just too many changes during development.&lt;/p&gt;

&lt;p&gt;Despite all that trouble, I didn’t have the confidence that the app would work like it was supposed to. But then, after three years of experimenting and learning about the testing ecosystem, I came up with a solution: &lt;strong&gt;Model Driven Integration Test&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s not just about writing the tests; it’s about structuring them in a way that’s scalable and maintainable. And that’s given me a lot of confidence. I can make changes to the Flutter and backend projects without worrying about breaking anything. This testing style has been a lifesaver.&lt;/p&gt;

&lt;p&gt;Sometimes, the tests would fail, and they would point out exactly where a feature was failing after making the changes. That was really helpful.&lt;/p&gt;

&lt;p&gt;Isn’t that what we’re trying to achieve when we write tests? With every new release, we should have the confidence that 99% of the time, our code will work. And if a bug does appear, I just extend the tests to cover that issue, and now it’s even more stable than before.&lt;/p&gt;

&lt;p&gt;I haven’t found any other way to make sure that every new release won’t be a pain. And I’d love to share this with you.&lt;/p&gt;

&lt;p&gt;The first few free videos will give you everything you need to know to write integration test for your project and if you want to learn the Model Driven Architecture then you can choose to enroll in the course.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/model-driven-flutter-integration-test-masterclass/?referralCode=BA04B8954550605C68F2" rel="noopener noreferrer"&gt;Checkout the course here!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>testing</category>
    </item>
    <item>
      <title>You don't have to memorize get config commands!</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Tue, 28 Jan 2025 10:38:02 +0000</pubDate>
      <link>https://forem.com/wootcot/you-dont-have-to-memorize-get-config-commands-3jk9</link>
      <guid>https://forem.com/wootcot/you-dont-have-to-memorize-get-config-commands-3jk9</guid>
      <description>&lt;p&gt;If you modify git configuration more that an average developer then the simplest way to edit git configuration is by opening up the file and modifying the contents directly.&lt;/p&gt;

&lt;p&gt;This is super useful if you have two different GitHub accounts, one personal and the other for work. Where you have to update the config file to adjust the signing key, adding suffix to the origin url, along with other informations. This approach mentioned here can save you valuable time if you have a habit like mine to forget the git commands frequently 😄.&lt;/p&gt;

&lt;p&gt;You can use the following command to locate your global git config file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--list&lt;/span&gt; &lt;span class="nt"&gt;--show-origin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, most of the time we want primary account to be the global config and for secondary account we want to have a project based configuration file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For your current project &lt;code&gt;.git/config&lt;/code&gt; is where the config file is stored and this file is a copy of global git config file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, use one of the following command to open up a file and then modify the contents directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .git/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano .git/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;open .git/config &lt;span class="nt"&gt;-a&lt;/span&gt; &amp;lt;your_IDE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you do not have to memorize all sorts of git commands.&lt;/p&gt;

&lt;p&gt;SAMPLE CONFIG FILE&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;core&lt;/span&gt;]
    &lt;span class="n"&gt;repositoryformatversion&lt;/span&gt; = &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;filemode&lt;/span&gt; = &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;bare&lt;/span&gt; = &lt;span class="n"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;logallrefupdates&lt;/span&gt; = &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;ignorecase&lt;/span&gt; = &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;precomposeunicode&lt;/span&gt; = &lt;span class="n"&gt;true&lt;/span&gt;
[&lt;span class="n"&gt;remote&lt;/span&gt; &lt;span class="s2"&gt;"origin"&lt;/span&gt;]
    &lt;span class="n"&gt;url&lt;/span&gt; = &amp;lt;&lt;span class="n"&gt;your_origin&lt;/span&gt;&amp;gt;
    &lt;span class="n"&gt;fetch&lt;/span&gt; = +&lt;span class="n"&gt;refs&lt;/span&gt;/&lt;span class="n"&gt;heads&lt;/span&gt;/*:&lt;span class="n"&gt;refs&lt;/span&gt;/&lt;span class="n"&gt;remotes&lt;/span&gt;/&lt;span class="n"&gt;origin&lt;/span&gt;/*
[&lt;span class="n"&gt;user&lt;/span&gt;]
    &lt;span class="n"&gt;name&lt;/span&gt; = &amp;lt;&lt;span class="n"&gt;username&lt;/span&gt;&amp;gt;
    &lt;span class="n"&gt;email&lt;/span&gt; = &amp;lt;&lt;span class="n"&gt;your_email&lt;/span&gt;&amp;gt;
    &lt;span class="n"&gt;signingkey&lt;/span&gt; = &lt;span class="n"&gt;XXXXXXXXXXXXXXXX&lt;/span&gt;
[&lt;span class="n"&gt;commit&lt;/span&gt;]
    &lt;span class="n"&gt;gpgsign&lt;/span&gt;=&lt;span class="n"&gt;true&lt;/span&gt;
[&lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="s2"&gt;"prod"&lt;/span&gt;]
    &lt;span class="n"&gt;remote&lt;/span&gt; = &lt;span class="n"&gt;origin&lt;/span&gt;
    &lt;span class="n"&gt;merge&lt;/span&gt; = &lt;span class="n"&gt;refs&lt;/span&gt;/&lt;span class="n"&gt;heads&lt;/span&gt;/&lt;span class="n"&gt;prod&lt;/span&gt;
    &lt;span class="n"&gt;vscode&lt;/span&gt;-&lt;span class="n"&gt;merge&lt;/span&gt;-&lt;span class="n"&gt;base&lt;/span&gt; = &lt;span class="n"&gt;origin&lt;/span&gt;/&lt;span class="n"&gt;prod&lt;/span&gt;
[&lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="s2"&gt;"dev"&lt;/span&gt;]
    &lt;span class="n"&gt;vscode&lt;/span&gt;-&lt;span class="n"&gt;merge&lt;/span&gt;-&lt;span class="n"&gt;base&lt;/span&gt; = &lt;span class="n"&gt;origin&lt;/span&gt;/&lt;span class="n"&gt;main&lt;/span&gt;
    &lt;span class="n"&gt;remote&lt;/span&gt; = &lt;span class="n"&gt;origin&lt;/span&gt;
    &lt;span class="n"&gt;merge&lt;/span&gt; = &lt;span class="n"&gt;refs&lt;/span&gt;/&lt;span class="n"&gt;heads&lt;/span&gt;/&lt;span class="n"&gt;dev&lt;/span&gt;
[&lt;span class="n"&gt;lfs&lt;/span&gt;]
    &lt;span class="n"&gt;repositoryformatversion&lt;/span&gt; = &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>git</category>
    </item>
    <item>
      <title>Printing HTML best technique with sample receipt.</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Fri, 10 Jan 2025 13:30:28 +0000</pubDate>
      <link>https://forem.com/wootcot/printing-html-best-technique-with-sample-receipt-lkj</link>
      <guid>https://forem.com/wootcot/printing-html-best-technique-with-sample-receipt-lkj</guid>
      <description>&lt;p&gt;I have been experementing with printing invoices using Javascript and Tailwindcss. After several trials and errors the following is the best configuration I found to get the optimal results.&lt;/p&gt;

&lt;h2&gt;
  
  
  (optional) Configure Tailwindcss
&lt;/h2&gt;

&lt;p&gt;If you are using tailwindcss to style your invoice then you can set the following configuration to access to 'print' and 'screen' prefixes that you can use to hide/show content based on your requirements.&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="cm"&gt;/** @type {import('tailwindcss').Config} */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;content&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;./src/**/*.{html,js,svelte,ts}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;screens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;print&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="na"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;screen&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="c1"&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;plugins&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;Now you can utilize this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"screen:bg-red-300 print:bg-white"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add this to your primary CSS file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* This will hide the extra header and footer contents added by the browser. */&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3in&lt;/span&gt; &lt;span class="m"&gt;0.7in&lt;/span&gt; &lt;span class="m"&gt;0.3in&lt;/span&gt; &lt;span class="m"&gt;0.7in&lt;/span&gt; &lt;span class="cp"&gt;!important&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="c"&gt;/* Change this as you like */&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#982b44&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;h2&gt;
  
  
  Always use a separate route, do not use a pop up window.
&lt;/h2&gt;

&lt;p&gt;Also, set the document title for better experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    ...
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;your-file-name&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-file-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use join('') to hide the unnecessary commas, if you are looping through the items like below.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tableRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;orders&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="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;tr class="border-b border-gray-200 break-inside-avoid break-before-auto"&amp;gt;
        &amp;lt;td class="max-w-0 py-2 pl-4 pr-3 text-sm sm:pl-0"&amp;gt;
            &amp;lt;div class="font-medium text-gray-900"&amp;gt;&amp;lt;span class="mr-4 text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&amp;lt;/span&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
        &amp;lt;/td&amp;gt;
        &amp;lt;td class="hidden px-3 py-2 text-right text-sm text-gray-500 sm:table-cell"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;weightUnit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class="hidden px-3 py-2 text-right text-sm text-gray-500 sm:table-cell"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class="py-2 pl-3 pr-4 text-right text-sm text-gray-500 sm:pr-0"&amp;gt;&amp;lt;span class="text-xs"&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;currency&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&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;and display this as,&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;tbody&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tableRows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/tbody&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sample Receipt
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;receiptGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;seller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;panNum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XXXXXXXX&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;companyLogo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// your-company-logo&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deliveryAddr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deliveryAddress&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;vat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;subTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&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;tableRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;order&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="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
            &amp;lt;tr class="border-b border-gray-200 break-inside-avoid break-before-auto"&amp;gt;
                &amp;lt;td class="max-w-0 py-2 pl-4 pr-3 text-sm sm:pl-0"&amp;gt;
                    &amp;lt;div class="font-medium text-gray-900"&amp;gt;&amp;lt;span class="mr-4 text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&amp;lt;/span&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
                &amp;lt;/td&amp;gt;
                &amp;lt;td class="hidden px-3 py-2 text-right text-sm text-gray-500 sm:table-cell"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;weightUnit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
                &amp;lt;td class="hidden px-3 py-2 text-right text-sm text-gray-500 sm:table-cell"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
                &amp;lt;td class="py-2 pl-3 pr-4 text-right text-sm text-gray-500 sm:pr-0"&amp;gt;&amp;lt;span class="text-xs"&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;currency&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&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="s2"&gt;`
        &amp;lt;div class="mx-auto my-6 max-w-max rounded bg-white p-6 shadow-sm text-black"&amp;gt;
            &amp;lt;div class="grid grid-cols-2 items-center"&amp;gt;
                &amp;lt;div&amp;gt;
                &amp;lt;img width="100" height="100" alt="company-logo" src="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;companyLogo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div class="text-right"&amp;gt;
                &amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
                &amp;lt;p class="text-sm text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
                &amp;lt;p class="mt-1 text-sm text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
                &amp;lt;p class="mt-1 text-sm text-gray-500"&amp;gt;VAT: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;panNum&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;!-- Client info --&amp;gt;
            &amp;lt;div class="mt-8 grid grid-cols-2 items-center"&amp;gt;
                &amp;lt;div&amp;gt;
                &amp;lt;p class="font-bold text-gray-800"&amp;gt;Bill to :&amp;lt;/p&amp;gt;
                &amp;lt;p class="text-gray-500"&amp;gt;
                    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deliveryAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addressLine1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
                    &amp;lt;br /&amp;gt;
                    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deliveryAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&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;deliveryAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&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;deliveryAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postcode&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;deliveryAddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
                &amp;lt;/p&amp;gt;
                &amp;lt;p class="text-gray-500"&amp;gt;info@email.com&amp;lt;/p&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div class="text-right"&amp;gt;
                &amp;lt;p class=""&amp;gt;
                    Invoice number:
                    &amp;lt;span class="text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;displayInvoiceNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orderNumber&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;
                &amp;lt;/p&amp;gt;
                &amp;lt;p class="text-sm"&amp;gt;
                    Invoice Date: &amp;lt;span class="text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectIdToDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;
                    &amp;lt;br /&amp;gt;
                    Due Date: &amp;lt;span class="text-gray-500"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectIdToDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;
                &amp;lt;/p&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;!-- Invoice Items --&amp;gt;
            &amp;lt;div class="-mx-4 mt-8 flow-root sm:mx-0"&amp;gt;
                &amp;lt;table class="min-w-full break-inside-auto"&amp;gt;
                    &amp;lt;colgroup class="break-inside-auto"&amp;gt;
                        &amp;lt;col class="w-full sm:w-1/2" /&amp;gt;
                        &amp;lt;col class="sm:w-auto" /&amp;gt;
                        &amp;lt;col class="sm:w-auto" /&amp;gt;
                        &amp;lt;col class="sm:w-1/5" /&amp;gt;
                    &amp;lt;/colgroup&amp;gt;
                    &amp;lt;thead class="border-b border-gray-300 text-gray-900 table-header-group"&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0"&amp;gt;Items&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="col" class="hidden px-3 py-3.5 text-right text-sm font-semibold text-gray-900 sm:table-cell"&amp;gt;Quantity&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="col" class="hidden px-3 py-3.5 text-right text-sm font-semibold text-gray-900 sm:table-cell"&amp;gt;Price&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="col" class="py-3.5 pl-3 pr-4 text-right text-sm font-semibold text-gray-900 sm:pr-0"&amp;gt;Amount&amp;lt;/th&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    &amp;lt;/thead&amp;gt;
                    &amp;lt;tbody&amp;gt;
                        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tableRows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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="s2"&gt;
                    &amp;lt;/tbody&amp;gt;
                &amp;lt;/table&amp;gt;
                &amp;lt;table class="min-w-full"&amp;gt;
                    &amp;lt;colgroup&amp;gt;
                        &amp;lt;col class="w-full sm:w-1/2" /&amp;gt;
                        &amp;lt;col class="sm:w-auto" /&amp;gt;
                        &amp;lt;col class="sm:w-auto" /&amp;gt;
                        &amp;lt;col class="sm:w-1/5" /&amp;gt;
                    &amp;lt;/colgroup&amp;gt;
                    &amp;lt;thead&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;th scope="row" colspan="3" class="hidden pl-4 pr-3 pt-6 text-right text-sm font-normal text-gray-500 sm:table-cell sm:pl-0"&amp;gt;Subtotal&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="row" class="pl-6 pr-3 pt-2 text-left text-sm font-normal text-gray-500 sm:hidden"&amp;gt;Subtotal&amp;lt;/th&amp;gt;
                            &amp;lt;td class="pl-3 pr-6 pt-2 text-right text-sm text-gray-500 sm:pr-0"&amp;gt;&amp;lt;span class="text-xs"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subTotal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;th scope="row" colspan="3" class="hidden pl-4 pr-3 pt-2 text-right text-sm font-normal text-gray-500 sm:table-cell sm:pl-0"&amp;gt;Tax&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="row" class="pl-6 pr-3 pt-2 text-left text-sm font-normal text-gray-500 sm:hidden"&amp;gt;Tax&amp;lt;/th&amp;gt;
                            &amp;lt;td class="pl-3 pr-6 pt-2 text-right text-sm text-gray-500 sm:pr-0"&amp;gt;&amp;lt;span class="text-xs"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subTotal&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;vat&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;th scope="row" colspan="3" class="hidden pl-4 pr-3 pt-2 text-right text-sm font-normal text-gray-500 sm:table-cell sm:pl-0"&amp;gt;Discount&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="row" class="pl-6 pr-3 pt-2 text-left text-sm font-normal text-gray-500 sm:hidden"&amp;gt;Discount&amp;lt;/th&amp;gt;
                            &amp;lt;td class="pl-3 pr-6 pt-2 text-right text-sm text-gray-500 sm:pr-0"&amp;gt;-&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;th scope="row" colspan="3" class="hidden pl-4 pr-3 pt-2 text-right text-sm font-semibold text-gray-900 sm:table-cell sm:pl-0"&amp;gt;Total&amp;lt;/th&amp;gt;
                            &amp;lt;th scope="row" class="pl-6 pr-3 pt-2 text-left text-sm font-semibold text-gray-900 sm:hidden"&amp;gt;Total&amp;lt;/th&amp;gt;
                            &amp;lt;td class="pl-3  pt-2 text-right text-sm font-semibold text-gray-900 sm:pr-0"&amp;gt;&amp;lt;span class="text-xs"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;subTotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;subTotal&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;vat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    &amp;lt;/thead&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;!--  Footer  --&amp;gt;
            &amp;lt;div class="mt-16 border-t-2 pt-4 text-center text-xs text-gray-500"&amp;gt;Please pay the invoice before the due date. You can pay the invoice by logging in to your account from our client portal.&amp;lt;/div&amp;gt;
        &amp;lt;/div&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;Hope this helps! Took me two days to make this perfect!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Launching my first game soon!</title>
      <dc:creator>Alish Giri</dc:creator>
      <pubDate>Thu, 21 Nov 2024 10:10:26 +0000</pubDate>
      <link>https://forem.com/wootcot/launching-my-first-game-soon-4149</link>
      <guid>https://forem.com/wootcot/launching-my-first-game-soon-4149</guid>
      <description>&lt;p&gt;After 7 years of software development I have decided to build my first game.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>gdscript</category>
    </item>
  </channel>
</rss>
