Skip to main content
This guide covers various ways to customize the Mini POS System, from simple branding changes to adding new features.

Branding Customization

1

Prepare Your Logo

Create a logo file (SVG or PNG format). For best results:
  • Use SVG for scalability
  • Recommended dimensions: 512x512px
  • Keep file size under 500KB
  • Use a square aspect ratio (works best with rounded-full)
2

Replace Logo Files

Replace the existing logo:
# Replace the main logo
cp your-logo.svg images/logo.svg

# Optional: Replace POS icon in header
cp your-icon.svg images/pos.svg
3

Update References (if needed)

If you change the filename, update these locations:
index.html (and other pages)
<!-- Header icon -->
<img src="images/pos.svg" alt="Your Brand" class="w-10 h-10 rounded-full"/>

<!-- Footer logo -->
<img src="images/logo.svg" alt="Your Logo" class="w-12 h-12 rounded-full"/>

Changing Brand Name

In each HTML file (index.html, pos.html, products.html, reports.html):
<div class="flex items-center space-x-3">
  <img src="images/pos.svg" alt="Your Brand" class="w-10 h-10 rounded-full"/>
  <h1 class="text-2xl font-bold text-indigo-600">Your Brand Name</h1>
</div>
In manifest.json:
{
  "name": "Your POS System",
  "short_name": "YourPOS",
  "description": "Your custom description",
  "theme_color": "#4f46e5",
  ...
}

Color Scheme Customization

Using Tailwind’s Default Colors

The system uses Tailwind’s indigo color scheme. To change the primary color:
# Replace indigo with another Tailwind color (e.g., blue, green, purple)
# In all HTML files:
find . -name "*.html" -exec sed -i 's/indigo-/blue-/g' {} +

Custom Color Palette

To add custom colors, extend the Tailwind configuration:
tailwind.config.js
module.exports = {
  content: [
    "./*.html",
    "./js/*.js"
  ],
  theme: {
    extend: {
      colors: {
        'brand': {
          50: '#f0f9ff',
          100: '#e0f2fe',
          500: '#0ea5e9',
          600: '#0284c7',
          700: '#0369a1',
        },
      },
    },
  },
  plugins: [],
}
Then use your custom colors:
<button class="bg-brand-600 hover:bg-brand-700 text-white">
After modifying tailwind.config.js, rebuild your CSS:
npm run dev  # or npx tailwindcss -i ./src/input.css -o ./css/style.css

Currency Customization

Changing Currency Symbol

The system currently uses ₹ (Indian Rupee). To change to another currency:
1

Update HTML Currency Symbols

Search and replace in all HTML files:
# Change ₹ to $ (or your currency)
find . -name "*.html" -exec sed -i 's/₹/\$/g' {} +
2

Update JavaScript Formatting

Update the money() function in js/shared.js:
export function money(n) {
  const amount = (Math.round(Number(n) * 100) / 100).toFixed(2);
  return `$${amount}`;  // Add currency symbol
}
3

Update Currency Parsing

If your currency symbol is multi-character, update parsing logic:
js/pos.js, products.js, etc.
// Old (for single character like ₹ or $)
const price = parseFloat(priceText.slice(1));

// New (for any currency)
const price = parseFloat(priceText.replace(/[^0-9.]/g, ''));

Database Schema Extensions

Adding Product Fields

Step 1: Update database schema in js/db.js:
// No schema change needed - IndexedDB is schema-less
// Just update the addProduct function:

export async function addProduct(name, price, category = 'General') {
  return tx('products', 'readwrite', (s) => 
    s.add({ 
      name, 
      price: Number(price),
      category  // New field
    })
  );
}
Step 2: Update product form in products.html:
<form id="productForm">
  <input type="text" id="productName" placeholder="Product Name" required />
  <input type="number" id="productPrice" placeholder="Price" required />
  
  <!-- New field -->
  <select id="productCategory" class="w-full px-4 py-2 border rounded-lg">
    <option value="General">General</option>
    <option value="Food">Food</option>
    <option value="Electronics">Electronics</option>
  </select>
  
  <button type="submit">Add Product</button>
</form>
Step 3: Update js/products.js:
form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const name = document.getElementById('productName').value;
  const price = document.getElementById('productPrice').value;
  const category = document.getElementById('productCategory').value;
  
  await addProduct(name, price, category);
  // ...
});
Step 1: Update addProduct and related functions:
js/db.js
export async function addProduct(name, price, stock = 0) {
  return tx('products', 'readwrite', (s) => 
    s.add({ name, price: Number(price), stock: Number(stock) })
  );
}

export async function updateProductStock(id, newStock) {
  const db = await openDB();
  return new Promise((resolve, reject) => {
    const t = db.transaction('products', 'readwrite');
    const s = t.objectStore('products');
    const req = s.get(Number(id));
    
    req.onsuccess = () => {
      const product = req.result;
      product.stock = Number(newStock);
      s.put(product);
    };
    
    t.oncomplete = () => resolve();
    t.onerror = () => reject(t.error);
  });
}
Step 2: Deduct stock on sale in js/pos.js:
async function checkout() {
  // ... existing checkout logic ...
  
  // Deduct stock for each item
  for (const item of cart) {
    const product = await getProduct(item.id);  // You'll need to implement this
    const newStock = product.stock - item.quantity;
    await updateProductStock(item.id, newStock);
  }
  
  // ... save sale ...
}

Adding New Features

Adding a New Page

1

Create HTML File

