<?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: sudarshan161219</title>
    <description>The latest articles on Forem by sudarshan161219 (@sudarshan_s_hosalli).</description>
    <link>https://forem.com/sudarshan_s_hosalli</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%2F879991%2Fa2ece000-2de6-44f3-8e64-11504d7a89e6.jpeg</url>
      <title>Forem: sudarshan161219</title>
      <link>https://forem.com/sudarshan_s_hosalli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sudarshan_s_hosalli"/>
    <language>en</language>
    <item>
      <title>I built a real-time retainer tracker using React and Node.js</title>
      <dc:creator>sudarshan161219</dc:creator>
      <pubDate>Sun, 18 Jan 2026 16:36:59 +0000</pubDate>
      <link>https://forem.com/sudarshan_s_hosalli/i-built-a-real-time-retainer-tracker-using-react-and-nodejs-4jj7</link>
      <guid>https://forem.com/sudarshan_s_hosalli/i-built-a-real-time-retainer-tracker-using-react-and-nodejs-4jj7</guid>
      <description>&lt;p&gt;Hi everyone.&lt;/p&gt;

&lt;p&gt;I recently built a tool called Retain to solve a specific problem: efficiently tracking freelance hours without spreadsheets or constant email updates.&lt;/p&gt;

&lt;p&gt;The Concept &lt;a href="https://retain-frontend-gamma.vercel.app" rel="noopener noreferrer"&gt;Retain&lt;/a&gt; is a client portal that keeps budget tracking transparent. The goal was to remove friction for both the developer and the client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-Time Sync: Utilizing Socket.io, budget bars update instantly on the client’s screen whenever hours are logged on the admin side.&lt;/li&gt;
&lt;li&gt;Magic Links: Clients receive a secure, cryptographic link to view their dashboard. No account creation or login is required.&lt;/li&gt;
&lt;li&gt;Tech Stack: React, Node.js, Express, Prisma, and PostgreSQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I set a total budget (e.g., 20 hours).&lt;/li&gt;
&lt;li&gt;I log time as I work.&lt;/li&gt;
&lt;li&gt;The client checks their permanent link to see exactly how much time remains.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I am currently refining the architecture and would appreciate any feedback on the concept or the stack.&lt;/p&gt;

&lt;p&gt;link:&lt;a href="https://retain-frontend-gamma.vercel.app" rel="noopener noreferrer"&gt;https://retain-frontend-gamma.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>node</category>
      <category>saas</category>
    </item>
    <item>
      <title>Built a lightweight client sign-off tool sharing the tech stack and design decisions (beta)</title>
      <dc:creator>sudarshan161219</dc:creator>
      <pubDate>Mon, 05 Jan 2026 20:11:19 +0000</pubDate>
      <link>https://forem.com/sudarshan_s_hosalli/built-a-lightweight-client-sign-off-tool-sharing-the-tech-stack-and-design-decisions-beta-1ag2</link>
      <guid>https://forem.com/sudarshan_s_hosalli/built-a-lightweight-client-sign-off-tool-sharing-the-tech-stack-and-design-decisions-beta-1ag2</guid>
      <description>&lt;p&gt;I’ve been working on a small side project to experiment with secure file sharing and approval workflows, and wanted to share the technical approach and get feedback from other developers.&lt;br&gt;
So I built a small client sign-off / approval tool.&lt;/p&gt;

&lt;p&gt;Core features&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File upload (images, PDFs)&lt;/li&gt;
&lt;li&gt;Public approval links (no authentication)&lt;/li&gt;
&lt;li&gt;Explicit approval / change-request state&lt;/li&gt;
&lt;li&gt;Simple audit trail of actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technical overview&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: React + TypeScript&lt;/li&gt;
&lt;li&gt;Backend: Node.js (Express)&lt;/li&gt;
&lt;li&gt;Database: PostgreSQL (via Prisma)&lt;/li&gt;
&lt;li&gt;Storage: Object storage with pre-signed URLs (no file proxying through the server)&lt;/li&gt;
&lt;li&gt;Auth model: Token-based public links instead of user accounts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Design decisions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No sign-up / no user auth: approval links are scoped via unique tokens to reduce friction&lt;/li&gt;
&lt;li&gt;Pre-signed uploads: keeps the backend stateless and avoids large file handling&lt;/li&gt;
&lt;li&gt;Minimal domain model: Project → File → Approval log&lt;/li&gt;
&lt;li&gt;Explicit states: PENDING / APPROVED / CHANGES_REQUESTED&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Current status&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beta&lt;/li&gt;
&lt;li&gt;Focused on correctness, simplicity, and clean APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d love feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture choices&lt;/li&gt;
&lt;li&gt;Security implications of public token links&lt;/li&gt;
&lt;li&gt;What you’d improve or redesign at this stage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;here is the link: &lt;a href="https://signoff-one.vercel.app/" rel="noopener noreferrer"&gt;https://signoff-one.vercel.app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>portfolio</category>
      <category>react</category>
    </item>
    <item>
      <title>Building a Serverless Invoice Generator with React, Zustand, and Tailwind</title>
      <dc:creator>sudarshan161219</dc:creator>
      <pubDate>Sat, 27 Dec 2025 20:07:25 +0000</pubDate>
      <link>https://forem.com/sudarshan_s_hosalli/building-a-serverless-invoice-generator-with-react-zustand-and-tailwind-4jm2</link>
      <guid>https://forem.com/sudarshan_s_hosalli/building-a-serverless-invoice-generator-with-react-zustand-and-tailwind-4jm2</guid>
      <description>&lt;p&gt;I just shipped a new portfolio project: a Free Invoice &amp;amp; Document Generator that runs entirely in the browser.&lt;/p&gt;

