diff --git a/FrontEnd/Dashboard.php b/FrontEnd/Dashboard.php
index 2801334c..74b617c1 100644
--- a/FrontEnd/Dashboard.php
+++ b/FrontEnd/Dashboard.php
@@ -124,6 +124,7 @@ $slug = $_GET['page'] ?? 'dashboard';
     "modules/workplace/workplaceinvoice":       "./js/modules/Workplace/workplaceInvoice.js",
     "modules/workplace/workplacereview":        "./js/modules/Workplace/workplaceReview.js",
     "modules/profile/userprofile":               "./js/modules/Profile/UserProfile.js",
+    "modules/quotations/quotations":             "./js/modules/quotations/quotations.js",
     "modules/employees":                        "./js/modules/Employees.js",
     "modules/access/useraccessmanager":         "./js/modules/Access/UserAccessManager.js",
     "modules/inventory/inventorymanagement":    "./js/modules/Inventory/InventoryManagement.js",
@@ -339,6 +340,13 @@ $slug = $_GET['page'] ?? 'dashboard';
     </a>
 <?php } ?>
 
+    <?php if ($auth->canViewModule('Quotations', $userId)) { ?>
+<a class="card flex flex-col items-center bg-base-100 rounded-lg shadow hover:shadow-lg transform hover:-translate-y-1 transition p-6 text-center text-base-content" href="#Quotations" aria-label="Quotations">
+      <i class="fa-solid fa-file-invoice-dollar text-primary text-4xl mb-2"></i>
+      <div class="label text-sm font-semibold">Quotations</div>
+    </a>
+<?php } ?>
+
 
 
   </main>
