appscms-tools-theme 5.1.7 → 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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/_data/.DS_Store +0 -0
  3. data/_data/aitools/en/ai-article-writer.json +184 -0
  4. data/_data/aitools/en/amazon-product-bullet-points-generator.json +222 -0
  5. data/_data/aitools/en/amazon-product-description-generator.json +222 -0
  6. data/_data/aitools/en/brand-name-generator.json +215 -0
  7. data/_data/aitools/en/product-description.json +222 -0
  8. data/_data/home/.DS_Store +0 -0
  9. data/_data/home/en/ens.json +143 -0
  10. data/_includes/.DS_Store +0 -0
  11. data/_includes/aitools/ai-article-writer.html +0 -0
  12. data/_includes/aitools/amazon-product-bullet-points-generator.html +0 -0
  13. data/_includes/aitools/amazon-product-description-generator.html +0 -0
  14. data/_includes/aitools/brand-name-generator.html +0 -0
  15. data/_includes/aitools/product-description.html +0 -0
  16. data/_includes/appscms/.DS_Store +0 -0
  17. data/_includes/appscms/customblog/pageRelatedPosts.html +1 -1
  18. data/_includes/appscms/scripts/script.html +3 -2
  19. data/_includes/script.html +159 -93
  20. data/_layouts/content-tool-ai copy 2.html +6611 -0
  21. data/_layouts/content-tool-ai copy.html +261 -0
  22. data/_layouts/content-tool-ai-2.html +353 -0
  23. data/_layouts/content-tool-ai.html +649 -229
  24. data/assets/.DS_Store +0 -0
  25. data/assets/css/content-tool-ai.css +777 -3
  26. data/assets/js/ai-article-writer.js +0 -0
  27. data/assets/js/amazon-product-bullet-points-generator.js +464 -0
  28. data/assets/js/amazon-product-bullet-points-generator3.js +176 -0
  29. data/assets/js/amazon-product-description-generator.js +309 -0
  30. data/assets/js/appscms-login.js +32 -133
  31. data/assets/js/blog-topic-ideas.js +57 -0
  32. data/assets/js/brand-name-generator.js +127 -0
  33. data/assets/js/human-written-blog-post.js +57 -0
  34. data/assets/js/instagram-caption.js +57 -0
  35. data/assets/js/instagram-hashtag-generator.js +10 -0
  36. data/assets/js/instagram-name-generator.js +61 -0
  37. data/assets/js/product-description.js +299 -0
  38. metadata +27 -2
