anuragshas commited on
Commit
99078a2
·
1 Parent(s): 6d70811

add: preview page

Browse files
Files changed (2) hide show
  1. index.html +86 -78
  2. script.js +70 -45
index.html CHANGED
@@ -9,84 +9,92 @@
9
  </head>
10
 
11
  <body class="bg-gray-100">
12
- <h1 class="text-3xl font-bold text-center my-8">Quotation Generator</h1>
13
- <div id="form-container" class="container mx-auto">
14
- <form id="quotation-form" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
15
- <fieldset class="border border-gray-300 p-4 mb-4">
16
- <legend class="text-lg font-semibold mb-2">Your Company Details</legend>
17
- <input type="text" id="company-name" name="company-name" placeholder="Company Name" required
18
- class="w-full p-2 border border-gray-300 rounded mb-2">
19
- <textarea id="company-address" name="company-address" placeholder="Address" required
20
- class="w-full p-2 border border-gray-300 rounded mb-2"></textarea>
21
- <input type="text" id="company-phone" name="company-phone" placeholder="Phone"
22
- class="w-full p-2 border border-gray-300 rounded mb-2">
23
- <input type="email" id="company-email" name="company-email" placeholder="Email"
24
- class="w-full p-2 border border-gray-300 rounded mb-2">
25
- <input type="text" id="company-gstin" name="company-gstin" placeholder="GSTIN"
26
- class="w-full p-2 border border-gray-300 rounded">
27
- </fieldset>
28
- <fieldset class="border border-gray-300 p-4 mb-4">
29
- <legend class="text-lg font-semibold mb-2">Customer Company Details</legend>
30
- <input type="text" id="customer-name" name="customer-name" placeholder="Customer Name" required
31
- class="w-full p-2 border border-gray-300 rounded mb-2">
32
- <textarea id="customer-address" name="customer-address" placeholder="Address" required
33
- class="w-full p-2 border border-gray-300 rounded mb-2"></textarea>
34
- <input type="text" id="customer-phone" name="customer-phone" placeholder="Phone"
35
- class="w-full p-2 border border-gray-300 rounded mb-2">
36
- <input type="email" id="customer-email" name="customer-email" placeholder="Email"
37
- class="w-full p-2 border border-gray-300 rounded mb-2">
38
- <input type="text" id="customer-gstin" name="customer-gstin" placeholder="GSTIN"
39
- class="w-full p-2 border border-gray-300 rounded">
40
- </fieldset>
41
- <fieldset class="border border-gray-300 p-4 mb-4">
42
- <legend class="text-lg font-semibold mb-2">Quotation Details</legend>
43
- <input type="text" id="quotation-number" name="quotation-number" placeholder="Quotation Number" required
44
- class="w-full p-2 border border-gray-300 rounded mb-2">
45
- <input type="date" id="quotation-date" name="quotation-date" required
46
- class="w-full p-2 border border-gray-300 rounded">
47
- </fieldset>
48
- <fieldset class="border border-gray-300 p-4 mb-4">
49
- <legend class="text-lg font-semibold mb-2">Items</legend>
50
- <table id="items-table" class="w-full mb-2">
51
- <thead>
52
- <tr class="bg-gray-200">
53
- <th class="p-2 border border-gray-300">S.No</th>
54
- <th class="p-2 border border-gray-300">Description</th>
55
- <th class="p-2 border border-gray-300">HSN Code</th>
56
- <th class="p-2 border border-gray-300">Qty</th>
57
- <th class="p-2 border border-gray-300">Unit Price</th>
58
- <th class="p-2 border border-gray-300">Discount (%)</th>
59
- <th class="p-2 border border-gray-300">Amount</th>
60
- <th class="p-2 border border-gray-300"></th>
61
- </tr>
62
- </thead>
63
- <tbody>
64
- </tbody>
65
- </table>
66
- <button type="button" id="add-item"
67
- class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Add Item</button>
68
- </fieldset>
69
- <fieldset class="border border-gray-300 p-4 mb-4">
70
- <legend class="text-lg font-semibold mb-2">Additional Charges</legend>
71
- <label class="block mb-2">IGST (%)<input type="number" id="igst-rate" name="igst-rate" value="0" min="0"
72
- class="w-full p-2 border border-gray-300 rounded"></label>
73
- <label class="block">Freight Charges<input type="number" id="freight-charges" name="freight-charges" value="0"
74
- min="0" class="w-full p-2 border border-gray-300 rounded"></label>
75
- </fieldset>
76
- <fieldset class="border border-gray-300 p-4 mb-4">
77
- <legend class="text-lg font-semibold mb-2">Bank Details</legend>
78
- <input type="text" id="bank-name" name="bank-name" placeholder="Bank Name" required
79
- class="w-full p-2 border border-gray-300 rounded mb-2">
80
- <input type="text" id="bank-account" name="bank-account" placeholder="Account Number" required
81
- class="w-full p-2 border border-gray-300 rounded mb-2">
82
- <input type="text" id="bank-ifsc" name="bank-ifsc" placeholder="IFSC Code" required
83
- class="w-full p-2 border border-gray-300 rounded mb-2">
84
- <input type="text" id="bank-branch" name="bank-branch" placeholder="Branch" required
85
- class="w-full p-2 border border-gray-300 rounded">
86
- </fieldset>
87
- <button type="submit" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">Generate
88
- Quotation</button>
89
- </form>
 
 
 
 
 
 
 
 
90
  </div>