diff --git a/FrontEnd/js/core/schema.js b/FrontEnd/js/core/schema.js
index bfa211b4..486d5d63 100644
--- a/FrontEnd/js/core/schema.js
+++ b/FrontEnd/js/core/schema.js
@@ -1,4 +1,4 @@
-export const DB_VERSION = 142;
+export const DB_VERSION = 143;
 
 export const DB_STORES = {
   EquipmentServices: { keyPath: 'id' },
@@ -277,4 +277,5 @@ export const DB_STORES = {
   auto_orders: {keyPath: 'auto_order_id' },
   generated_payslips: { keyPath: 'payslip_id' },
   users_profiles: { keyPath: 'user_profile_id'  },
+  quotations: { keyPath: 'quotation_id' },
 };
diff --git a/FrontEnd/js/modules/quotations/quotationpreview.js b/FrontEnd/js/modules/quotations/quotationpreview.js
new file mode 100644
index 00000000..e948edf4
--- /dev/null
+++ b/FrontEnd/js/modules/quotations/quotationpreview.js
@@ -0,0 +1,24 @@
+function handleWorkflowEvent(e){
+  const detail = e?.detail;
+  if(!detail) return;
+  if(typeof detail === 'object' && detail.action === 'open_modal' && detail.name === 'Quotation Preview'){
+    const id = detail.context?.quotation_id;
+    if(!id) return;
+    fetch(`../api/quotations/view/${id}`)
+      .then(r => r.ok ? r.text() : '')
+      .then(html => {
+        if(!html) return;
+        const container = document.getElementById('quotationPreview');
+        if(container) {
+          container.innerHTML = html;
+        }
+      })
+      .catch(err => console.error('load quotation preview', err));
+  }
+}
+
+if(typeof window !== 'undefined'){
+  window.addEventListener('workflowEvent', handleWorkflowEvent);
+}
+
+export { handleWorkflowEvent };
\ No newline at end of file
diff --git a/FrontEnd/js/modules/quotations/quotations.js b/FrontEnd/js/modules/quotations/quotations.js
new file mode 100644
index 00000000..552026f4
--- /dev/null
+++ b/FrontEnd/js/modules/quotations/quotations.js
@@ -0,0 +1,429 @@
+import { LocalSyncManager } from "core/localsyncmanager";
+import { DataLoader       } from "core/dataloader";
+import { ModalBuilder     } from "core/modalbuilder";
+import './quotationpreview.js';
+
+let syncManager, dataLoader;        // module-scoped, NOT global
+
+export async function mount(target = '#work-area') {
+
+    syncManager = new LocalSyncManager({
+        autoPush: true,
+        dbName: 'TAFDB',
+        tables: {
+            quotations: '../api/quotations'
+        }
+    });
+
+    await syncManager.init();
+
+    // Create the module content with header and table
+    const html = `
+        <div class="mb-4">
+            <button id="addQuotationBtn" class="btn btn-primary">Add Quotation</button>
+        </div>
+        <table class="quotations-table"></table>
+    `;
+    $(target).html(html);
+
+    dataLoader = new DataLoader({
+        selector: '.quotations-table',
+        tableName: 'quotations',
+        syncManager,
+        limit: 10,
+        searchInputTypes: {
+            quotation_number: 'text',
+            customer_id: 'text',
+            date: 'text'
+        },
+        columnsToShow: [
+            'quotation_number', 'customer_id', 'date'
+        ],
+        rowActions: [{
+            label: 'View',
+            onClick: (row) => {
+                // Open a modal for viewing the quotation
+                window.dispatchEvent(new CustomEvent('workflowEvent', {
+                    detail: {
+                        action: 'open_modal',
+                        name: 'Quotation Preview',
+                        context: { quotation_id: row.quotation_id }
+                    }
+                }));
+            }
+        }]
+    });
+
+    await dataLoader.init();
+    await dataLoader.fetchData();
+
+    // Add event listener for the Add Quotation button
+    $('#addQuotationBtn').on('click', openNewQuotationModal);
+
+    await loadDummyQuotationsOnce(syncManager);
+    await dataLoader.fetchData(); // Refresh after loading dummy data
+
+}
+
+export async function unmount() {
+    // Clean up any resources if needed
+    if (syncManager) {
+        // Any cleanup for syncManager if needed
+    }
+}
+
+async function loadDummyQuotationsOnce(syncManager) {
+    const DUMMY_KEY = 'quotationsDummyLoaded';
+    if (localStorage.getItem(DUMMY_KEY)) return;
+
+    const dummyQuotations = Array.from({ length: 20 }, (_, i) => ({
+        quotation_id: `0194a8b2-0000-7123-8123-${String(1000 + i).padStart(12, '0')}`,
+        quotation_number: `Q-${1000 + i}`,
+        customer_id: [
+            '0194a8b2-1001-7123-8123-123456789abc',
+            '0194a8b2-1002-7123-8123-123456789abc', 
+            '0194a8b2-1003-7123-8123-123456789abc',
+            '0194a8b2-1004-7123-8123-123456789abc',
+            '0194a8b2-1005-7123-8123-123456789abc'
+        ][i % 5],
+        date: new Date(Date.now() - i * 86400000).toISOString().split('T')[0]
+    }));
+
+    for (const quotation of dummyQuotations) {
+        await syncManager.add('quotations', quotation);
+    }
+
+    localStorage.setItem(DUMMY_KEY, 'true');
+    console.log('[Quotations] Dummy data loaded.');
+}
+
+async function openNewQuotationModal() {
+    const schema = {
+        title: "New Quotation",
+        body: [
+            {
+                type: "html",
+                html: `
+                    <div>
+                        <div class="form-control mb-4">
+                            <label class="label">
+                                <span class="label-text">Customer</span>
+                            </label>
+                            <select id="customerSelect" class="select select-bordered w-full">
+                                <option value="">Select Customer</option>
+                            </select>
+                        </div>
+                        <table id="itemsTable" class="table w-full">
+                            <thead>
+                                <tr>
+                                    <th>Name</th>
+                                    <th>Description</th>
+                                    <th>Unit Price</th>
+                                    <th>Unit</th>
+                                    <th>Total</th>
+                                    <th>Action</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                            </tbody>
+                        </table>
+                        
+                        <!-- Note Section -->
+                        <div id="noteSection" class="mt-4 p-4 bg-blue-50 rounded-lg border border-blue-200 hidden">
+                            <div class="form-control">
+                                <label class="label">
+                                    <span class="label-text font-semibold text-blue-700">Quotation Note</span>
+                                </label>
+                                <textarea id="quotationNote" class="textarea textarea-bordered h-24" placeholder="Enter any additional notes for this quotation..."></textarea>
+                            </div>
+                            <div class="flex justify-end mt-3">
+                                <button id="saveNoteBtn" class="btn btn-sm btn-info">
+                                    <i class="fas fa-save mr-1"></i>Save Note
+                                </button>
+                            </div>
+                        </div>
+                        
+                        <!-- Validity Section -->
+                        <div id="validitySection" class="mt-4 p-4 bg-orange-50 rounded-lg border border-orange-200 hidden">
+                            <div class="form-control">
+                                <label class="label">
+                                    <span class="label-text font-semibold text-orange-700">Validity Period</span>
+                                </label>
+                                <div class="flex items-center gap-2">
+                                    <input type="number" id="validityDays" class="input input-bordered w-32" placeholder="30" min="1" value="30">
+                                    <span class="text-sm text-gray-600">days</span>
+                                </div>
+                            </div>
+                            <div class="flex justify-end mt-3">
+                                <button id="saveValidityBtn" class="btn btn-sm btn-warning">
+                                    <i class="fas fa-save mr-1"></i>Save Validity
+                                </button>
+                            </div>
+                        </div>
+                        
+                                                </table>
+                        
+                        <!-- Grand Total Display -->
+                        <div class="mt-4 text-right">
+                            <span class="text-lg font-semibold">Grand Total: $<span id="grandTotal">0.00</span></span>
+                        </div>
+                        
+                        <!-- Saved Note Display -->
+                        <div id="savedNoteDisplay" class="mt-4 p-3 bg-blue-50 rounded-lg border-l-4 border-blue-400 hidden">
+                            <div class="flex items-start gap-2">
+                                <i class="fas fa-sticky-note text-blue-600 mt-1"></i>
+                                <div class="flex-1">
+                                    <div class="text-sm font-semibold text-blue-700 mb-1">Quotation Note:</div>
+                                    <div id="savedNoteText" class="text-sm text-gray-700 whitespace-pre-wrap"></div>
+                                </div>
+                                <div class="flex gap-1">
+                                    <button id="editNoteBtn" class="btn btn-xs btn-ghost text-blue-600" title="Edit Note">
+                                        <i class="fas fa-edit"></i>
+                                    </button>
+                                    <button id="deleteNoteBtn" class="btn btn-xs btn-ghost text-red-500 hover:text-red-700" title="Delete Note">
+                                        <i class="fas fa-times"></i>
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                        
+                        <!-- Saved Validity Display -->
+                        <div id="savedValidityDisplay" class="mt-4 p-3 bg-orange-50 rounded-lg border-l-4 border-orange-400 hidden">
+                            <div class="flex items-center gap-2">
+                                <i class="fas fa-calendar-alt text-orange-600"></i>
+                                <div class="flex-1">
+                                    <div class="text-sm font-semibold text-orange-700">Validity Period:</div>
+                                    <div id="savedValidityText" class="text-sm text-gray-700"></div>
+                                </div>
+                                <div class="flex gap-1">
+                                    <button id="editValidityBtn" class="btn btn-xs btn-ghost text-orange-600" title="Edit Validity">
+                                        <i class="fas fa-edit"></i>
+                                    </button>
+                                    <button id="deleteValidityBtn" class="btn btn-xs btn-ghost text-red-500 hover:text-red-700" title="Delete Validity">
+                                        <i class="fas fa-times"></i>
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                        
+                        <div class="flex justify-start items-center mt-4">
+                            <div class="flex gap-2">
+                                <button id="addRowBtn" class="btn btn-primary">
+                                    <i class="fas fa-plus mr-2"></i>Add Item
+                                </button>
+                                <button id="noteBtn" class="btn btn-outline btn-info">
+                                    <i class="fas fa-sticky-note mr-2"></i>Note
+                                </button>
+                                <button id="validityBtn" class="btn btn-outline btn-warning">
+                                    <i class="fas fa-calendar-alt mr-2"></i>Validity
+                                </button>
+                            </div>
+                        </div>
+                    </div>
+                `
+            }
+        ],
+        footer: [
+            {
+                type: "button",
+                label: "Save",
+                onClick: saveQuotation
+            },
+            {
+                type: "button",
+                label: "Cancel",
+                onClick: closeCurrentModal
+            }
+        ]
+    };
+
+    // Create a new modal container for the add quotation modal
+    const modalId = 'add-quotation-modal';
+    if (!$('#' + modalId).length) {
+        $('body').append(`<div id="${modalId}" class="modal"></div>`);
+    }
+
+    const builder = new ModalBuilder(schema);
+    window.currentModalBuilder = builder;
+    await builder.render('#' + modalId);
+    populateCustomers();
+    setupTableEvents();
+}
+
+async function populateCustomers() {
+    try {
+        const response = await fetch('../api/customers');
+        if (response.ok) {
+            const customers = await response.json();
+            const select = $('#customerSelect');
+            select.empty();
+            select.append('<option value="">Select Customer</option>');
+            customers.forEach(customer => {
+                const option = document.createElement('option');
+                option.value = customer.customer_id;
+                option.textContent = customer.name;
+                select.append(option);
+            });
+        } else {
+            console.error('Failed to fetch customers');
+        }
+    } catch (error) {
+        console.error('Error fetching customers:', error);
+    }
+}
+
+function setupTableEvents() {
+    $('#addRowBtn').on('click', addRow);
+    $('#noteBtn').on('click', function() {
+        $('#noteSection').toggleClass('hidden');
+        $('#validitySection').addClass('hidden'); // Hide validity if open
+    });
+    $('#validityBtn').on('click', function() {
+        $('#validitySection').toggleClass('hidden');
+        $('#noteSection').addClass('hidden'); // Hide note if open
+    });
+    $('#saveNoteBtn').on('click', function() {
+        const noteText = $('#quotationNote').val().trim();
+        if (noteText) {
+            $('#savedNoteText').text(noteText);
+            $('#savedNoteDisplay').removeClass('hidden');
+        } else {
+            $('#savedNoteDisplay').addClass('hidden');
+        }
+        $('#noteSection').addClass('hidden');
+    });
+    $('#saveValidityBtn').on('click', function() {
+        const validityDays = $('#validityDays').val();
+        if (validityDays && validityDays > 0) {
+            $('#savedValidityText').text(`${validityDays} days`);
+            $('#savedValidityDisplay').removeClass('hidden');
+        } else {
+            $('#savedValidityDisplay').addClass('hidden');
+        }
+        $('#validitySection').addClass('hidden');
+    });
+    $('#editNoteBtn').on('click', function() {
+        $('#noteSection').removeClass('hidden');
+        $('#validitySection').addClass('hidden');
+    });
+    $('#editValidityBtn').on('click', function() {
+        $('#validitySection').removeClass('hidden');
+        $('#noteSection').addClass('hidden');
+    });
+    $('#deleteNoteBtn').on('click', function() {
+        $('#savedNoteDisplay').addClass('hidden');
+        $('#quotationNote').val('');
+    });
+    $('#deleteValidityBtn').on('click', function() {
+        $('#savedValidityDisplay').addClass('hidden');
+        $('#validityDays').val('30');
+    });
+    $('#itemsTable').on('input', handleInput);
+    $('#itemsTable').on('click', handleClick);
+}
+
+function addRow() {
+    const tbody = $('#itemsTable tbody');
+    const row = document.createElement('tr');
+    row.innerHTML = `
+        <td><input type="text" class="input input-bordered w-full" name="name"></td>
+        <td><input type="text" class="input input-bordered w-full" name="description"></td>
+        <td><input type="number" class="input input-bordered w-full" name="unit_price" step="0.01"></td>
+        <td><input type="number" class="input input-bordered w-full" name="unit" min="1" value="1"></td>
+        <td><input type="number" class="input input-bordered w-full" name="total" readonly></td>
+        <td><button class="btn btn-sm btn-error remove-row">Remove</button></td>
+    `;
+    tbody.append(row);
+    updateGrandTotal();
+}
+
+function handleInput(event) {
+    const target = $(event.target);
+    if (target.attr('name') === 'unit_price' || target.attr('name') === 'unit') {
+        const row = target.closest('tr');
+        const unitPrice = parseFloat(row.find('input[name="unit_price"]').val()) || 0;
+        const unit = parseFloat(row.find('input[name="unit"]').val()) || 1;
+        const totalInput = row.find('input[name="total"]');
+        totalInput.val((unitPrice * unit).toFixed(2));
+        updateGrandTotal();
+    }
+}
+
+function handleClick(event) {
+    const target = $(event.target);
+    if (target.hasClass('remove-row')) {
+        target.closest('tr').remove();
+        updateGrandTotal();
+    }
+}
+
+function updateGrandTotal() {
+    let grandTotal = 0;
+    $('#itemsTable tbody tr').each(function() {
+        const rowTotal = parseFloat($(this).find('input[name="total"]').val()) || 0;
+        grandTotal += rowTotal;
+    });
+    $('#grandTotal').text(grandTotal.toFixed(2));
+}
+
+async function saveQuotation() {
+    const customerId = $('#customerSelect').val();
+    if (!customerId) {
+        alert('Please select a customer');
+        return;
+    }
+
+    const rows = $('#itemsTable tbody tr');
+    const items = [];
+    rows.each(function() {
+        const row = $(this);
+        const name = row.find('input[name="name"]').val();
+        const description = row.find('input[name="description"]').val();
+        const unitPrice = parseFloat(row.find('input[name="unit_price"]').val()) || 0;
+        const unit = parseFloat(row.find('input[name="unit"]').val()) || 1;
+        const total = parseFloat(row.find('input[name="total"]').val()) || 0;
+        if (name || description || unitPrice) {
+            items.push({ name, description, unit_price: unitPrice, unit, total });
+        }
+    });
+
+    if (items.length === 0) {
+        alert('Please add at least one item');
+        return;
+    }
+
+    const quotation = {
+        quotation_id: generateUUID(),
+        quotation_number: `Q-${Date.now()}`,
+        customer_id: customerId,
+        date: new Date().toISOString().split('T')[0],
+        items: items,
+        note: $('#quotationNote').val().trim() || '',
+        validity_days: parseInt($('#validityDays').val()) || 30
+    };
+
+    await syncManager.add('quotations', quotation);
+    alert('Quotation saved successfully');
+    
+    // Close modal
+    closeCurrentModal();
+}
+
+function generateUUID() {
+    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+        const r = Math.random() * 16 | 0;
+        const v = c == 'x' ? r : (r & 0x3 | 0x8);
+        return v.toString(16);
+    });
+}
+
+function closeCurrentModal() {
+    if (window.currentModalBuilder) {
+        // Clean up instances before closing
+        window.currentModalBuilder.destroy();
+        const modalId = 'add-quotation-modal';
+        const $modal = $('#' + modalId);
+        $modal.removeClass('modal-open');
+        $modal.remove();
+    }
+}
\ No newline at end of file
diff --git a/TAFDB.pgsql b/TAFDB.pgsql
index 09e7785e..1366fe3a 100644
--- a/TAFDB.pgsql
+++ b/TAFDB.pgsql
@@ -1286,6 +1286,15 @@ CREATE TABLE policies (
   updatedAt         timestamptz NOT NULL DEFAULT now()
 );
 