@@ -0,0 +1,309 @@
1
+ // Auto-generated JS for Amazon Product Description Generator
2
+ document.addEventListener("DOMContentLoaded", function () {
3
+ const form = document.getElementById("contentToolForm");
4
+ const tool = "amazon_product_description_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
+ form.addEventListener("submit", async function (e) {
21
+ e.preventDefault();
22
+
23
+ // Check if Quill is available
24
+ if (!quill) {
25
+ console.error("Quill editor not found");
26
+ return;
27
+ }
28
+
29
+ // Show loading state
30
+ const submitButton = form.querySelector('button[type="submit"]');
31
+ const originalText = submitButton ? submitButton.textContent : "";
32
+ if (submitButton) {
33
+ submitButton.textContent = "Generating...";
34
+ submitButton.disabled = true;
35
+ }
36
+
37
+ const options = {};
38
+
39
+ options["product_name"] = input0.value;
40
+ options["key_features"] = input1.value;
41
+ options["language"] = language.value;
42
+ options["tone"] = tone.value;
43
+
44
+ const body = {
45
+ tool: tool,
46
+ llm: "gemini",
47
+ model_name: "gemini-2.0-flash",
48
+ options: options,
49
+ };
50
+
51
+ try {
52
+ const response = await fetch(
53
+ "http://localhost:8000/api/v1/ecommerce-tools/amazon-product-description-generator",
54
+ {
55
+ method: "POST",
56
+ headers: {
57
+ "Content-Type": "application/json",
58
+ },
59
+ body: JSON.stringify(body),
60
+ }
61
+ );
62
+
63
+ const data = await response.json();
64
+
65
+ if (data.result) {
66
+ // Clear the editor first
67
+ quill.setText("");
68
+
69
+ // Parse and render markdown content
70
+ renderMarkdownToQuill(data.result, quill);
71
+
72
+ console.log("✅ Content generated successfully");
73
+ } else {
74
+ quill.setText("No output received from server.");
75
+ }
76
+ } catch (err) {
77
+ console.error("❌ API Error:", err);
78
+ quill.setText("Error: " + err.message);
79
+ } finally {
80
+ // Reset button state
81
+ if (submitButton) {
82
+ submitButton.textContent = originalText;
83
+ submitButton.disabled = false;
84
+ }
85
+ }
86
+ });
87
+ });
88
+
89
+ // Function to render markdown content to Quill editor
90
+ function renderMarkdownToQuill(markdownText, quill) {
91
+ // Clear editor
92
+ quill.setText("");
93
+
94
+ let index = 0;
95
+ const lines = markdownText.split("\n");
96
+
97
+ lines.forEach((line, lineIndex) => {
98
+ if (line.trim() === "") {
99
+ // Empty line - add line break
100
+ if (lineIndex < lines.length - 1) {
101
+ quill.insertText(index, "\n");
102
+ index += 1;
103
+ }
104
+ return;
105
+ }
106
+
107
+ // Handle different markdown patterns
108
+ if (line.startsWith("**") && line.endsWith("**") && line.length > 4) {
109
+ // Bold text (like **Product Title:** or **Key Features:**)
110
+ const text = line.replace(/^\*\*(.*?)\*\*$/, "$1");
111
+ quill.insertText(index, text, { bold: true });
112
+ index += text.length;
113
+ } else if (line.includes("**")) {
114
+ // Mixed bold and normal text (like **Product Title:** Coffee Mug)
115
+ const parts = line.split("**");
116
+ for (let i = 0; i < parts.length; i++) {
117
+ if (parts[i]) {
118
+ if (i % 2 === 1) {
119
+ // Odd index = bold text
120
+ quill.insertText(index, parts[i], { bold: true });
121
+ index += parts[i].length;
122
+ } else {
123
+ // Even index = normal text
124
+ quill.insertText(index, parts[i]);
125
+ index += parts[i].length;
126
+ }
127
+ }
128
+ }
129
+ } else if (line.startsWith("- ")) {
130
+ // Bullet points
131
+ const text = line.substring(2); // Remove '- '
132
+ quill.insertText(index, "• " + text);
133
+ index += text.length + 2;
134
+ } else if (line.match(/^\d+\.\s/)) {
135
+ // Numbered lists
136
+ const match = line.match(/^(\d+\.\s)(.*)$/);
137
+ if (match) {
138
+ const number = match[1];
139
+ const content = match[2];
140
+
141
+ // Insert number in bold
142
+ quill.insertText(index, number, { bold: true });
143
+ index += number.length;
144
+
145
+ // Insert content in normal text
146
+ quill.insertText(index, content);
147
+ index += content.length;
148
+ } else {
149
+ quill.insertText(index, line);
150
+ index += line.length;
151
+ }
152
+ } else if (line.startsWith("### ")) {
153
+ // Headers (H3)
154
+ const text = line.substring(4);
155
+ quill.insertText(index, text, { bold: true });
156
+ index += text.length;
157
+ } else if (line.startsWith("## ")) {
158
+ // Headers (H2)
159
+ const text = line.substring(3);
160
+ quill.insertText(index, text, { bold: true, size: "large" });
161
+ index += text.length;
162
+ } else if (line.startsWith("# ")) {
163
+ // Headers (H1)
164
+ const text = line.substring(2);
165
+ quill.insertText(index, text, { bold: true, size: "huge" });
166
+ index += text.length;
167
+ } else if (line.startsWith("*") && line.endsWith("*") && line.length > 2) {
168
+ // Italic text
169
+ const text = line.replace(/^\*(.*?)\*$/, "$1");
170
+ quill.insertText(index, text, { italic: true });
171
+ index += text.length;
172
+ } else {
173
+ // Normal text
174
+ quill.insertText(index, line);
175
+ index += line.length;
176
+ }
177
+
178
+ // Add line break if not the last line
179
+ if (lineIndex < lines.length - 1) {
180
+ quill.insertText(index, "\n");
181
+ index += 1;
182
+ }
183
+ });
184
+ }
185
+
186
+ // Alternative function using marked.js if available
187
+ function renderMarkdownToQuillWithMarked(markdownText, quill) {
188
+ if (typeof marked !== "undefined") {
189
+ try {
190
+ // Convert markdown to HTML
191
+ const html = marked.parse(markdownText);
192
+
193
+ // Create a temporary div to parse HTML
194
+ const tempDiv = document.createElement("div");
195
+ tempDiv.innerHTML = html;
196
+
197
+ // Clear editor
198
+ quill.setText("");
199
+
200
+ let index = 0;
201
+
202
+ // Process each child element
203
+ tempDiv.childNodes.forEach((node) => {
204
+ if (node.nodeType === Node.TEXT_NODE) {
205
+ const text = node.textContent.trim();
206
+ if (text) {
207
+ quill.insertText(index, text);
208
+ index += text.length;
209
+ }
210
+ } else if (node.nodeType === Node.ELEMENT_NODE) {
211
+ switch (node.tagName.toLowerCase()) {
212
+ case "h1":
213
+ quill.insertText(index, node.textContent, {
214
+ bold: true,
215
+ size: "huge",
216
+ });
217
+ index += node.textContent.length;
218
+ break;
219
+ case "h2":
220
+ quill.insertText(index, node.textContent, {
221
+ bold: true,
222
+ size: "large",
223
+ });
224
+ index += node.textContent.length;
225
+ break;
226
+ case "h3":
227
+ case "h4":
228
+ case "h5":
229
+ case "h6":
230
+ quill.insertText(index, node.textContent, { bold: true });
231
+ index += node.textContent.length;
232
+ break;
233
+ case "strong":
234
+ case "b":
235
+ quill.insertText(index, node.textContent, { bold: true });
236
+ index += node.textContent.length;
237
+ break;
238
+ case "em":
239
+ case "i":
240
+ quill.insertText(index, node.textContent, { italic: true });
241
+ index += node.textContent.length;
242
+ break;
243
+ case "ul":
244
+ node.querySelectorAll("li").forEach((li) => {
245
+ quill.insertText(index, "• " + li.textContent + "\n");
246
+ index += li.textContent.length + 3;
247
+ });
248
+ break;
249
+ case "ol":
250
+ node.querySelectorAll("li").forEach((li, i) => {
251
+ const number = `${i + 1}. `;
252
+ quill.insertText(index, number, { bold: true });
253
+ index += number.length;
254
+ quill.insertText(index, li.textContent + "\n");
255
+ index += li.textContent.length + 1;
256
+ });
257
+ break;
258
+ case "p":
259
+ const pText = node.textContent.trim();
260
+ if (pText) {
261
+ quill.insertText(index, pText + "\n");
262
+ index += pText.length + 1;
263
+ }
264
+ break;
265
+ case "br":
266
+ quill.insertText(index, "\n");
267
+ index += 1;
268
+ break;
269
+ default:
270
+ const defaultText = node.textContent.trim();
271
+ if (defaultText) {
272
+ quill.insertText(index, defaultText);
273
+ index += defaultText.length;
274
+ }
275
+ }
276
+ }
277
+ });
278
+
279
+ // Add final formatting cleanup
280
+ if (index > 0) {
281
+ quill.insertText(index, "\n");
282
+ }
283
+ } catch (error) {
284
+ console.error("Error parsing markdown with marked.js:", error);
285
+ // Fallback to basic markdown parsing
286
+ renderMarkdownToQuill(markdownText, quill);
287
+ }
288
+ } else {
289
+ // Fallback to basic markdown parsing
290
+ renderMarkdownToQuill(markdownText, quill);
291
+ }
292
+ }
293
+
294
+ // Enhanced function that tries marked.js first, then falls back to basic parsing
295
+ function renderContentToQuill(content, quill) {
296
+ // Try to detect if content is markdown
297
+ const hasMarkdownPatterns = /\*\*|\*|#{1,6}\s|^\s*[-*+]\s|^\s*\d+\.\s/m.test(
298
+ content
299
+ );
300
+
301
+ if (hasMarkdownPatterns && typeof marked !== "undefined") {
302
+ renderMarkdownToQuillWithMarked(content, quill);
303
+ } else if (hasMarkdownPatterns) {
304
+ renderMarkdownToQuill(content, quill);
305
+ } else {
306
+ // Plain text
307
+ quill.setText(content);
308
+ }
309
+ }
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  ---
3
+
3
4
  const profileButton = document.getElementById("profileButton");
