Spaces:
Sleeping
Sleeping
Commit
·
a40e4c4
1
Parent(s):
5e5606b
add data to localstorage
Browse files- data-manager.js +425 -0
- index.html +104 -6
data-manager.js
ADDED
@@ -0,0 +1,425 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class QuotationDataManager {
|
2 |
+
constructor() {
|
3 |
+
this.keys = {
|
4 |
+
company: "companyDetails",
|
5 |
+
bank: "bankDetails",
|
6 |
+
customer: "customerDetails",
|
7 |
+
};
|
8 |
+
}
|
9 |
+
|
10 |
+
// Save company details to localStorage
|
11 |
+
saveCompanyDetails(formData) {
|
12 |
+
const companyData = {
|
13 |
+
name: formData["company-name"] || "",
|
14 |
+
address: formData["company-address"] || "",
|
15 |
+
phone: formData["company-phone"] || "",
|
16 |
+
email: formData["company-email"] || "",
|
17 |
+
gstin: formData["company-gstin"] || "",
|
18 |
+
};
|
19 |
+
|
20 |
+
try {
|
21 |
+
localStorage.setItem(
|
22 |
+
this.keys.company,
|
23 |
+
JSON.stringify(companyData),
|
24 |
+
);
|
25 |
+
} catch (error) {
|
26 |
+
console.error("Error saving company details:", error);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
// Save bank details to localStorage
|
31 |
+
saveBankDetails(formData) {
|
32 |
+
const bankData = {
|
33 |
+
name: formData["bank-name"] || "",
|
34 |
+
account: formData["bank-account"] || "",
|
35 |
+
ifsc: formData["bank-ifsc"] || "",
|
36 |
+
branch: formData["bank-branch"] || "",
|
37 |
+
};
|
38 |
+
|
39 |
+
try {
|
40 |
+
localStorage.setItem(this.keys.bank, JSON.stringify(bankData));
|
41 |
+
} catch (error) {
|
42 |
+
console.error("Error saving bank details:", error);
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
// Save customer details to sessionStorage (temporary)
|
47 |
+
saveCustomerDetails(formData) {
|
48 |
+
const customerData = {
|
49 |
+
name: formData["customer-name"] || "",
|
50 |
+
address: formData["customer-address"] || "",
|
51 |
+
phone: formData["customer-phone"] || "",
|
52 |
+
email: formData["customer-email"] || "",
|
53 |
+
gstin: formData["customer-gstin"] || "",
|
54 |
+
};
|
55 |
+
|
56 |
+
try {
|
57 |
+
sessionStorage.setItem(
|
58 |
+
this.keys.customer,
|
59 |
+
JSON.stringify(customerData),
|
60 |
+
);
|
61 |
+
} catch (error) {
|
62 |
+
console.error("Error saving customer details:", error);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
// Load company details from localStorage
|
67 |
+
loadCompanyDetails() {
|
68 |
+
try {
|
69 |
+
const data = localStorage.getItem(this.keys.company);
|
70 |
+
return data ? JSON.parse(data) : null;
|
71 |
+
} catch (error) {
|
72 |
+
console.error("Error loading company details:", error);
|
73 |
+
return null;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
// Load bank details from localStorage
|
78 |
+
loadBankDetails() {
|
79 |
+
try {
|
80 |
+
const data = localStorage.getItem(this.keys.bank);
|
81 |
+
return data ? JSON.parse(data) : null;
|
82 |
+
} catch (error) {
|
83 |
+
console.error("Error loading bank details:", error);
|
84 |
+
return null;
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
// Load customer details from sessionStorage
|
89 |
+
loadCustomerDetails() {
|
90 |
+
try {
|
91 |
+
const data = sessionStorage.getItem(this.keys.customer);
|
92 |
+
return data ? JSON.parse(data) : null;
|
93 |
+
} catch (error) {
|
94 |
+
console.error("Error loading customer details:", error);
|
95 |
+
return null;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
// Clear all stored data
|
100 |
+
clearAllData() {
|
101 |
+
try {
|
102 |
+
localStorage.removeItem(this.keys.company);
|
103 |
+
localStorage.removeItem(this.keys.bank);
|
104 |
+
sessionStorage.removeItem(this.keys.customer);
|
105 |
+
} catch (error) {
|
106 |
+
console.error("Error clearing data:", error);
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
// Clear only customer data
|
111 |
+
clearCustomerData() {
|
112 |
+
try {
|
113 |
+
sessionStorage.removeItem(this.keys.customer);
|
114 |
+
} catch (error) {
|
115 |
+
console.error("Error clearing customer data:", error);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
// Load all saved form data into the form
|
120 |
+
loadFormData() {
|
121 |
+
// Load company details
|
122 |
+
const companyData = this.loadCompanyDetails();
|
123 |
+
if (companyData) {
|
124 |
+
document.getElementById("company-name").value =
|
125 |
+
companyData.name || "";
|
126 |
+
document.getElementById("company-address").value =
|
127 |
+
companyData.address || "";
|
128 |
+
document.getElementById("company-phone").value =
|
129 |
+
companyData.phone || "";
|
130 |
+
document.getElementById("company-email").value =
|
131 |
+
companyData.email || "";
|
132 |
+
document.getElementById("company-gstin").value =
|
133 |
+
companyData.gstin || "";
|
134 |
+
}
|
135 |
+
|
136 |
+
// Load bank details
|
137 |
+
const bankData = this.loadBankDetails();
|
138 |
+
if (bankData) {
|
139 |
+
document.getElementById("bank-name").value = bankData.name || "";
|
140 |
+
document.getElementById("bank-account").value =
|
141 |
+
bankData.account || "";
|
142 |
+
document.getElementById("bank-ifsc").value = bankData.ifsc || "";
|
143 |
+
document.getElementById("bank-branch").value =
|
144 |
+
bankData.branch || "";
|
145 |
+
}
|
146 |
+
|
147 |
+
// Load customer details
|
148 |
+
const customerData = this.loadCustomerDetails();
|
149 |
+
if (customerData) {
|
150 |
+
document.getElementById("customer-name").value =
|
151 |
+
customerData.name || "";
|
152 |
+
document.getElementById("customer-address").value =
|
153 |
+
customerData.address || "";
|
154 |
+
document.getElementById("customer-phone").value =
|
155 |
+
customerData.phone || "";
|
156 |
+
document.getElementById("customer-email").value =
|
157 |
+
customerData.email || "";
|
158 |
+
document.getElementById("customer-gstin").value =
|
159 |
+
customerData.gstin || "";
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
// Get form data as object
|
164 |
+
getFormData() {
|
165 |
+
const formData = new FormData(
|
166 |
+
document.getElementById("quotation-form"),
|
167 |
+
);
|
168 |
+
const data = {};
|
169 |
+
for (let [key, value] of formData.entries()) {
|
170 |
+
data[key] = value;
|
171 |
+
}
|
172 |
+
return data;
|
173 |
+
}
|
174 |
+
|
175 |
+
// Setup auto-save functionality
|
176 |
+
setupAutoSave() {
|
177 |
+
// Company fields auto-save
|
178 |
+
const companyFields = [
|
179 |
+
"company-name",
|
180 |
+
"company-address",
|
181 |
+
"company-phone",
|
182 |
+
"company-email",
|
183 |
+
"company-gstin",
|
184 |
+
];
|
185 |
+
companyFields.forEach((fieldId) => {
|
186 |
+
const field = document.getElementById(fieldId);
|
187 |
+
if (field) {
|
188 |
+
field.addEventListener("blur", () => {
|
189 |
+
const formData = this.getFormData();
|
190 |
+
this.saveCompanyDetails(formData);
|
191 |
+
this.updateStorageStatus();
|
192 |
+
});
|
193 |
+
}
|
194 |
+
});
|
195 |
+
|
196 |
+
// Bank fields auto-save
|
197 |
+
const bankFields = [
|
198 |
+
"bank-name",
|
199 |
+
"bank-account",
|
200 |
+
"bank-ifsc",
|
201 |
+
"bank-branch",
|
202 |
+
];
|
203 |
+
bankFields.forEach((fieldId) => {
|
204 |
+
const field = document.getElementById(fieldId);
|
205 |
+
if (field) {
|
206 |
+
field.addEventListener("blur", () => {
|
207 |
+
const formData = this.getFormData();
|
208 |
+
this.saveBankDetails(formData);
|
209 |
+
this.updateStorageStatus();
|
210 |
+
});
|
211 |
+
}
|
212 |
+
});
|
213 |
+
|
214 |
+
// Customer fields auto-save (to sessionStorage)
|
215 |
+
const customerFields = [
|
216 |
+
"customer-name",
|
217 |
+
"customer-address",
|
218 |
+
"customer-phone",
|
219 |
+
"customer-email",
|
220 |
+
"customer-gstin",
|
221 |
+
];
|
222 |
+
customerFields.forEach((fieldId) => {
|
223 |
+
const field = document.getElementById(fieldId);
|
224 |
+
if (field) {
|
225 |
+
field.addEventListener("blur", () => {
|
226 |
+
const formData = this.getFormData();
|
227 |
+
this.saveCustomerDetails(formData);
|
228 |
+
this.updateStorageStatus();
|
229 |
+
});
|
230 |
+
}
|
231 |
+
});
|
232 |
+
}
|
233 |
+
|
234 |
+
// Check if localStorage is available
|
235 |
+
isLocalStorageAvailable() {
|
236 |
+
try {
|
237 |
+
const test = "__localStorage_test__";
|
238 |
+
localStorage.setItem(test, test);
|
239 |
+
localStorage.removeItem(test);
|
240 |
+
return true;
|
241 |
+
} catch (_error) {
|
242 |
+
return false;
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
// Show status modal
|
247 |
+
showModal(message, type = "info") {
|
248 |
+
const modal = document.getElementById("status-modal");
|
249 |
+
const modalMessage = document.getElementById("modal-message");
|
250 |
+
|
251 |
+
modalMessage.innerHTML = `<p class="text-${type === "error" ? "red" : "green"}-600">${message}</p>`;
|
252 |
+
modal.classList.remove("hidden");
|
253 |
+
modal.classList.add("flex");
|
254 |
+
}
|
255 |
+
|
256 |
+
// Hide status modal
|
257 |
+
hideModal() {
|
258 |
+
const modal = document.getElementById("status-modal");
|
259 |
+
modal.classList.add("hidden");
|
260 |
+
modal.classList.remove("flex");
|
261 |
+
}
|
262 |
+
|
263 |
+
// Setup event handlers for data management buttons
|
264 |
+
setupDataManagementHandlers() {
|
265 |
+
// Save data button
|
266 |
+
const saveButton = document.getElementById("save-data");
|
267 |
+
if (saveButton) {
|
268 |
+
saveButton.addEventListener("click", () => {
|
269 |
+
try {
|
270 |
+
const formData = this.getFormData();
|
271 |
+
this.saveCompanyDetails(formData);
|
272 |
+
this.saveBankDetails(formData);
|
273 |
+
this.saveCustomerDetails(formData);
|
274 |
+
this.updateStorageStatus();
|
275 |
+
this.showModal("✅ Data saved successfully!", "success");
|
276 |
+
} catch (error) {
|
277 |
+
console.error("Error saving data:", error);
|
278 |
+
this.showModal(
|
279 |
+
"❌ Error saving data. Please try again.",
|
280 |
+
"error",
|
281 |
+
);
|
282 |
+
}
|
283 |
+
});
|
284 |
+
}
|
285 |
+
|
286 |
+
// Clear data button
|
287 |
+
const clearButton = document.getElementById("clear-data");
|
288 |
+
if (clearButton) {
|
289 |
+
clearButton.addEventListener("click", () => {
|
290 |
+
if (
|
291 |
+
confirm(
|
292 |
+
"Are you sure you want to clear all saved data? This cannot be undone.",
|
293 |
+
)
|
294 |
+
) {
|
295 |
+
try {
|
296 |
+
this.clearAllData();
|
297 |
+
// Clear form fields
|
298 |
+
document.getElementById("quotation-form").reset();
|
299 |
+
this.updateStorageStatus();
|
300 |
+
this.showModal(
|
301 |
+
"🗑️ All saved data cleared successfully!",
|
302 |
+
"success",
|
303 |
+
);
|
304 |
+
} catch (error) {
|
305 |
+
console.error("Error clearing data:", error);
|
306 |
+
this.showModal(
|
307 |
+
"❌ Error clearing data. Please try again.",
|
308 |
+
"error",
|
309 |
+
);
|
310 |
+
}
|
311 |
+
}
|
312 |
+
});
|
313 |
+
}
|
314 |
+
|
315 |
+
// Modal close button
|
316 |
+
const modalCloseButton = document.getElementById("modal-close");
|
317 |
+
if (modalCloseButton) {
|
318 |
+
modalCloseButton.addEventListener("click", () => {
|
319 |
+
this.hideModal();
|
320 |
+
});
|
321 |
+
}
|
322 |
+
|
323 |
+
// Close modal when clicking outside
|
324 |
+
const modal = document.getElementById("status-modal");
|
325 |
+
if (modal) {
|
326 |
+
modal.addEventListener("click", (e) => {
|
327 |
+
if (e.target === modal) {
|
328 |
+
this.hideModal();
|
329 |
+
}
|
330 |
+
});
|
331 |
+
}
|
332 |
+
|
333 |
+
// Storage info panel handlers
|
334 |
+
const showStorageInfoButton =
|
335 |
+
document.getElementById("show-storage-info");
|
336 |
+
const hideStorageInfoButton =
|
337 |
+
document.getElementById("hide-storage-info");
|
338 |
+
const storageInfoPanel = document.getElementById("storage-info-panel");
|
339 |
+
|
340 |
+
if (showStorageInfoButton && storageInfoPanel) {
|
341 |
+
showStorageInfoButton.addEventListener("click", () => {
|
342 |
+
this.updateStorageStatus();
|
343 |
+
storageInfoPanel.classList.remove("hidden");
|
344 |
+
});
|
345 |
+
}
|
346 |
+
|
347 |
+
if (hideStorageInfoButton && storageInfoPanel) {
|
348 |
+
hideStorageInfoButton.addEventListener("click", () => {
|
349 |
+
storageInfoPanel.classList.add("hidden");
|
350 |
+
});
|
351 |
+
}
|
352 |
+
}
|
353 |
+
|
354 |
+
// Update storage status display
|
355 |
+
updateStorageStatus() {
|
356 |
+
const companyData = this.loadCompanyDetails();
|
357 |
+
const bankData = this.loadBankDetails();
|
358 |
+
const customerData = this.loadCustomerDetails();
|
359 |
+
|
360 |
+
// Update company status
|
361 |
+
const companyStatus = document.getElementById("company-storage-status");
|
362 |
+
if (companyStatus) {
|
363 |
+
if (companyData && companyData.name) {
|
364 |
+
companyStatus.textContent = `✅ Saved (${companyData.name})`;
|
365 |
+
companyStatus.className = "text-blue-600";
|
366 |
+
} else {
|
367 |
+
companyStatus.textContent = "❌ Not saved";
|
368 |
+
companyStatus.className = "text-gray-600";
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
// Update bank status
|
373 |
+
const bankStatus = document.getElementById("bank-storage-status");
|
374 |
+
if (bankStatus) {
|
375 |
+
if (bankData && bankData.name) {
|
376 |
+
bankStatus.textContent = `✅ Saved (${bankData.name})`;
|
377 |
+
bankStatus.className = "text-green-600";
|
378 |
+
} else {
|
379 |
+
bankStatus.textContent = "❌ Not saved";
|
380 |
+
bankStatus.className = "text-gray-600";
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
+
// Update customer status
|
385 |
+
const customerStatus = document.getElementById(
|
386 |
+
"customer-storage-status",
|
387 |
+
);
|
388 |
+
if (customerStatus) {
|
389 |
+
if (customerData && customerData.name) {
|
390 |
+
customerStatus.textContent = `✅ Saved in session (${customerData.name})`;
|
391 |
+
customerStatus.className = "text-yellow-600";
|
392 |
+
} else {
|
393 |
+
customerStatus.textContent = "❌ Not saved (Session only)";
|
394 |
+
customerStatus.className = "text-gray-600";
|
395 |
+
}
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
// Initialize data manager
|
400 |
+
init() {
|
401 |
+
if (!this.isLocalStorageAvailable()) {
|
402 |
+
console.warn(
|
403 |
+
"localStorage is not available. Data will not be saved.",
|
404 |
+
);
|
405 |
+
return;
|
406 |
+
}
|
407 |
+
|
408 |
+
// Load existing data when page loads
|
409 |
+
document.addEventListener("DOMContentLoaded", () => {
|
410 |
+
this.loadFormData();
|
411 |
+
this.setupAutoSave();
|
412 |
+
this.setupDataManagementHandlers();
|
413 |
+
this.updateStorageStatus();
|
414 |
+
});
|
415 |
+
|
416 |
+
// Clear customer data when page unloads (optional)
|
417 |
+
window.addEventListener("beforeunload", () => {
|
418 |
+
this.clearCustomerData();
|
419 |
+
});
|
420 |
+
}
|
421 |
+
}
|
422 |
+
|
423 |
+
// Initialize the data manager
|
424 |
+
const dataManager = new QuotationDataManager();
|
425 |
+
dataManager.init();
|
index.html
CHANGED
@@ -251,12 +251,30 @@
|
|
251 |
class="w-full p-2 border border-gray-300 rounded"
|
252 |
/>
|
253 |
</fieldset>
|
254 |
-
<
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
</form>
|
261 |
</div>
|
262 |
<div id="preview-container" class="w-1/2 pl-4">
|
@@ -269,9 +287,89 @@
|
|
269 |
</h2>
|
270 |
<div id="preview-content"></div>
|
271 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
</div>
|
273 |
</div>
|
274 |
<div id="quotation-output" style="display: none"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
<script src="script.js"></script>
|
276 |
</body>
|
277 |
</html>
|
|
|
251 |
class="w-full p-2 border border-gray-300 rounded"
|
252 |
/>
|
253 |
</fieldset>
|
254 |
+
<div class="flex justify-between items-center">
|
255 |
+
<button
|
256 |
+
type="submit"
|
257 |
+
class="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded"
|
258 |
+
>
|
259 |
+
Generate Quotation
|
260 |
+
</button>
|
261 |
+
<div class="space-x-2">
|
262 |
+
<button
|
263 |
+
type="button"
|
264 |
+
id="clear-data"
|
265 |
+
class="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded"
|
266 |
+
>
|
267 |
+
Clear Saved Data
|
268 |
+
</button>
|
269 |
+
<button
|
270 |
+
type="button"
|
271 |
+
id="show-storage-info"
|
272 |
+
class="bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded"
|
273 |
+
>
|
274 |
+
Storage Info
|
275 |
+
</button>
|
276 |
+
</div>
|
277 |
+
</div>
|
278 |
</form>
|
279 |
</div>
|
280 |
<div id="preview-container" class="w-1/2 pl-4">
|
|
|
287 |
</h2>
|
288 |
<div id="preview-content"></div>
|
289 |
</div>
|
290 |
+
|
291 |
+
<!-- Storage Information Panel -->
|
292 |
+
<div
|
293 |
+
id="storage-info-panel"
|
294 |
+
class="bg-white shadow-md rounded px-6 pt-4 pb-6 mb-4 hidden"
|
295 |
+
>
|
296 |
+
<h3 class="text-lg font-bold mb-3">
|
297 |
+
💾 Storage Information
|
298 |
+
</h3>
|
299 |
+
<div class="text-sm space-y-2">
|
300 |
+
<div class="bg-blue-50 p-3 rounded">
|
301 |
+
<h4 class="font-semibold text-blue-800">
|
302 |
+
Company Details
|
303 |
+
</h4>
|
304 |
+
<p
|
305 |
+
id="company-storage-status"
|
306 |
+
class="text-blue-600"
|
307 |
+
>
|
308 |
+
Not saved
|
309 |
+
</p>
|
310 |
+
</div>
|
311 |
+
<div class="bg-green-50 p-3 rounded">
|
312 |
+
<h4 class="font-semibold text-green-800">
|
313 |
+
Bank Details
|
314 |
+
</h4>
|
315 |
+
<p id="bank-storage-status" class="text-green-600">
|
316 |
+
Not saved
|
317 |
+
</p>
|
318 |
+
</div>
|
319 |
+
<div class="bg-yellow-50 p-3 rounded">
|
320 |
+
<h4 class="font-semibold text-yellow-800">
|
321 |
+
Customer Details
|
322 |
+
</h4>
|
323 |
+
<p
|
324 |
+
id="customer-storage-status"
|
325 |
+
class="text-yellow-600"
|
326 |
+
>
|
327 |
+
Not saved (Session only)
|
328 |
+
</p>
|
329 |
+
</div>
|
330 |
+
<div class="bg-gray-50 p-3 rounded mt-3">
|
331 |
+
<h4 class="font-semibold text-gray-800">
|
332 |
+
⚠️ Security Notice
|
333 |
+
</h4>
|
334 |
+
<p class="text-gray-600 text-xs">
|
335 |
+
Data is stored in your browser's localStorage.
|
336 |
+
For maximum security:
|
337 |
+
<br />• Use private/incognito browsing <br />•
|
338 |
+
Clear data when done <br />• Don't use on shared
|
339 |
+
computers
|
340 |
+
</p>
|
341 |
+
</div>
|
342 |
+
</div>
|
343 |
+
<button
|
344 |
+
id="hide-storage-info"
|
345 |
+
class="mt-4 bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded-lg shadow-md transition-all duration-200 ease-in-out transform hover:scale-105"
|
346 |
+
>
|
347 |
+
Hide
|
348 |
+
</button>
|
349 |
+
</div>
|
350 |
</div>
|
351 |
</div>
|
352 |
<div id="quotation-output" style="display: none"></div>
|
353 |
+
|
354 |
+
<!-- Data Management Status Modal -->
|
355 |
+
<div
|
356 |
+
id="status-modal"
|
357 |
+
class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden items-center justify-center"
|
358 |
+
>
|
359 |
+
<div class="bg-white p-6 rounded-lg shadow-lg max-w-sm mx-auto">
|
360 |
+
<div id="modal-content" class="text-center">
|
361 |
+
<div id="modal-message" class="mb-4"></div>
|
362 |
+
<button
|
363 |
+
id="modal-close"
|
364 |
+
class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg shadow-md transition-all duration-200 ease-in-out transform hover:scale-105"
|
365 |
+
>
|
366 |
+
OK
|
367 |
+
</button>
|
368 |
+
</div>
|
369 |
+
</div>
|
370 |
+
</div>
|
371 |
+
|
372 |
+
<script src="data-manager.js"></script>
|
373 |
<script src="script.js"></script>
|
374 |
</body>
|
375 |
</html>
|