&lt;p&gt;I wanted to challenge myself to build a complex form-handling application without relying on a backend database. The goal was to create something useful for freelancers that respects user privacy by design.&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%2Fau3s9jjdyocqbem50t1r.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%2Fau3s9jjdyocqbem50t1r.png" alt=" " width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 The Project
&lt;/h2&gt;

&lt;p&gt;The app allows users to generate professional Invoices, Quotes, and Receipts instantly. Because it uses Local Storage, users can close the tab and come back later without losing their work, but no data is ever sent to a server.&lt;/p&gt;

&lt;p&gt;🔗 Live Demo: &lt;a href="https://invo-eight.vercel.app/" rel="noopener noreferrer"&gt;Invo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Framework: React (Vite) for speed.&lt;/li&gt;
&lt;li&gt;State: Zustand (for handling complex nested form data).&lt;/li&gt;
&lt;li&gt;Styling: Tailwind CSS (specifically utilizing &lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; print to ensure pixel-perfect A4 outputs).&lt;/li&gt;
&lt;li&gt;Icons: Lucide React.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔮 Future Roadmap
&lt;/h2&gt;

&lt;p&gt;While the app is functional now, I have a few features on the roadmap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloud Backup: Integrating Supabase/Firebase for users who want to sync across devices.&lt;/li&gt;
&lt;li&gt;PDF Export: Improving the native download functionality.&lt;/li&gt;
&lt;li&gt;Authentication: Optional login for saving client lists permanently.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🙏 Request for Feedback
&lt;/h2&gt;

&lt;p&gt;I built this to demonstrate my skills for freelance clients on Upwork.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How is the UX? Is the form flow intuitive?&lt;/li&gt;
&lt;li&gt;Are there any "must-have" features for invoicing that I missed?&lt;/li&gt;
&lt;li&gt;Any code organization tips for large Zustand stores?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I appreciate any feedback or code reviews!&lt;/p&gt;

&lt;p&gt;Thanks for reading. Happy coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Modal closing on refresh (React + Zustand + sessionStorage)</title>
      <dc:creator>sudarshan161219</dc:creator>
      <pubDate>Sat, 01 Nov 2025 20:36:40 +0000</pubDate>
      <link>https://forem.com/sudarshan_s_hosalli/modal-closing-on-refresh-react-zustand-sessionstorage-28ef</link>
      <guid>https://forem.com/sudarshan_s_hosalli/modal-closing-on-refresh-react-zustand-sessionstorage-28ef</guid>
      <description>&lt;p&gt;I wanted my modal state to survive page reloads, so I persisted it in sessionStorage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "isOpen": true,&lt;br&gt;
  "activeModal": "addFile",&lt;br&gt;
  "mode": "addFile"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Problem:&lt;br&gt;
When navigating to a different route, the modal should auto-close ✅&lt;br&gt;
But on refresh, React remounts → effect runs → modal closes ❌&lt;/p&gt;

&lt;p&gt;Final clean fix&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";
import { useModalStore } from "@/store/useModalStore";

export const useAutoCloseModalOnRouteChange = () =&amp;gt; {
  const { pathname } = useLocation();
  const prevPath = useRef(pathname);

  useEffect(() =&amp;gt; {
    const store = useModalStore.getState();

    // ✅ Only close if the route *actually* changed
    if (prevPath.current !== pathname &amp;amp;&amp;amp; store.isOpen) {
      store.closeModal();
    }

    prevPath.current = pathname;
  }, [pathname]);
};

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