91
  <div id="quotation-output" style="display:none;"></div>
92
  <script src="script.js"></script>
 
9
  </head>
10
 
11
  <body class="bg-gray-100">
12
+ <h1 class="text-3xl font-bold text-center my-8" id="top-header">Quotation Generator</h1>
13
+ <div class="flex container mx-auto">
14
+ <div id="form-container" class="w-1/2 pr-4">
15
+ <form id="quotation-form" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
16
+ <fieldset class="border border-gray-300 p-4 mb-4">
17
+ <legend class="text-lg font-semibold mb-2">Your Company Details</legend>
18
+ <input type="text" id="company-name" name="company-name" placeholder="Company Name" required
19
+ class="w-full p-2 border border-gray-300 rounded mb-2">
20
+ <textarea id="company-address" name="company-address" placeholder="Address" required
21
+ class="w-full p-2 border border-gray-300 rounded mb-2"></textarea>
22
+ <input type="text" id="company-phone" name="company-phone" placeholder="Phone"
23
+ class="w-full p-2 border border-gray-300 rounded mb-2">
24
+ <input type="email" id="company-email" name="company-email" placeholder="Email"
25
+ class="w-full p-2 border border-gray-300 rounded mb-2">
26
+ <input type="text" id="company-gstin" name="company-gstin" placeholder="GSTIN"
27
+ class="w-full p-2 border border-gray-300 rounded">
28
+ </fieldset>
29
+ <fieldset class="border border-gray-300 p-4 mb-4">
30
+ <legend class="text-lg font-semibold mb-2">Customer Company Details</legend>
31
+ <input type="text" id="customer-name" name="customer-name" placeholder="Customer Name" required
32
+ class="w-full p-2 border border-gray-300 rounded mb-2">
33
+ <textarea id="customer-address" name="customer-address" placeholder="Address" required
34
+ class="w-full p-2 border border-gray-300 rounded mb-2"></textarea>
35
+ <input type="text" id="customer-phone" name="customer-phone" placeholder="Phone"
36
+ class="w-full p-2 border border-gray-300 rounded mb-2">
37
+ <input type="email" id="customer-email" name="customer-email" placeholder="Email"
38
+ class="w-full p-2 border border-gray-300 rounded mb-2">
39
+ <input type="text" id="customer-gstin" name="customer-gstin" placeholder="GSTIN"
40
+ class="w-full p-2 border border-gray-300 rounded">
41
+ </fieldset>
42
+ <fieldset class="border border-gray-300 p-4 mb-4">
43
+ <legend class="text-lg font-semibold mb-2">Quotation Details</legend>
44
+ <input type="text" id="quotation-number" name="quotation-number" placeholder="Quotation Number" required
45
+ class="w-full p-2 border border-gray-300 rounded mb-2">
46
+ <input type="date" id="quotation-date" name="quotation-date" required
47
+ class="w-full p-2 border border-gray-300 rounded">
48
+ </fieldset>
49
+ <fieldset class="border border-gray-300 p-4 mb-4">
50
+ <legend class="text-lg font-semibold mb-2">Items</legend>
51
+ <table id="items-table" class="w-full mb-2">
52
+ <thead>
53
+ <tr class="bg-gray-200">
54
+ <th class="p-2 border border-gray-300">S.No</th>
55
+ <th class="p-2 border border-gray-300">Description</th>
56
+ <th class="p-2 border border-gray-300">HSN Code</th>
57
+ <th class="p-2 border border-gray-300">Qty</th>
58
+ <th class="p-2 border border-gray-300">Unit Price</th>
59
+ <th class="p-2 border border-gray-300">Discount (%)</th>
60
+ <th class="p-2 border border-gray-300">Amount</th>
61
+ <th class="p-2 border border-gray-300"></th>
62
+ </tr>
63
+ </thead>
64
+ <tbody>
65
+ </tbody>
66
+ </table>
67
+ <button type="button" id="add-item"
68
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Add Item</button>
69
+ </fieldset>
70
+ <fieldset class="border border-gray-300 p-4 mb-4">
71
+ <legend class="text-lg font-semibold mb-2">Additional Charges</legend>
72
+ <label class="block mb-2">IGST (%)<input type="number" id="igst-rate" name="igst-rate" value="0" min="0"
73
+ class="w-full p-2 border border-gray-300 rounded"></label>
74
+ <label class="block">Freight Charges<input type="number" id="freight-charges" name="freight-charges" value="0"
75
+ min="0" class="w-full p-2 border border-gray-300 rounded"></label>
76
+ </fieldset>
77
+ <fieldset class="border border-gray-300 p-4 mb-4">
78
+ <legend class="text-lg font-semibold mb-2">Bank Details</legend>
79
+ <input type="text" id="bank-name" name="bank-name" placeholder="Bank Name" required
80
+ class="w-full p-2 border border-gray-300 rounded mb-2">
81
+ <input type="text" id="bank-account" name="bank-account" placeholder="Account Number" required
82
+ class="w-full p-2 border border-gray-300 rounded mb-2">
83
+ <input type="text" id="bank-ifsc" name="bank-ifsc" placeholder="IFSC Code" required
84
+ class="w-full p-2 border border-gray-300 rounded mb-2">
85
+ <input type="text" id="bank-branch" name="bank-branch" placeholder="Branch" required
86
+ class="w-full p-2 border border-gray-300 rounded">
87
+ </fieldset>
88
+ <button type="submit" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">Generate
89
+ Quotation</button>
90
+ </form>
91
+ </div>
92
+ <div id="preview-container" class="w-1/2 pl-4">
93
+ <div id="quotation-preview" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
94
+ <h2 class="text-2xl font-bold text-center mb-4">Quotation Preview</h2>
95
+ <div id="preview-content"></div>
96
+ </div>
97
+ </div>
98
  </div>