+CREATE TABLE  quotations (
+  quotation_id        uuid PRIMARY KEY DEFAULT uuid_generate_v7(),
+  quotation_number    text DEFAULT NULL,
+  date                date NOT NULL,
+  customer_id         uuid NOT NULL,
+  isDeleted           BOOLEAN NOT NULL DEFAULT FALSE,
+  updatedAt           timestamptz NOT NULL DEFAULT now() 
+);
+
 /*
 The above tables are the UUID versions of the already below tables.
 */
diff --git a/models/quotations.php b/models/quotations.php
new file mode 100644
index 00000000..cde9947a
--- /dev/null
+++ b/models/quotations.php
@@ -0,0 +1,16 @@
+<?php
+return [
+    'table'      => 'quotations',
+    'primaryKey' => 'quotation_id',
+    'fields'     => [
+        'quotation_number'    => ['type' => 'text',      'nullable' => true],
+        'date'                => ['type' => 'date',      'nullable' => false],
+        'customer_id'         => ['type' => 'uuid',      'nullable' => false],
+        'isDeleted'           => ['type' => 'bool',      'default' => false, 'required' => true],
+        'updatedAt'           => ['type' => 'timestamptz','default' => 'now()', 'required' => true],
+    ],
+    // metadata used by UI builders
+    'metadata' => [
+        'dateFields' => ['date'],
+    ],
+];
\ No newline at end of file