&lt;/div&gt;



&lt;p&gt;✅ Closes modal only on real navigation&lt;br&gt;
✅ Modal stays open on page refresh&lt;br&gt;
✅ Works with Zustand + sessionStorage&lt;br&gt;
✅ No infinite loops&lt;br&gt;
✅ No permissions required  browsers allow sessionStorage by default&lt;/p&gt;

&lt;p&gt;✅ Short feedback&lt;/p&gt;

&lt;p&gt;This approach is clean because:&lt;/p&gt;

&lt;p&gt;You don’t add closeModal to dependencies (avoids re-renders)&lt;/p&gt;

&lt;p&gt;No infinite loops (not watching isOpen)&lt;/p&gt;

&lt;p&gt;Fully independent from the UI can be dropped into any route-based modal&lt;/p&gt;

&lt;p&gt;Nice little pattern for URL-synced modals 👌&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>frontend</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Building My Invoice App – Added File Attachments Today</title>
      <dc:creator>sudarshan161219</dc:creator>
      <pubDate>Fri, 31 Oct 2025 06:19:57 +0000</pubDate>
      <link>https://forem.com/sudarshan_s_hosalli/building-my-invoice-app-added-file-attachments-today-1313</link>
      <guid>https://forem.com/sudarshan_s_hosalli/building-my-invoice-app-added-file-attachments-today-1313</guid>
      <description>&lt;p&gt;I’m still working on my invoice tool for freelancers and small businesses, and today I added a new feature: file attachments for each client or invoice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I wanted
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Let users attach receipts, PDFs, images, contracts, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow multiple uploads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show real-time progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename files before/after uploading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store files in the cloud (not just locally)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep everything tied to a specific client&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Formats I decided to support
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
  type="file"
  className="hidden"
  onChange={handleChange}
  multiple
  disabled={uploadedFiles.length + uploadQueue.length &amp;gt;= MAX_FILES}
  accept="
    .jpg,.jpeg,.png,.webp,
    .pdf,.doc,.docx,.xls,.xlsx,.csv,.txt,.odt,
    .zip,.rar,.7z,.tar,.gz,
    .mp3,.wav,.mp4,.mov,
    .psd,.ai,.svg,.fig"
 /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tools I used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;React + TypeScript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloudflare R2 for storage(free upto 10gb)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Presigned URLs for direct uploads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prisma to link attachments to clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modals + toasts for UI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m sharing this because I’m trying to build this project piece by piece, learning as I go.&lt;br&gt;
If you have ideas, better approaches, or feature suggestions, I’d love to hear them.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>buildinpublic</category>
      <category>sideprojects</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Is it still worth building an invoice generator SaaS in 2025?</title>
      <dc:creator>sudarshan161219</dc:creator>
      <pubDate>Tue, 28 Oct 2025 05:44:33 +0000</pubDate>
      <link>https://forem.com/sudarshan_s_hosalli/is-it-still-worth-building-an-invoice-generator-saas-in-2025-3ho7</link>
      <guid>https://forem.com/sudarshan_s_hosalli/is-it-still-worth-building-an-invoice-generator-saas-in-2025-3ho7</guid>
      <description>&lt;p&gt;Hi friends&lt;/p&gt;

&lt;p&gt;I’m a solo developer currently about 75% done building an invoice generator SaaS for freelancers and small business owners.&lt;/p&gt;

&lt;p&gt;It started as a simple tool for myself  something minimal, privacy-focused, and quick to use. But as I kept building, I realized… there are tons of invoice tools already out there 😅&lt;/p&gt;

&lt;p&gt;Now I’m wondering is it still worth finishing and launching it?&lt;/p&gt;

&lt;p&gt;Here’s what my version focuses on so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Minimal and fast UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simple subscription-based pricing (no complex tiers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Privacy-first (no tracking, no data selling)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Freelancer-focused workflow — quick client and invoice creation, no bloat&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not trying to reinvent the wheel just make invoicing cleaner and lighter for solo creators and small businesses.&lt;/p&gt;

&lt;p&gt;But I’d love to get your perspective:&lt;/p&gt;

&lt;p&gt;Would you still use a new invoice generator today?&lt;/p&gt;

&lt;p&gt;What would make one stand out for you in 2025?&lt;/p&gt;

&lt;p&gt;If you’ve built a SaaS before how did you validate it before launch?&lt;/p&gt;

&lt;p&gt;Any feedback or advice from fellow builders would mean a lot 🙏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>saas</category>
      <category>discuss</category>
      <category>react</category>
    </item>
  </channel>
</rss>