99
  <div id="quotation-output" style="display:none;"></div>
100
  <script src="script.js"></script>
script.js CHANGED
@@ -26,49 +26,9 @@ if (typeof document !== 'undefined') {
26
  const itemsTableBody = document.querySelector('#items-table tbody');
27
  const form = document.getElementById('quotation-form');
28
  const output = document.getElementById('quotation-output');
 
29
 
30
- function updateSerialNumbers() {
31
- itemsTableBody.querySelectorAll('tr').forEach((row, i) => {
32
- row.querySelector('.item-slno').textContent = i + 1;
33
- });
34
- }
35
-
36
- function addItemRow() {
37
- const row = document.createElement('tr');
38
- row.innerHTML = `
39
- <td class="item-slno" data-label="S.No"></td>
40
- <td data-label="Description"><input type="text" class="item-desc" placeholder="Item Description" required></td>
41
- <td data-label="HSN Code"><input type="text" class="item-hsn" placeholder="HSN Code"></td>
42
- <td data-label="Qty"><input type="number" class="item-qty" value="1" min="0" required></td>
43
- <td data-label="Unit Price"><input type="number" class="item-price" value="0" min="0" required></td>
44
- <td data-label="Discount (%)"><input type="number" class="item-discount" value="0" min="0" max="100" step="0.01" placeholder="Discount %"></td>
45
- <td class="item-amount" data-label="Amount">0.00</td>
46
- <td data-label="Action"><button type="button" class="remove-item">Remove</button></td>
47
- `;
48
- itemsTableBody.appendChild(row);
49
- updateSerialNumbers();
50
- const inputs = row.querySelectorAll('input');
51
- inputs.forEach(input => input.addEventListener('input', updateItemAmount));
52
- row.querySelector('.remove-item').addEventListener('click', () => {
53
- row.remove();
54
- updateSerialNumbers();
55
- });
56
- }
57
-
58
- function updateItemAmount(e) {
59
- const row = e.target.closest('tr');
60
- const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
61
- const price = parseFloat(row.querySelector('.item-price').value) || 0;
62
- const discountRate = parseFloat(row.querySelector('.item-discount').value) || 0;
63
- const discountAmount = qty * price * discountRate / 100;
64
- const amount = qty * price - discountAmount;
65
- row.querySelector('.item-amount').textContent = amount.toFixed(2);
66
- }
67
-
68
- addItemBtn.addEventListener('click', addItemRow);
69
-
70
- form.addEventListener('submit', function (e) {
71
- e.preventDefault();
72
  const data = new FormData(form);
73
  const company = {
74
  name: data.get('company-name'),
@@ -117,7 +77,7 @@ if (typeof document !== 'undefined') {
117
  <div class="quotation-print">
118
  <div class="header">
119
  <div class="company-details">
120
- <h1>${company.name}</h1><br>
121
  {{address}}<br>
122
  GST NO. : ${company.gstin || ''}<br>
123
  CONTACT NO : ${company.phone} ${company.email}
@@ -230,12 +190,77 @@ if (typeof document !== 'undefined') {
230
  </div>
231
  `;
232
  html = html.replace('{{address}}', company.address.replace(/\n/g, '<br>'));
233
- html = html.replace('{{cutomer_address}}', company.address.replace(/\n/g, '<br>'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  output.innerHTML = html;
235
  output.style.display = 'block';
236
  document.getElementById('form-container').style.display = 'none';
237
- addItemRow();
 
238
  });
 
 
 
239
  });
240
  }
241
 
 
26
  const itemsTableBody = document.querySelector('#items-table tbody');
27
  const form = document.getElementById('quotation-form');
28
  const output = document.getElementById('quotation-output');
29
+ const previewContent = document.getElementById('preview-content');
30
 
31
+ function generateQuotationHTML(form) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  const data = new FormData(form);
33
  const company = {
34
  name: data.get('company-name'),
 
77
  <div class="quotation-print">
78
  <div class="header">
79
  <div class="company-details">
80
+ <h1>${company.name}</h1>
81
  {{address}}<br>
82
  GST NO. : ${company.gstin || ''}<br>
83
  CONTACT NO : ${company.phone} ${company.email}
 
190
  </div>
191
  `;
192
  html = html.replace('{{address}}', company.address.replace(/\n/g, '<br>'));
193
+ html = html.replace('{{cutomer_address}}', customer.address.replace(/\n/g, '<br>'));
194
+ return html;
195
+ }
196
+
197
+ function updatePreview() {
198
+ const html = generateQuotationHTML(form);
199
+ previewContent.innerHTML = html;
200
+ }
201
+
202
+ function updateSerialNumbers() {
203
+ itemsTableBody.querySelectorAll('tr').forEach((row, i) => {
204
+ row.querySelector('.item-slno').textContent = i + 1;
205
+ });
206
+ }
207
+
208
+ function addItemRow() {
209
+ const row = document.createElement('tr');
210
+ row.innerHTML = `
211
+ <td class="item-slno" data-label="S.No"></td>
212
+ <td data-label="Description"><input type="text" class="item-desc" placeholder="Item Description" required></td>
213
+ <td data-label="HSN Code"><input type="text" class="item-hsn" placeholder="HSN Code"></td>
214
+ <td data-label="Qty"><input type="number" class="item-qty" value="1" min="0" required></td>
215
+ <td data-label="Unit Price"><input type="number" class="item-price" value="0" min="0" required></td>
216
+ <td data-label="Discount (%)"><input type="number" class="item-discount" value="0" min="0" max="100" step="0.01" placeholder="Discount %"></td>
217
+ <td class="item-amount" data-label="Amount">0.00</td>
218
+ <td data-label="Action"><button type="button" class="remove-item">Remove</button></td>
219
+ `;
220
+ itemsTableBody.appendChild(row);
221
+ updateSerialNumbers();
222
+ const inputs = row.querySelectorAll('input');
223
+ inputs.forEach(input => input.addEventListener('input', () => {
224
+ updateItemAmount(event);
225
+ updatePreview();
226
+ }));
227
+ row.querySelector('.remove-item').addEventListener('click', () => {
228
+ row.remove();
229
+ updateSerialNumbers();
230
+ updatePreview();
231
+ });
232
+ }
233
+
234
+ function updateItemAmount(e) {
235
+ const row = e.target.closest('tr');
236
+ if (!row) return;
237
+ const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
238
+ const price = parseFloat(row.querySelector('.item-price').value) || 0;
239
+ const discountRate = parseFloat(row.querySelector('.item-discount').value) || 0;
240
+ const discountAmount = qty * price * discountRate / 100;
241
+ const amount = qty * price - discountAmount;
242
+ row.querySelector('.item-amount').textContent = amount.toFixed(2);
243
+ }
244
+
245
+ addItemBtn.addEventListener('click', () => {
246
+ addItemRow();
247
+ updatePreview();
248
+ });
249
+
250
+ form.addEventListener('input', updatePreview);
251
+
252
+ form.addEventListener('submit', function (e) {
253
+ e.preventDefault();
254
+ const html = generateQuotationHTML(form);
255
  output.innerHTML = html;
256
  output.style.display = 'block';
257
  document.getElementById('form-container').style.display = 'none';
258
+ document.getElementById('preview-container').style.display = 'none';
259
+ document.getElementById('top-header').style.display = 'none';
260
  });
261
+
262
+ // Initial preview
263
+ updatePreview();
264
  });
265
  }
266