4
5
  const userModal = document.getElementById("userModal");
5
6
  let isModalOpen = false;
@@ -39,7 +40,6 @@ const closeModalBtn = document.querySelector(".close-modal-btn");
39
40
  function openModal() {
40
41
  if (modalOverlayy && sideModal) {
41
42
  modalOverlayy.style.display = "block";
42
- // Slight delay for the overlay to appear before the modal slides in
43
43
  setTimeout(() => {
44
44
  sideModal.style.right = "0";
45
45
  }, 50);
@@ -50,7 +50,6 @@ function openModal() {
50
50
  function closeModal() {
51
51
  if (sideModal && modalOverlayy) {
52
52
  sideModal.style.right = "-90%";
53
- // Wait for the animation to complete before hiding the overlay
54
53
  setTimeout(() => {
55
54
  modalOverlayy.style.display = "none";
56
55
  }, 300);
@@ -70,7 +69,6 @@ if (modalOverlayy) {
70
69
  modalOverlayy.addEventListener("click", closeModal);
71
70
  }
72
71
 
73
- // Prevent closing when clicking inside the modal
74
72
  if (sideModal) {
75
73
  sideModal.addEventListener("click", function (event) {
76
74
  event.stopPropagation();
@@ -89,35 +87,25 @@ let firebaseConfig;
89
87
 
90
88
  async function loadFirebaseConfig() {
91
89
  try {
92
- // Try to get config from Netlify function
93
90
  const hostname = window.location.hostname;
94
- const port = window.location.port;
95
-
96
91
  let baseUrl = "";
97
92
 
98
- // Development environment detection
99
93
  if (hostname === "localhost" || hostname === "127.0.0.1") {
100
- // When running locally, we need to specify which port the Netlify Functions are running on
101
- // Default Netlify CLI functions port is 8888, but could be 9000 or custom
102
- baseUrl = "http://localhost:9000"; // Adjust this if your Netlify Functions are on a different port
94
+ baseUrl = "http://localhost:9000";
103
95
  }
104
96
 
105
- // Make the request to the Netlify function with credentials included
106
-
107
97
  const response = await fetch(
108
- `http://localhost:9000/.netlify/functions/get-firebase-config`
98
+ `${baseUrl}/.netlify/functions/get-firebase-config`
109
99
  );
110
100
 
111
101
  if (response.ok) {
112
102
  firebaseConfig = await response.json();
113
103
 
114
- // Check if we got all required config fields
115
104
  if (
116
105
  firebaseConfig.apiKey &&
117
106
  firebaseConfig.authDomain &&
118
107
  firebaseConfig.projectId
119
108
  ) {
120
- // Initialize Firebase with the config
121
109
  if (typeof firebase !== "undefined") {
122
110
  initializeFirebase();
123
111
  } else {
@@ -138,7 +126,6 @@ async function loadFirebaseConfig() {
138
126
  function initializeFirebase() {
139
127
  if (!firebase.apps.length) {
140
128
  firebase.initializeApp(firebaseConfig);
141
-
142
129
  setupAuthListeners();
143
130
  }
144
131
  }
@@ -150,9 +137,7 @@ function setupAuthListeners() {
150
137
  .getRedirectResult()
151
138
  .then((result) => {
152
139
  if (result && result.user) {
153
- // Twitter or other redirect login was successful
154
- // Auth state observer will handle the UI update
155
- } else if (result) {
140
+ // Successful redirect login
156
141
  }
157
142
  })
158
143
  .catch((error) => {
@@ -162,14 +147,12 @@ function setupAuthListeners() {
162
147
  }
163
148
  });
164
149
 
165
- // DOM Elements
166
150
  const loginForm = document.getElementById("loginForm");
167
151
  const signupForm = document.getElementById("signupForm");
168
152
  const forgotPasswordForm = document.getElementById("forgotPasswordForm");
169
153
  const userAvatar = document.getElementById("userAvatar");
170
154
  const profileUserAvatar = document.querySelector(".profile-user-avatar");
171
155
 
172
- // Switch between login and signup
173
156
  const showSignupBtn = document.getElementById("showSignup");
174
157
  if (showSignupBtn) {
175
158
  showSignupBtn.addEventListener("click", (e) => {
@@ -190,7 +173,6 @@ function setupAuthListeners() {
190
173
  });
191
174
  }
192
175
 
193
- // Show forgot password form
194
176
  const forgotPasswordBtn = document.getElementById("forgotPassword");
195
177
  if (forgotPasswordBtn) {
196
178
  forgotPasswordBtn.addEventListener("click", (e) => {
@@ -200,7 +182,6 @@ function setupAuthListeners() {
200
182
  });
201
183
  }
202
184
 
203
- // Back to login from forgot password
204
185
  const backToLoginBtn = document.getElementById("backToLogin");
205
186
  if (backToLoginBtn) {
206
187
  backToLoginBtn.addEventListener("click", () => {
@@ -211,7 +192,6 @@ function setupAuthListeners() {
211
192
  });
212
193
  }
213
194
 
214
- // Handle reset password form submission
215
195
  const resetPasswordForm = document.getElementById("resetPasswordForm");
216
196
  if (resetPasswordForm) {
217
197
  resetPasswordForm.addEventListener("submit", (e) => {
@@ -221,7 +201,6 @@ function setupAuthListeners() {
221
201
 
222
202
  const email = resetEmail.value;
223
203
 
224
- // This is the correct way to set up redirects - Firebase will handle adding the continueUrl internally
225
204
  const actionCodeSettings = {
226
205
  url: "https://pdftoolkit-develop.netlify.app/",
227
206
  handleCodeInApp: false,
@@ -230,7 +209,6 @@ function setupAuthListeners() {
230
209
  auth
231
210
  .sendPasswordResetEmail(email, actionCodeSettings)
232
211
  .then(() => {
233
- // Show success message
234
212
  const resetSuccess = document.getElementById("resetSuccess");
235
213
  if (resetSuccess) resetSuccess.style.display = "block";
236
214
  resetPasswordForm.reset();
@@ -241,7 +219,6 @@ function setupAuthListeners() {
241
219
  });
242
220
  }
243
221
 
244
- // Toggle password visibility
245
222
  const toggleLoginPassword = document.getElementById("toggleLoginPassword");
246
223
  if (toggleLoginPassword) {
247
224
  toggleLoginPassword.addEventListener("click", () => {
@@ -264,7 +241,6 @@ function setupAuthListeners() {
264
241
  });
265
242
  }
266
243
 
267
- // Email/Password Login
268
244
  const emailLoginForm = document.getElementById("emailLoginForm");
269
245
  if (emailLoginForm) {
270
246
  emailLoginForm.addEventListener("submit", (e) => {
@@ -273,22 +249,15 @@ function setupAuthListeners() {
273
249
  const loginPassword = document.getElementById("loginPassword");
274
250
  if (!loginEmail || !loginPassword) return;
275
251
 
276
- const email = loginEmail.value;
277
- const password = loginPassword.value;
278
-
279
252
  auth
280
- .signInWithEmailAndPassword(email, password)
281
- .then((userCredential) => {
282
- // Signed in
283
- const user = userCredential.user;
284
- })
253
+ .signInWithEmailAndPassword(loginEmail.value, loginPassword.value)
254
+ .then(() => {})
285
255
  .catch((error) => {
286
256
  alert(`Login error: ${error.message}`);
287
257
  });
288
258
  });
289
259
  }
290
260
 
291
- // Email/Password Signup
292
261
  const emailSignupForm = document.getElementById("emailSignupForm");
293
262
  if (emailSignupForm) {
294
263
  emailSignupForm.addEventListener("submit", (e) => {
@@ -297,29 +266,22 @@ function setupAuthListeners() {
297
266
  const signupPassword = document.getElementById("signupPassword");
298
267
  if (!signupEmail || !signupPassword) return;
299
268
 
300
- const email = signupEmail.value;
301
- const password = signupPassword.value;
302
-
303
269
  auth
304
- .createUserWithEmailAndPassword(email, password)
305
- .then((userCredential) => {
306
- // Signed up
307
- const user = userCredential.user;
308
- })
270
+ .createUserWithEmailAndPassword(signupEmail.value, signupPassword.value)
271
+ .then(() => {})
309
272
  .catch((error) => {
310
273
  alert(`Signup error: ${error.message}`);
311
274
  });
312
275
  });
313
276
  }
314
277
 
315
- // Google Login
316
278
  const googleLoginBtn = document.getElementById("googleLogin");
317
279
  if (googleLoginBtn) {
318
280
  googleLoginBtn.addEventListener("click", () => {
319
281
  const provider = new firebase.auth.GoogleAuthProvider();
320
282
  auth
321
283
  .signInWithPopup(provider)
322
- .then((result) => {})
284
+ .then(() => {})
323
285
  .catch((error) => {
324
286
  alert(`Google login error: ${error.message}`);
325
287
  });
@@ -332,24 +294,22 @@ function setupAuthListeners() {
332
294
  const provider = new firebase.auth.GoogleAuthProvider();
333
295
  auth
334
296
  .signInWithPopup(provider)
335
- .then((result) => {})
297
+ .then(() => {})
336
298
  .catch((error) => {
337
299
  alert(`Google signup error: ${error.message}`);
338
300
  });
339
301
  });
340
302
  }
341
303
 
342
- // Facebook Login
343
304
  const facebookLoginBtn = document.getElementById("facebookLogin");
344
305
  if (facebookLoginBtn) {
345
306
  facebookLoginBtn.addEventListener("click", () => {
346
307
  const provider = new firebase.auth.FacebookAuthProvider();
347
308
  provider.addScope("email");
348
309
 
349
- // Try popup instead of redirect for Facebook
350
310
  auth
351
311
  .signInWithPopup(provider)
352
- .then((result) => {})
312
+ .then(() => {})
353
313
  .catch((error) => {
354
314
  console.error("Facebook login error:", error);
355
315
  alert(`Facebook login error: ${error.message}`);
@@ -357,40 +317,30 @@ function setupAuthListeners() {
357
317
  });
358
318
  }
359
319
 
360
- // Twitter Login - Try using popup method first
361
320
  const twitterLoginBtn = document.getElementById("twitterLogin");
362
321
  if (twitterLoginBtn) {
363
322
  twitterLoginBtn.addEventListener("click", () => {
364
323
  const provider = new firebase.auth.TwitterAuthProvider();
365
-
366
- try {
367
- // Try popup method first as it provides better error feedback
368
- auth
369
- .signInWithPopup(provider)
370
- .then((result) => {})
371
- .catch((error) => {
372
- console.error("Twitter popup error:", error);
373
-
374
- // If popup fails, fallback to redirect
375
- if (
376
- error.code === "auth/popup-blocked" ||
377
- error.code === "auth/popup-closed-by-user"
378
- ) {
379
- auth.signInWithRedirect(provider).catch((redirectError) => {
380
- console.error("Twitter redirect error:", redirectError);
381
- alert(`Twitter login error: ${redirectError.message}`);
382
- });
383
- } else {
384
- alert(`Twitter login error: ${error.message}`);
385
- }
386
- });
387
- } catch (e) {
388
- console.error("Exception during Twitter login:", e);
389
- }
324
+ auth
325
+ .signInWithPopup(provider)
326
+ .then(() => {})
327
+ .catch((error) => {
328
+ console.error("Twitter popup error:", error);
329
+ if (
330
+ error.code === "auth/popup-blocked" ||
331
+ error.code === "auth/popup-closed-by-user"
332
+ ) {
333
+ auth.signInWithRedirect(provider).catch((redirectError) => {
334
+ console.error("Twitter redirect error:", redirectError);
335
+ alert(`Twitter login error: ${redirectError.message}`);
336
+ });
337
+ } else {
338
+ alert(`Twitter login error: ${error.message}`);
339
+ }
340
+ });
390
341
  });
391
342
  }
392
343
 
393
- // Logout
394
344
  const logoutBtn = document.getElementById("logoutBtn");
395
345
  if (logoutBtn) {
396
346
  logoutBtn.addEventListener("click", () => {
@@ -409,7 +359,6 @@ function setupAuthListeners() {
409
359
  });
410
360
  }
411
361
 
412
- // Auth state observer
413
362
  auth.onAuthStateChanged((user) => {
414
363
  if (user) {
415
364
  const email = user.email || "No email available";
@@ -419,7 +368,6 @@ function setupAuthListeners() {
419
368
  let displayName =
420
369
  user.displayName || (user.email ? user.email.split("@")[0] : "User");
421
370
 
422
- // Special handling for Twitter users who might not have email
423
371
  if (
424
372
  user.providerData[0].providerId === "twitter.com" &&
425
373
  !user.displayName
@@ -442,7 +390,6 @@ function setupAuthListeners() {
442
390
  const loginModalButton = document.querySelector(".login-modal-button");
443
391
  if (loginModalButton) loginModalButton.style.display = "none";
444
392
 
445
- // Set initials for avatar
446
393
  const initials = displayName
447
394
  .split(" ")
448
395
  .map((n) => n[0])
@@ -465,12 +412,14 @@ function setupAuthListeners() {
465
412
  const userProfileSection = document.querySelector(
466
413
  ".user-profile-section"
467
414
  );
468
- if (userProfileSection) userProfileSection.style.display = "flex";
415
+ if (userProfileSection)
416
+ userProfileSection.style.display = "flex";
469
417
 
470
418
  const profileLoginContainer = document.querySelector(
471
419
  ".profile-login-container"
472
420
  );
473
- if (profileLoginContainer) profileLoginContainer.style.display = "none";
421
+ if (profileLoginContainer)
422
+ profileLoginContainer.style.display = "none";
474
423
 
475
424
  const avatarLarge = document.querySelector(".avatar-large");
476
425
  if (avatarLarge) avatarLarge.textContent = initials;
@@ -488,55 +437,6 @@ function setupAuthListeners() {
488
437
  if (forgotPasswordForm) forgotPasswordForm.style.display = "none";
489
438
  }
490
439
  });
491
- const OPERATION_LIMIT = "{{ site.OPERATION_LIMIT }}"; // Set based on site config
492
- const STORAGE_KEY = "user_operations";
493
-
494
- function getOperationCount() {
495
- const storedCount = localStorage.getItem(STORAGE_KEY);
496
- return storedCount ? parseInt(storedCount, 10) : 0;
497
- }
498
-
499
- function incrementOperationCount() {
500
- let currentCount = getOperationCount();
501
-
502
- if (currentCount >= OPERATION_LIMIT) {
503
- showSignupPopup();
504
- return false; // Prevent further uploads
505
- }
506
-
507
- localStorage.setItem(STORAGE_KEY, currentCount + 1);
508
- return true;
509
- }
510
-
511
- function showSignupPopup() {
512
- auth.onAuthStateChanged((user) => {
513
- if (user) {
514
- console.log(user);
515
- }
516
- else{
517
- openModal()
518
- document.querySelector('.close-modal-btn').style.display="none"
519
- }
520
- })
521
-
522
- }
523
-
524
- function hideSignupPopup() {
525
- closeModal()
526
- }
527
-
528
-
529
-
530
- // Attach event listener to all file inputs
531
- document.querySelectorAll("input[type='file']").forEach(input => {
532
- input.addEventListener("change", function () {
533
- if (incrementOperationCount()) {
534
- console.log("File uploaded in:", this);
535
- } else {
536
- this.value = ""; // Reset the input field
537
- }
538
- });
539
- });
540
440
  }
541
441
 
542
442
  // Initialize the app
@@ -545,4 +445,3 @@ if (document.readyState === "loading") {
545
445
  } else {
546
446
  loadFirebaseConfig();
547
447
  }
548
-