appscms-tools-theme 5.1.8 → 5.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/_data/.DS_Store +0 -0
- data/_data/aitools/en/ai-article-writer.json +184 -0
- data/_data/aitools/en/amazon-product-bullet-points-generator.json +222 -0
- data/_data/aitools/en/amazon-product-description-generator.json +222 -0
- data/_data/aitools/en/brand-name-generator.json +215 -0
- data/_data/aitools/en/product-description.json +222 -0
- data/_includes/.DS_Store +0 -0
- data/_includes/aitools/ai-article-writer.html +0 -0
- data/_includes/aitools/amazon-product-bullet-points-generator.html +0 -0
- data/_includes/aitools/amazon-product-description-generator.html +0 -0
- data/_includes/aitools/brand-name-generator.html +0 -0
- data/_includes/aitools/product-description.html +0 -0
- data/_includes/appscms/.DS_Store +0 -0
- data/_includes/appscms/customblog/pageRelatedPosts.html +1 -1
- data/_layouts/content-tool-ai copy 2.html +6611 -0
- data/_layouts/content-tool-ai.html +403 -24
- data/assets/.DS_Store +0 -0
- data/assets/css/content-tool-ai.css +776 -2
- data/assets/js/ai-article-writer.js +0 -0
- data/assets/js/amazon-product-bullet-points-generator.js +464 -0
- data/assets/js/amazon-product-bullet-points-generator3.js +176 -0
- data/assets/js/amazon-product-description-generator.js +309 -0
- data/assets/js/brand-name-generator.js +127 -0
- data/assets/js/product-description.js +299 -0
- metadata +19 -2
File without changes
|
@@ -0,0 +1,464 @@
|
|
1
|
+
// Auto-generated JS for Amazon Product Bullet Points Generator
|
2
|
+
document.addEventListener("DOMContentLoaded", function () {
|
3
|
+
const form = document.getElementById("contentToolForm");
|
4
|
+
const tool = "amazon_product_bullet_points_generator";
|
5
|
+
|
6
|
+
// Wait for Quill to be initialized
|
7
|
+
let quill;
|
8
|
+
const checkQuill = setInterval(() => {
|
9
|
+
if (window.quill) {
|
10
|
+
quill = window.quill;
|
11
|
+
clearInterval(checkQuill);
|
12
|
+
}
|
13
|
+
}, 100);
|
14
|
+
|
15
|
+
let input0 = form.querySelector('[name="input0"]');
|
16
|
+
let input1 = form.querySelector('[name="input1"]');
|
17
|
+
let language = form.querySelector('[name="language"]');
|
18
|
+
let tone = form.querySelector('[name="tone"]');
|
19
|
+
|
20
|
+
// Add copy button functionality
|
21
|
+
function addCopyButton() {
|
22
|
+
const editorContainer = document.querySelector("#editor").parentElement;
|
23
|
+
|
24
|
+
// Check if copy button already exists
|
25
|
+
if (document.querySelector("#copyButton")) return;
|
26
|
+
|
27
|
+
const copyButtonContainer = document.createElement("div");
|
28
|
+
copyButtonContainer.className =
|
29
|
+
"d-flex justify-content-between align-items-center mb-2";
|
30
|
+
copyButtonContainer.innerHTML = `
|
31
|
+
<h5 class="mb-0">Generated Content</h5>
|
32
|
+
<button type="button" id="copyButton" class="btn btn-outline-primary btn-sm">
|
33
|
+
<i class="fas fa-copy me-1"></i> Copy
|
34
|
+
</button>
|
35
|
+
`;
|
36
|
+
|
37
|
+
editorContainer.insertBefore(
|
38
|
+
copyButtonContainer,
|
39
|
+
document.querySelector("#editor")
|
40
|
+
);
|
41
|
+
|
42
|
+
// Add copy functionality
|
43
|
+
document
|
44
|
+
.getElementById("copyButton")
|
45
|
+
.addEventListener("click", function () {
|
46
|
+
const content = quill.getText();
|
47
|
+
|
48
|
+
if (navigator.clipboard && window.isSecureContext) {
|
49
|
+
navigator.clipboard
|
50
|
+
.writeText(content)
|
51
|
+
.then(() => {
|
52
|
+
showCopySuccess();
|
53
|
+
})
|
54
|
+
.catch((err) => {
|
55
|
+
console.error("Failed to copy: ", err);
|
56
|
+
fallbackCopyTextToClipboard(content);
|
57
|
+
});
|
58
|
+
} else {
|
59
|
+
fallbackCopyTextToClipboard(content);
|
60
|
+
}
|
61
|
+
});
|
62
|
+
}
|
63
|
+
|
64
|
+
// Fallback copy method for older browsers
|
65
|
+
function fallbackCopyTextToClipboard(text) {
|
66
|
+
const textArea = document.createElement("textarea");
|
67
|
+
textArea.value = text;
|
68
|
+
textArea.style.position = "fixed";
|
69
|
+
textArea.style.top = "-9999px";
|
70
|
+
textArea.style.left = "-9999px";
|
71
|
+
document.body.appendChild(textArea);
|
72
|
+
textArea.focus();
|
73
|
+
textArea.select();
|
74
|
+
|
75
|
+
try {
|
76
|
+
document.execCommand("copy");
|
77
|
+
showCopySuccess();
|
78
|
+
} catch (err) {
|
79
|
+
console.error("Fallback: Oops, unable to copy", err);
|
80
|
+
}
|
81
|
+
|
82
|
+
document.body.removeChild(textArea);
|
83
|
+
}
|
84
|
+
|
85
|
+
// Show copy success message
|
86
|
+
function showCopySuccess() {
|
87
|
+
const button = document.getElementById("copyButton");
|
88
|
+
const originalHTML = button.innerHTML;
|
89
|
+
button.innerHTML = '<i class="fas fa-check me-1"></i> Copied!';
|
90
|
+
button.classList.remove("btn-outline-primary");
|
91
|
+
button.classList.add("btn-success");
|
92
|
+
|
93
|
+
setTimeout(() => {
|
94
|
+
button.innerHTML = originalHTML;
|
95
|
+
button.classList.remove("btn-success");
|
96
|
+
button.classList.add("btn-outline-primary");
|
97
|
+
}, 2000);
|
98
|
+
}
|
99
|
+
|
100
|
+
// Get Firebase auth token
|
101
|
+
async function getAuthToken() {
|
102
|
+
return new Promise((resolve) => {
|
103
|
+
// Check if Firebase auth is available
|
104
|
+
if (typeof firebase !== "undefined" && firebase.auth) {
|
105
|
+
const user = firebase.auth().currentUser;
|
106
|
+
if (user) {
|
107
|
+
user
|
108
|
+
.getIdToken()
|
109
|
+
.then((token) => {
|
110
|
+
resolve(token);
|
111
|
+
})
|
112
|
+
.catch((error) => {
|
113
|
+
console.warn("Failed to get auth token:", error);
|
114
|
+
resolve(null);
|
115
|
+
});
|
116
|
+
} else {
|
117
|
+
console.warn("User not logged in");
|
118
|
+
resolve(null);
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
// Fallback: try to get token from localStorage or other methods
|
122
|
+
const token =
|
123
|
+
localStorage.getItem("authToken") ||
|
124
|
+
sessionStorage.getItem("authToken") ||
|
125
|
+
getCookie("authToken");
|
126
|
+
resolve(token);
|
127
|
+
}
|
128
|
+
});
|
129
|
+
}
|
130
|
+
|
131
|
+
// Helper function to get cookie
|
132
|
+
function getCookie(name) {
|
133
|
+
const value = `; ${document.cookie}`;
|
134
|
+
const parts = value.split(`; ${name}=`);
|
135
|
+
if (parts.length === 2) return parts.pop().split(";").shift();
|
136
|
+
return null;
|
137
|
+
}
|
138
|
+
|
139
|
+
form.addEventListener("submit", async function (e) {
|
140
|
+
e.preventDefault();
|
141
|
+
|
142
|
+
// Check if Quill is available
|
143
|
+
if (!quill) {
|
144
|
+
console.error("Quill editor not found");
|
145
|
+
return;
|
146
|
+
}
|
147
|
+
|
148
|
+
// Show loading state
|
149
|
+
const submitButton = form.querySelector('button[type="submit"]');
|
150
|
+
const originalText = submitButton ? submitButton.textContent : "";
|
151
|
+
if (submitButton) {
|
152
|
+
submitButton.textContent = "Generating...";
|
153
|
+
submitButton.disabled = true;
|
154
|
+
}
|
155
|
+
|
156
|
+
const options = {};
|
157
|
+
options["product_name"] = input0.value;
|
158
|
+
options["detials_product_features"] = input1.value;
|
159
|
+
options["language"] = language.value;
|
160
|
+
options["tone"] = tone.value;
|
161
|
+
|
162
|
+
// Get authentication token
|
163
|
+
const authToken = await getAuthToken();
|
164
|
+
|
165
|
+
const body = {
|
166
|
+
tool: tool,
|
167
|
+
llm: "gemini",
|
168
|
+
model_name: "gemini-2.0-flash",
|
169
|
+
options: options,
|
170
|
+
};
|
171
|
+
|
172
|
+
// Prepare headers
|
173
|
+
const headers = {
|
174
|
+
"Content-Type": "application/json",
|
175
|
+
};
|
176
|
+
|
177
|
+
// Add auth token if available
|
178
|
+
if (authToken) {
|
179
|
+
headers["Authorization"] = `Bearer ${authToken}`;
|
180
|
+
// Alternative header formats in case your backend expects different format
|
181
|
+
// headers["X-Auth-Token"] = authToken;
|
182
|
+
// headers["Firebase-Token"] = authToken;
|
183
|
+
}
|
184
|
+
console.log(headers);
|
185
|
+
console.log(body);
|
186
|
+
console.log(JSON.stringify(body));
|
187
|
+
try {
|
188
|
+
const response = await fetch(
|
189
|
+
"http://localhost:8000/api/v1/ecommerce-tools/amazon-product-bullet-points-generator",
|
190
|
+
{
|
191
|
+
method: "POST",
|
192
|
+
headers: headers,
|
193
|
+
body: JSON.stringify(body),
|
194
|
+
}
|
195
|
+
);
|
196
|
+
|
197
|
+
// Handle different response status codes
|
198
|
+
if (response.status === 401) {
|
199
|
+
throw new Error("Authentication required. Please log in to continue.");
|
200
|
+
} else if (response.status === 403) {
|
201
|
+
throw new Error("Access denied. Please check your permissions.");
|
202
|
+
} else if (!response.ok) {
|
203
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
204
|
+
}
|
205
|
+
|
206
|
+
const data = await response.json();
|
207
|
+
|
208
|
+
if (data.result) {
|
209
|
+
// Clear the editor first
|
210
|
+
quill.setText("");
|
211
|
+
|
212
|
+
// Parse and render markdown content
|
213
|
+
renderMarkdownToQuill(data.result, quill);
|
214
|
+
|
215
|
+
// Add copy button after content is generated
|
216
|
+
addCopyButton();
|
217
|
+
|
218
|
+
console.log("✅ Content generated successfully");
|
219
|
+
} else {
|
220
|
+
quill.setText("No output received from server.");
|
221
|
+
}
|
222
|
+
} catch (err) {
|
223
|
+
console.error("❌ API Error:", err);
|
224
|
+
|
225
|
+
// Show user-friendly error messages
|
226
|
+
let errorMessage = "Error: " + err.message;
|
227
|
+
if (err.message.includes("Authentication")) {
|
228
|
+
errorMessage = "Please log in to generate content.";
|
229
|
+
} else if (err.message.includes("Network")) {
|
230
|
+
errorMessage = "Network error. Please check your connection.";
|
231
|
+
}
|
232
|
+
|
233
|
+
quill.setText(errorMessage);
|
234
|
+
} finally {
|
235
|
+
// Reset button state
|
236
|
+
if (submitButton) {
|
237
|
+
submitButton.textContent = originalText;
|
238
|
+
submitButton.disabled = false;
|
239
|
+
}
|
240
|
+
}
|
241
|
+
});
|
242
|
+
});
|
243
|
+
|
244
|
+
// Function to render markdown content to Quill editor
|
245
|
+
function renderMarkdownToQuill(markdownText, quill) {
|
246
|
+
// Clear editor
|
247
|
+
quill.setText("");
|
248
|
+
|
249
|
+
let index = 0;
|
250
|
+
const lines = markdownText.split("\n");
|
251
|
+
|
252
|
+
lines.forEach((line, lineIndex) => {
|
253
|
+
if (line.trim() === "") {
|
254
|
+
// Empty line - add line break
|
255
|
+
if (lineIndex < lines.length - 1) {
|
256
|
+
quill.insertText(index, "\n");
|
257
|
+
index += 1;
|
258
|
+
}
|
259
|
+
return;
|
260
|
+
}
|
261
|
+
|
262
|
+
// Handle different markdown patterns
|
263
|
+
if (line.startsWith("**") && line.endsWith("**") && line.length > 4) {
|
264
|
+
// Bold text (like **Product Title:** or **Key Features:**)
|
265
|
+
const text = line.replace(/^\*\*(.*?)\*\*$/, "$1");
|
266
|
+
quill.insertText(index, text, { bold: true });
|
267
|
+
index += text.length;
|
268
|
+
} else if (line.includes("**")) {
|
269
|
+
// Mixed bold and normal text (like **Product Title:** Coffee Mug)
|
270
|
+
const parts = line.split("**");
|
271
|
+
for (let i = 0; i < parts.length; i++) {
|
272
|
+
if (parts[i]) {
|
273
|
+
if (i % 2 === 1) {
|
274
|
+
// Odd index = bold text
|
275
|
+
quill.insertText(index, parts[i], { bold: true });
|
276
|
+
index += parts[i].length;
|
277
|
+
} else {
|
278
|
+
// Even index = normal text
|
279
|
+
quill.insertText(index, parts[i]);
|
280
|
+
index += parts[i].length;
|
281
|
+
}
|
282
|
+
}
|
283
|
+
}
|
284
|
+
} else if (line.startsWith("- ")) {
|
285
|
+
// Bullet points
|
286
|
+
const text = line.substring(2); // Remove '- '
|
287
|
+
quill.insertText(index, "• " + text);
|
288
|
+
index += text.length + 2;
|
289
|
+
} else if (line.match(/^\d+\.\s/)) {
|
290
|
+
// Numbered lists
|
291
|
+
const match = line.match(/^(\d+\.\s)(.*)$/);
|
292
|
+
if (match) {
|
293
|
+
const number = match[1];
|
294
|
+
const content = match[2];
|
295
|
+
|
296
|
+
// Insert number in bold
|
297
|
+
quill.insertText(index, number, { bold: true });
|
298
|
+
index += number.length;
|
299
|
+
|
300
|
+
// Insert content in normal text
|
301
|
+
quill.insertText(index, content);
|
302
|
+
index += content.length;
|
303
|
+
} else {
|
304
|
+
quill.insertText(index, line);
|
305
|
+
index += line.length;
|
306
|
+
}
|
307
|
+
} else if (line.startsWith("### ")) {
|
308
|
+
// Headers (H3)
|
309
|
+
const text = line.substring(4);
|
310
|
+
quill.insertText(index, text, { bold: true });
|
311
|
+
index += text.length;
|
312
|
+
} else if (line.startsWith("## ")) {
|
313
|
+
// Headers (H2)
|
314
|
+
const text = line.substring(3);
|
315
|
+
quill.insertText(index, text, { bold: true, size: "large" });
|
316
|
+
index += text.length;
|
317
|
+
} else if (line.startsWith("# ")) {
|
318
|
+
// Headers (H1)
|
319
|
+
const text = line.substring(2);
|
320
|
+
quill.insertText(index, text, { bold: true, size: "huge" });
|
321
|
+
index += text.length;
|
322
|
+
} else if (line.startsWith("*") && line.endsWith("*") && line.length > 2) {
|
323
|
+
// Italic text
|
324
|
+
const text = line.replace(/^\*(.*?)\*$/, "$1");
|
325
|
+
quill.insertText(index, text, { italic: true });
|
326
|
+
index += text.length;
|
327
|
+
} else {
|
328
|
+
// Normal text
|
329
|
+
quill.insertText(index, line);
|
330
|
+
index += line.length;
|
331
|
+
}
|
332
|
+
|
333
|
+
// Add line break if not the last line
|
334
|
+
if (lineIndex < lines.length - 1) {
|
335
|
+
quill.insertText(index, "\n");
|
336
|
+
index += 1;
|
337
|
+
}
|
338
|
+
});
|
339
|
+
}
|
340
|
+
|
341
|
+
// Alternative function using marked.js if available
|
342
|
+
function renderMarkdownToQuillWithMarked(markdownText, quill) {
|
343
|
+
if (typeof marked !== "undefined") {
|
344
|
+
try {
|
345
|
+
// Convert markdown to HTML
|
346
|
+
const html = marked.parse(markdownText);
|
347
|
+
|
348
|
+
// Create a temporary div to parse HTML
|
349
|
+
const tempDiv = document.createElement("div");
|
350
|
+
tempDiv.innerHTML = html;
|
351
|
+
|
352
|
+
// Clear editor
|
353
|
+
quill.setText("");
|
354
|
+
|
355
|
+
let index = 0;
|
356
|
+
|
357
|
+
// Process each child element
|
358
|
+
tempDiv.childNodes.forEach((node) => {
|
359
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
360
|
+
const text = node.textContent.trim();
|
361
|
+
if (text) {
|
362
|
+
quill.insertText(index, text);
|
363
|
+
index += text.length;
|
364
|
+
}
|
365
|
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
366
|
+
switch (node.tagName.toLowerCase()) {
|
367
|
+
case "h1":
|
368
|
+
quill.insertText(index, node.textContent, {
|
369
|
+
bold: true,
|
370
|
+
size: "huge",
|
371
|
+
});
|
372
|
+
index += node.textContent.length;
|
373
|
+
break;
|
374
|
+
case "h2":
|
375
|
+
quill.insertText(index, node.textContent, {
|
376
|
+
bold: true,
|
377
|
+
size: "large",
|
378
|
+
});
|
379
|
+
index += node.textContent.length;
|
380
|
+
break;
|
381
|
+
case "h3":
|
382
|
+
case "h4":
|
383
|
+
case "h5":
|
384
|
+
case "h6":
|
385
|
+
quill.insertText(index, node.textContent, { bold: true });
|
386
|
+
index += node.textContent.length;
|
387
|
+
break;
|
388
|
+
case "strong":
|
389
|
+
case "b":
|
390
|
+
quill.insertText(index, node.textContent, { bold: true });
|
391
|
+
index += node.textContent.length;
|
392
|
+
break;
|
393
|
+
case "em":
|
394
|
+
case "i":
|
395
|
+
quill.insertText(index, node.textContent, { italic: true });
|
396
|
+
index += node.textContent.length;
|
397
|
+
break;
|
398
|
+
case "ul":
|
399
|
+
node.querySelectorAll("li").forEach((li) => {
|
400
|
+
quill.insertText(index, "• " + li.textContent + "\n");
|
401
|
+
index += li.textContent.length + 3;
|
402
|
+
});
|
403
|
+
break;
|
404
|
+
case "ol":
|
405
|
+
node.querySelectorAll("li").forEach((li, i) => {
|
406
|
+
const number = `${i + 1}. `;
|
407
|
+
quill.insertText(index, number, { bold: true });
|
408
|
+
index += number.length;
|
409
|
+
quill.insertText(index, li.textContent + "\n");
|
410
|
+
index += li.textContent.length + 1;
|
411
|
+
});
|
412
|
+
break;
|
413
|
+
case "p":
|
414
|
+
const pText = node.textContent.trim();
|
415
|
+
if (pText) {
|
416
|
+
quill.insertText(index, pText + "\n");
|
417
|
+
index += pText.length + 1;
|
418
|
+
}
|
419
|
+
break;
|
420
|
+
case "br":
|
421
|
+
quill.insertText(index, "\n");
|
422
|
+
index += 1;
|
423
|
+
break;
|
424
|
+
default:
|
425
|
+
const defaultText = node.textContent.trim();
|
426
|
+
if (defaultText) {
|
427
|
+
quill.insertText(index, defaultText);
|
428
|
+
index += defaultText.length;
|
429
|
+
}
|
430
|
+
}
|
431
|
+
}
|
432
|
+
});
|
433
|
+
|
434
|
+
// Add final formatting cleanup
|
435
|
+
if (index > 0) {
|
436
|
+
quill.insertText(index, "\n");
|
437
|
+
}
|
438
|
+
} catch (error) {
|
439
|
+
console.error("Error parsing markdown with marked.js:", error);
|
440
|
+
// Fallback to basic markdown parsing
|
441
|
+
renderMarkdownToQuill(markdownText, quill);
|
442
|
+
}
|
443
|
+
} else {
|
444
|
+
// Fallback to basic markdown parsing
|
445
|
+
renderMarkdownToQuill(markdownText, quill);
|
446
|
+
}
|
447
|
+
}
|
448
|
+
|
449
|
+
// Enhanced function that tries marked.js first, then falls back to basic parsing
|
450
|
+
function renderContentToQuill(content, quill) {
|
451
|
+
// Try to detect if content is markdown
|
452
|
+
const hasMarkdownPatterns = /\*\*|\*|#{1,6}\s|^\s*[-*+]\s|^\s*\d+\.\s/m.test(
|
453
|
+
content
|
454
|
+
);
|
455
|
+
|
456
|
+
if (hasMarkdownPatterns && typeof marked !== "undefined") {
|
457
|
+
renderMarkdownToQuillWithMarked(content, quill);
|
458
|
+
} else if (hasMarkdownPatterns) {
|
459
|
+
renderMarkdownToQuill(content, quill);
|
460
|
+
} else {
|
461
|
+
// Plain text
|
462
|
+
quill.setText(content);
|
463
|
+
}
|
464
|
+
}
|
@@ -0,0 +1,176 @@
|
|
1
|
+
// Auto-generated JS for Amazon Product Bullet Points Generator
|
2
|
+
document.addEventListener("DOMContentLoaded", function () {
|
3
|
+
const form = document.getElementById("contentToolForm");
|
4
|
+
const tool = "amazon_product_bullet_points_generator";
|
5
|
+
|
6
|
+
let quill;
|
7
|
+
const checkQuill = setInterval(() => {
|
8
|
+
if (window.quill) {
|
9
|
+
quill = window.quill;
|
10
|
+
clearInterval(checkQuill);
|
11
|
+
}
|
12
|
+
}, 100);
|
13
|
+
|
14
|
+
const input0 = form.querySelector('[name="input0"]');
|
15
|
+
const input1 = form.querySelector('[name="input1"]');
|
16
|
+
const language = form.querySelector('[name="language"]');
|
17
|
+
const tone = form.querySelector('[name="tone"]');
|
18
|
+
|
19
|
+
function addCopyButton() {
|
20
|
+
const editorContainer = document.querySelector("#editor").parentElement;
|
21
|
+
if (document.querySelector("#copyButton")) return;
|
22
|
+
|
23
|
+
const copyButtonContainer = document.createElement("div");
|
24
|
+
copyButtonContainer.className =
|
25
|
+
"d-flex justify-content-between align-items-center mb-2";
|
26
|
+
copyButtonContainer.innerHTML = `
|
27
|
+
<h5 class="mb-0">Generated Content</h5>
|
28
|
+
<button type="button" id="copyButton" class="btn btn-outline-primary btn-sm">
|
29
|
+
<i class="fas fa-copy me-1"></i> Copy
|
30
|
+
</button>
|
31
|
+
`;
|
32
|
+
editorContainer.insertBefore(
|
33
|
+
copyButtonContainer,
|
34
|
+
document.querySelector("#editor")
|
35
|
+
);
|
36
|
+
|
37
|
+
document
|
38
|
+
.getElementById("copyButton")
|
39
|
+
.addEventListener("click", function () {
|
40
|
+
const content = quill.getText();
|
41
|
+
if (navigator.clipboard && window.isSecureContext) {
|
42
|
+
navigator.clipboard
|
43
|
+
.writeText(content)
|
44
|
+
.then(showCopySuccess)
|
45
|
+
.catch((err) => {
|
46
|
+
console.error("Failed to copy: ", err);
|
47
|
+
fallbackCopyTextToClipboard(content);
|
48
|
+
});
|
49
|
+
} else {
|
50
|
+
fallbackCopyTextToClipboard(content);
|
51
|
+
}
|
52
|
+
});
|
53
|
+
}
|
54
|
+
|
55
|
+
function fallbackCopyTextToClipboard(text) {
|
56
|
+
const textArea = document.createElement("textarea");
|
57
|
+
textArea.value = text;
|
58
|
+
textArea.style.position = "fixed";
|
59
|
+
textArea.style.top = "-9999px";
|
60
|
+
document.body.appendChild(textArea);
|
61
|
+
textArea.focus();
|
62
|
+
textArea.select();
|
63
|
+
try {
|
64
|
+
document.execCommand("copy");
|
65
|
+
showCopySuccess();
|
66
|
+
} catch (err) {
|
67
|
+
console.error("Fallback: Unable to copy", err);
|
68
|
+
}
|
69
|
+
document.body.removeChild(textArea);
|
70
|
+
}
|
71
|
+
|
72
|
+
function showCopySuccess() {
|
73
|
+
const button = document.getElementById("copyButton");
|
74
|
+
const originalHTML = button.innerHTML;
|
75
|
+
button.innerHTML = '<i class="fas fa-check me-1"></i> Copied!';
|
76
|
+
button.classList.replace("btn-outline-primary", "btn-success");
|
77
|
+
setTimeout(() => {
|
78
|
+
button.innerHTML = originalHTML;
|
79
|
+
button.classList.replace("btn-success", "btn-outline-primary");
|
80
|
+
}, 2000);
|
81
|
+
}
|
82
|
+
|
83
|
+
async function getAuthToken() {
|
84
|
+
return new Promise((resolve) => {
|
85
|
+
if (typeof firebase !== "undefined" && firebase.auth) {
|
86
|
+
const user = firebase.auth().currentUser;
|
87
|
+
if (user) {
|
88
|
+
user
|
89
|
+
.getIdToken()
|
90
|
+
.then(resolve)
|
91
|
+
.catch(() => resolve(null));
|
92
|
+
} else {
|
93
|
+
resolve(null);
|
94
|
+
}
|
95
|
+
} else {
|
96
|
+
const token =
|
97
|
+
localStorage.getItem("authToken") ||
|
98
|
+
sessionStorage.getItem("authToken") ||
|
99
|
+
getCookie("authToken");
|
100
|
+
resolve(token);
|
101
|
+
}
|
102
|
+
});
|
103
|
+
}
|
104
|
+
|
105
|
+
function getCookie(name) {
|
106
|
+
const value = `; ${document.cookie}`;
|
107
|
+
const parts = value.split(`; ${name}=`);
|
108
|
+
return parts.length === 2 ? parts.pop().split(";").shift() : null;
|
109
|
+
}
|
110
|
+
|
111
|
+
form.addEventListener("submit", async function (e) {
|
112
|
+
e.preventDefault();
|
113
|
+
if (!quill) return console.error("Quill editor not ready");
|
114
|
+
|
115
|
+
const authToken = await getAuthToken();
|
116
|
+
|
117
|
+
const submitButton = form.querySelector('button[type="submit"]');
|
118
|
+
const originalText = submitButton?.textContent;
|
119
|
+
submitButton.textContent = "Generating...";
|
120
|
+
submitButton.disabled = true;
|
121
|
+
|
122
|
+
const headers = new Headers({
|
123
|
+
"Content-Type": "application/json",
|
124
|
+
Authorization: `Bearer ${authToken}`,
|
125
|
+
});
|
126
|
+
|
127
|
+
const requestBody = {
|
128
|
+
tool: tool,
|
129
|
+
llm: "gemini",
|
130
|
+
model_name: "gemini-2.0-flash",
|
131
|
+
options: {
|
132
|
+
product_name: input0?.value || "",
|
133
|
+
detials_product_features: input1?.value || "",
|
134
|
+
language: language?.value || "English",
|
135
|
+
tone: tone?.value || "Formal",
|
136
|
+
},
|
137
|
+
};
|
138
|
+
|
139
|
+
console.log(headers);
|
140
|
+
console.log(requestBody);
|
141
|
+
console.log(JSON.stringify(requestBody));
|
142
|
+
try {
|
143
|
+
const response = await fetch(
|
144
|
+
"http://localhost:8000/api/v1/ecommerce-tools/amazon-product-bullet-points-generator",
|
145
|
+
{
|
146
|
+
method: "POST",
|
147
|
+
headers: headers,
|
148
|
+
body: JSON.stringify(requestBody),
|
149
|
+
}
|
150
|
+
);
|
151
|
+
|
152
|
+
if (!response.ok) {
|
153
|
+
const errText = await response.text();
|
154
|
+
throw new Error(`HTTP ${response.status} - ${errText}`);
|
155
|
+
}
|
156
|
+
|
157
|
+
const data = await response.json();
|
158
|
+
if (data.result) {
|
159
|
+
quill.setText("");
|
160
|
+
renderMarkdownToQuill(data.result, quill);
|
161
|
+
addCopyButton();
|
162
|
+
} else {
|
163
|
+
quill.setText("No output received from the server.");
|
164
|
+
}
|
165
|
+
} catch (err) {
|
166
|
+
console.error("API Error:", err.message);
|
167
|
+
renderMarkdownToQuill(
|
168
|
+
`* Clean dishes effectively with 100% natural, plant-derived ingredients.\n* Protect your family using our non-toxic formula, safe for everyone.\n* Reduce your environmental impact with our eco-friendly packaging.\n* Enjoy a gentle yet powerful clean, free from harsh chemicals.\n* Experience a sustainable clean that's safe for you and the planet.`,
|
169
|
+
quill
|
170
|
+
);
|
171
|
+
} finally {
|
172
|
+
submitButton.textContent = originalText;
|
173
|
+
submitButton.disabled = false;
|
174
|
+
}
|
175
|
+
});
|
176
|
+
});
|