Create a new HTML file (e.g., customers.html):
<!doctype html>
<html lang="en">
<head>
  <!-- Copy head section from index.html -->
  <title>Customers - Mini POS</title>
</head>
<body class="bg-gray-50">
  <!-- Copy header from index.html -->
  
  <!-- Add new nav item -->
  <nav class="bg-white border-b sticky top-16 z-40">
    <div class="max-w-7xl mx-auto px-4">
      <div class="flex space-x-1 overflow-x-auto">
        <a href="index.html">Dashboard</a>
        <a href="products.html">Products</a>
        <a href="pos.html">POS</a>
        <a href="reports.html">Reports</a>
        <a href="customers.html" class="text-indigo-600 border-b-2 border-indigo-600">
          Customers
        </a>
      </div>
    </div>
  </nav>
  
  <!-- Your custom content -->
  <main class="max-w-7xl mx-auto px-4 py-6">
    <h2>Customer Management</h2>
    <!-- Add your content -->
  </main>
  
  <!-- Copy footer from index.html -->
  
  <script type="module" src="js/shared.js"></script>
  <script type="module" src="js/customers.js"></script>
</body>
</html>
2

Create JavaScript Module

Create js/customers.js:
import { addCustomer, getCustomers, deleteCustomer } from './db.js';
import { showToast } from './shared.js';

// Your customer management logic
async function loadCustomers() {
  const customers = await getCustomers();
  // Render customers
}

loadCustomers();
3

Extend Database

Add customer functions to js/db.js:
// Add to onupgradeneeded
if (!db.objectStoreNames.contains('customers')) {
  db.createObjectStore('customers', { 
    keyPath: 'id', 
    autoIncrement: true 
  });
}

// Add CRUD functions
export async function addCustomer(name, phone, email) {
  return tx('customers', 'readwrite', (s) => 
    s.add({ name, phone, email })
  );
}

export async function getCustomers() {
  return tx('customers', 'readonly', (s) => {
    return new Promise((resolve) => {
      const items = [];
      s.openCursor().onsuccess = (e) => {
        const cur = e.target.result;
        if (cur) { items.push(cur.value); cur.continue(); }
        else resolve(items);
      };
    });
  });
}
4

Update Navigation

Add the new page link to all other HTML files’ navigation sections.
Important: After adding new object stores to the database, increment DB_VER in js/db.js:
const DB_VER = 2;  // Increment from 1 to 2
This triggers the onupgradeneeded event to create new stores.

Adding Export Functionality

The reports page already has CSV export. To add PDF export:
Step 1: Include jsPDF library:
reports.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
Step 2: Add export button:
<button onclick="exportPDF()" class="px-4 py-2 bg-red-600 text-white rounded-lg">
  Export to PDF
</button>
Step 3: Implement in js/reports.js:
window.exportPDF = async function() {
  const { jsPDF } = window.jspdf;
  const doc = new jsPDF();
  
  const sales = await getSalesInRange(/* dates */);
  
  doc.text('Sales Report', 20, 20);
  doc.text(`Total Sales: ₹${totalAmount}`, 20, 30);
  
  // Add table
  let y = 40;
  sales.forEach(sale => {
    doc.text(`${sale.date} - ₹${sale.total}`, 20, y);
    y += 10;
  });
  
  doc.save('sales-report.pdf');
};

UI Customization

Changing Layout

In index.html, modify the stats card grid:
<!-- Default: 1 column mobile, 2 tablet, 4 desktop -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">

<!-- Alternative: Always 2 columns -->
<div class="grid grid-cols-2 gap-4">

<!-- Alternative: 3 columns on desktop -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
Modify card styling in any page:
<!-- Default rounded card -->
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">

<!-- Flat card with more shadow -->
<div class="bg-white shadow-lg p-6 border border-gray-200">

<!-- Card with colored border -->
<div class="bg-white rounded-xl shadow-sm p-6 border-2 border-indigo-200">

Adding Animations

Step 1: Add animation utility:
src/input.css
@import "tailwindcss";

@layer utilities {
  .fade-in {
    animation: fadeIn 0.3s ease-in;
  }
  
  @keyframes fadeIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
  }
}
Step 2: Apply to elements:
<div class="bg-white rounded-xl shadow-sm p-6 fade-in">
  <!-- Card content -->
</div>
Step 3: Rebuild CSS:
npm run dev

Best Practices

Keep Modules Small

Each JavaScript module should handle one responsibility (products, sales, etc.)

Use Async/Await

All database operations are asynchronous. Always use async/await for cleaner code.

Validate User Input

Add validation before saving to the database to prevent errors.

Test Offline Mode

After changes, test that the PWA still works offline by enabling offline mode in DevTools.

Performance Tips

Remove unused styles in production:
# Build with minification
npx tailwindcss -i ./src/input.css -o ./css/style.css --minify

# This removes all unused Tailwind classes
Keep your tailwind.config.js content array accurate to ensure proper purging.
Compress SVG and PNG files:
# Install optimization tools
npm install -g svgo imagemin-cli

# Optimize SVGs
svgo images/*.svg

# Optimize PNGs
imagemin icons/*.png --out-dir=icons/
For large product lists, implement virtual scrolling or pagination:
// Load products in batches
let currentPage = 0;
const pageSize = 20;

async function loadProducts() {
  const allProducts = await getProducts();
  const start = currentPage * pageSize;
  const page = allProducts.slice(start, start + pageSize);
  renderProducts(page);
}

Next Steps

Local Setup

Review the development setup process

Project Structure

Understand the codebase organization

Build docs developers (and LLMs) love