import React, { useState, useEffect, useRef } from "react"; // Simple GST Billing React component (single-file prototype) // - Uses Tailwind CSS classes for styling // - Features: seller/buyer details, add items with HSN, qty, rate, discount, GST rate // - Auto-calculates taxable value, CGST/SGST or IGST based on states // - Save/Load invoices to localStorage, Print/Export using window.print() // - Default export: React functional component export default function GstBillingApp() { const [seller, setSeller] = useState({ name: "Your Business", address: "", state: "Maharashtra", gstin: "" }); const [buyer, setBuyer] = useState({ name: "Customer", address: "", state: "Karnataka", gstin: "" }); const [items, setItems] = useState([ { id: 1, desc: "Sample Item", hsn: "1001", qty: 1, rate: 100.0, discount: 0, gst: 18 } ]); const [invoiceNo, setInvoiceNo] = useState(() => `INV-${Date.now().toString().slice(-6)}`); const [date, setDate] = useState(() => new Date().toISOString().slice(0, 10)); const printRef = useRef(); // helper: compute line totals function lineTotal(it) { const amount = it.qty * it.rate; const disc = (it.discount || 0) / 100 * amount; const taxable = Math.max(0, amount - disc); const gstAmt = taxable * (it.gst || 0) / 100; return { amount, disc, taxable, gstAmt }; } function isInterState() { return seller.state && buyer.state && seller.state.trim().toLowerCase() !== buyer.state.trim().toLowerCase(); } function invoiceTotals() { let totalTaxable = 0, totalGst = 0; items.forEach(it => { const { taxable, gstAmt } = lineTotal(it); totalTaxable += taxable; totalGst += gstAmt; }); return { totalTaxable, totalGst, grandTotal: totalTaxable + totalGst }; } function updateItem(id, key, value) { setItems(prev => prev.map(it => it.id === id ? { ...it, [key]: value } : it)); } function addItem() { setItems(prev => [...prev, { id: Date.now(), desc: "", hsn: "", qty: 1, rate: 0, discount: 0, gst: 18 }]); } function removeItem(id) { setItems(prev => prev.filter(it => it.id !== id)); } function saveDraft() { const payload = { seller, buyer, items, invoiceNo, date }; localStorage.setItem(`gst-invoice-${invoiceNo}`, JSON.stringify(payload)); localStorage.setItem("gst-invoice-latest", JSON.stringify(payload)); alert("Invoice saved to localStorage (draft)"); } function loadLatest() { const data = localStorage.getItem("gst-invoice-latest"); if (!data) return alert("No saved invoice found."); const p = JSON.parse(data); setSeller(p.seller || seller); setBuyer(p.buyer || buyer); setItems(p.items || items); setInvoiceNo(p.invoiceNo || invoiceNo); setDate(p.date || date); alert("Loaded latest saved invoice."); } function exportAsJSON() { const payload = { seller, buyer, items, invoiceNo, date }; const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `${invoiceNo}.json`; a.click(); URL.revokeObjectURL(url); } function printInvoice() { window.print(); } // small UI const totals = invoiceTotals(); return (

GST Billing — Prototype

Seller (From)

setSeller({ ...seller, name: e.target.value })} placeholder="Seller name" /> setSeller({ ...seller, address: e.target.value })} placeholder="Address" /> setSeller({ ...seller, state: e.target.value })} placeholder="State" /> setSeller({ ...seller, gstin: e.target.value })} placeholder="GSTIN" />

Buyer (To)

setBuyer({ ...buyer, name: e.target.value })} placeholder="Buyer name" /> setBuyer({ ...buyer, address: e.target.value })} placeholder="Address" /> setBuyer({ ...buyer, state: e.target.value })} placeholder="State" /> setBuyer({ ...buyer, gstin: e.target.value })} placeholder="GSTIN" />
setInvoiceNo(e.target.value)} /> setDate(e.target.value)} />
{isInterState() ? Interstate → IGST : Intrastate → CGST+SGST}
{items.map((it, idx) => { const lt = lineTotal(it); return ( ); })}
# Description HSN Qty Rate Discount % GST % Taxable Tax Total Action
{idx + 1} updateItem(it.id, 'desc', e.target.value)} /> updateItem(it.id, 'hsn', e.target.value)} /> updateItem(it.id, 'qty', parseFloat(e.target.value || 0))} /> updateItem(it.id, 'rate', parseFloat(e.target.value || 0))} /> updateItem(it.id, 'discount', parseFloat(e.target.value || 0))} /> {lt.taxable.toFixed(2)} {lt.gstAmt.toFixed(2)} {(lt.taxable + lt.gstAmt).toFixed(2)}
Taxable Total: {totals.totalTaxable.toFixed(2)}
GST Total: {totals.totalGst.toFixed(2)}
Grand Total: {totals.grandTotal.toFixed(2)}
This is a prototype. For production: add digital signing, e-invoice integration, QR code, PDF templates, and secure backend.
); }

Comments

Popular posts from this blog