appscms-tools-theme 5.2.3 → 5.2.4
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/_includes/appscms/head/head.html +2 -2
- data/_includes/appscms/navbars/ai-image-tools-navbar.html +14 -6
- data/_includes/appscms/scripts/script.html +0 -4
- data/_layouts/ai-image-generator.html +2 -2
- data/_layouts/ai-image-pricing.html +281 -5
- data/_layouts/ai-image-profile.html +434 -0
- data/assets/css/ai-image-home.css +5 -2
- data/assets/js/get-credits.js +0 -91
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c72045a315e29500c743645c3c663244a4634fdf34e9c1b99d41e9100c18385
|
|
4
|
+
data.tar.gz: 419f2df4838deb2f76dd9c9ab63cb764bd0d36af937cef06b8744fad204ed6ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81e298f6a91ed13c65364e6562e4bafd0f8a022d2ac357075071a65352afb9ff402ad790a0013e40a60f1b64007baa1e84cb28c1a4d55a733af3719bd1f29a7e
|
|
7
|
+
data.tar.gz: 9278501b82f31a5a3f010167624d244e6b14dd4188ea35a3fb56092b11e57ce900e82a31bb9c702d717181884c1beb9fee13bfaeb9c469abad9eee1bbdd902a7
|
|
@@ -216,7 +216,7 @@
|
|
|
216
216
|
|
|
217
217
|
|
|
218
218
|
|
|
219
|
-
{%- if page.layout == 'ai-image-home' or page.layout == "ai-image-generator" or page.layout == "ai-image-pricing" -%}
|
|
219
|
+
{%- if page.layout == 'ai-image-home' or page.layout == "ai-image-generator" or page.layout == "ai-image-pricing" or page.layout == "ai-image-profile" -%}
|
|
220
220
|
<link rel="stylesheet" href="/assets/css/ai-image-home.css" />
|
|
221
221
|
{%- endif -%}
|
|
222
222
|
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
{%- endif -%}
|
|
234
234
|
|
|
235
235
|
{%- if page.layout != 'contenttool-home' and page.layout != 'content-tool-ai' and page.layout != "ai-image-home" and page.layout != "ai-image-generator"
|
|
236
|
-
and page.layout != "ai-image-pricing" -%}
|
|
236
|
+
and page.layout != "ai-image-pricing" and page.layout != "ai-image-profile" -%}
|
|
237
237
|
<link rel="stylesheet" href="/assets/css/appscms-theme.css" />
|
|
238
238
|
{%- endif -%}
|
|
239
239
|
|
|
@@ -60,6 +60,8 @@
|
|
|
60
60
|
</div>
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
|
|
64
|
+
{%- if page.layout == "ai-image-home" -%}
|
|
63
65
|
<a href="#" class="modal-item">
|
|
64
66
|
<div class="item-icon">
|
|
65
67
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -75,9 +77,13 @@
|
|
|
75
77
|
</g>
|
|
76
78
|
</svg>
|
|
77
79
|
</div>
|
|
78
|
-
<div class="item-text" id="showCredits">Credits</div>
|
|
80
|
+
<div class="item-text" id="showCredits">Credits 0</div>
|
|
79
81
|
|
|
80
82
|
</a>
|
|
83
|
+
{%- endif -%}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
81
87
|
<a href="/profile" class="modal-item">
|
|
82
88
|
<div class="item-icon">
|
|
83
89
|
<svg height="20" width="20" viewBox="0 0 24 24" id="Layer_1" data-name="Layer 1"
|
|
@@ -224,6 +230,8 @@
|
|
|
224
230
|
</div>
|
|
225
231
|
</div>
|
|
226
232
|
</div>
|
|
233
|
+
|
|
234
|
+
|
|
227
235
|
<div class="side-modal-overlay" id="modalOverlay"></div>
|
|
228
236
|
<div class="side-modal" id="sideModal">
|
|
229
237
|
<div class="modal-header">
|
|
@@ -436,11 +444,11 @@
|
|
|
436
444
|
|
|
437
445
|
<script>
|
|
438
446
|
document.addEventListener("DOMContentLoaded", function () {
|
|
439
|
-
|
|
440
|
-
|
|
447
|
+
const toggler = document.querySelector(".navbar-toggler");
|
|
448
|
+
const menu = document.getElementById("navbarSupportedContent");
|
|
441
449
|
|
|
442
|
-
|
|
443
|
-
|
|
450
|
+
toggler.addEventListener("click", function () {
|
|
451
|
+
menu.classList.toggle("show");
|
|
452
|
+
});
|
|
444
453
|
});
|
|
445
|
-
});
|
|
446
454
|
</script>
|
|
@@ -162,10 +162,6 @@ if page.layout == "appscms-feature" -%}
|
|
|
162
162
|
<script src="/assets/js/userUsageCount.js"></script>
|
|
163
163
|
{%- endif -%}
|
|
164
164
|
|
|
165
|
-
{%- if page.layout == "ai-image-home" or page.layout == "ai-image-generator" or page.layout == "ai-image-pricing" -%}
|
|
166
|
-
<script defer src="/assets/js/get-credits.js"></script>
|
|
167
|
-
{%- endif -%}
|
|
168
|
-
|
|
169
165
|
|
|
170
166
|
{%- if page.layout == "ai-image-generator" -%}
|
|
171
167
|
<script src="/js/ai-image.generator.js"></script>
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
</select>
|
|
56
56
|
</div>
|
|
57
57
|
|
|
58
|
-
<div class="settings
|
|
58
|
+
<div class="settings">
|
|
59
59
|
<label class="setting-label">Additional Prompt</label>
|
|
60
|
-
<textarea name="" id="additionalPrompt"></textarea>
|
|
60
|
+
<textarea class="select-box" name="" id="additionalPrompt"></textarea>
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
63
|
<div class="settings">
|
|
@@ -178,7 +178,257 @@
|
|
|
178
178
|
|
|
179
179
|
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
|
|
180
180
|
|
|
181
|
+
|
|
181
182
|
<script>
|
|
183
|
+
// Loading Overlay Functions
|
|
184
|
+
function createLoadingOverlays() {
|
|
185
|
+
const overlay = document.createElement("div");
|
|
186
|
+
overlay.id = "pricingLoadingOverlay";
|
|
187
|
+
overlay.innerHTML = `
|
|
188
|
+
<div class="pricing-loading-overlay">
|
|
189
|
+
<div class="pricing-loading-content">
|
|
190
|
+
<div class="pricing-loading-spinner"></div>
|
|
191
|
+
<div class="pricing-loading-text">Loading pricing plans...</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
`;
|
|
195
|
+
|
|
196
|
+
// Add CSS if not already present
|
|
197
|
+
if (!document.querySelector("#pricingLoadingStyles")) {
|
|
198
|
+
const style = document.createElement("style");
|
|
199
|
+
style.id = "pricingLoadingStyles";
|
|
200
|
+
style.textContent = `
|
|
201
|
+
.pricing-loading-overlay {
|
|
202
|
+
position: fixed;
|
|
203
|
+
top: 0;
|
|
204
|
+
left: 0;
|
|
205
|
+
width: 100%;
|
|
206
|
+
height: 100%;
|
|
207
|
+
background: rgba(255, 255, 255, 0.95);
|
|
208
|
+
backdrop-filter: blur(4px);
|
|
209
|
+
display: flex;
|
|
210
|
+
align-items: center;
|
|
211
|
+
justify-content: center;
|
|
212
|
+
z-index: 10000;
|
|
213
|
+
opacity: 1;
|
|
214
|
+
transition: opacity 0.3s ease;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.pricing-loading-content {
|
|
218
|
+
text-align: center;
|
|
219
|
+
padding: 40px;
|
|
220
|
+
background: white;
|
|
221
|
+
border-radius: 12px;
|
|
222
|
+
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.pricing-loading-spinner {
|
|
226
|
+
width: 40px;
|
|
227
|
+
height: 40px;
|
|
228
|
+
border: 4px solid #f3f3f3;
|
|
229
|
+
border-top: 4px solid #f59e0b;
|
|
230
|
+
border-radius: 50%;
|
|
231
|
+
animation: pricingLoadingSpin 1s linear infinite;
|
|
232
|
+
margin: 0 auto 16px;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.pricing-loading-text {
|
|
236
|
+
color: #333;
|
|
237
|
+
font-size: 16px;
|
|
238
|
+
font-weight: 500;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@keyframes pricingLoadingSpin {
|
|
242
|
+
0% { transform: rotate(0deg); }
|
|
243
|
+
100% { transform: rotate(360deg); }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.pricing-loading-overlay.fade-out {
|
|
247
|
+
opacity: 0;
|
|
248
|
+
pointer-events: none;
|
|
249
|
+
}
|
|
250
|
+
`;
|
|
251
|
+
document.head.appendChild(style);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return overlay;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Success Modal Function
|
|
258
|
+
function showSubscriptionSuccess() {
|
|
259
|
+
// Create success modal
|
|
260
|
+
const modal = document.createElement('div');
|
|
261
|
+
modal.id = 'subscriptionSuccessModal';
|
|
262
|
+
modal.innerHTML = `
|
|
263
|
+
<div class="success-modal-overlay">
|
|
264
|
+
<div class="success-modal-content">
|
|
265
|
+
<div class="success-icon-wrapper">
|
|
266
|
+
<svg class="success-checkmark" viewBox="0 0 52 52">
|
|
267
|
+
<circle class="success-checkmark-circle" cx="26" cy="26" r="25" fill="none"/>
|
|
268
|
+
<path class="success-checkmark-check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
|
|
269
|
+
</svg>
|
|
270
|
+
</div>
|
|
271
|
+
<h2 class="success-title">Subscription Activated! 🎉</h2>
|
|
272
|
+
<p class="success-message">Your subscription has been successfully activated. You now have full access to all premium features!</p>
|
|
273
|
+
<div class="success-redirect-info">
|
|
274
|
+
<span class="redirect-text">Redirecting to dashboard in <span id="countdown">3</span>s...</span>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
`;
|
|
279
|
+
|
|
280
|
+
// Add CSS for success modal
|
|
281
|
+
const style = document.createElement('style');
|
|
282
|
+
style.textContent = `
|
|
283
|
+
.success-modal-overlay {
|
|
284
|
+
position: fixed;
|
|
285
|
+
top: 0;
|
|
286
|
+
left: 0;
|
|
287
|
+
width: 100%;
|
|
288
|
+
height: 100%;
|
|
289
|
+
background: rgba(0, 0, 0, 0.6);
|
|
290
|
+
backdrop-filter: blur(8px);
|
|
291
|
+
display: flex;
|
|
292
|
+
align-items: center;
|
|
293
|
+
justify-content: center;
|
|
294
|
+
z-index: 10001;
|
|
295
|
+
animation: fadeIn 0.3s ease;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.success-modal-content {
|
|
299
|
+
background: white;
|
|
300
|
+
border-radius: 20px;
|
|
301
|
+
padding: 50px 40px;
|
|
302
|
+
max-width: 450px;
|
|
303
|
+
text-align: center;
|
|
304
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
305
|
+
animation: slideUp 0.4s ease;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.success-icon-wrapper {
|
|
309
|
+
margin: 0 auto 30px;
|
|
310
|
+
width: 80px;
|
|
311
|
+
height: 80px;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.success-checkmark {
|
|
315
|
+
width: 80px;
|
|
316
|
+
height: 80px;
|
|
317
|
+
border-radius: 50%;
|
|
318
|
+
display: block;
|
|
319
|
+
stroke-width: 3;
|
|
320
|
+
stroke: #10b981;
|
|
321
|
+
stroke-miterlimit: 10;
|
|
322
|
+
box-shadow: inset 0px 0px 0px #10b981;
|
|
323
|
+
animation: fill 0.4s ease-in-out 0.4s forwards, scale 0.3s ease-in-out 0.9s both;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.success-checkmark-circle {
|
|
327
|
+
stroke-dasharray: 166;
|
|
328
|
+
stroke-dashoffset: 166;
|
|
329
|
+
stroke-width: 3;
|
|
330
|
+
stroke-miterlimit: 10;
|
|
331
|
+
stroke: #10b981;
|
|
332
|
+
fill: none;
|
|
333
|
+
animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.success-checkmark-check {
|
|
337
|
+
transform-origin: 50% 50%;
|
|
338
|
+
stroke-dasharray: 48;
|
|
339
|
+
stroke-dashoffset: 48;
|
|
340
|
+
stroke: #10b981;
|
|
341
|
+
animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.success-title {
|
|
345
|
+
font-size: 28px;
|
|
346
|
+
font-weight: 700;
|
|
347
|
+
color: #1f2937;
|
|
348
|
+
margin-bottom: 15px;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.success-message {
|
|
352
|
+
font-size: 16px;
|
|
353
|
+
color: #6b7280;
|
|
354
|
+
line-height: 1.6;
|
|
355
|
+
margin-bottom: 25px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.success-redirect-info {
|
|
359
|
+
background: #f0fdf4;
|
|
360
|
+
border: 1px solid #86efac;
|
|
361
|
+
border-radius: 10px;
|
|
362
|
+
padding: 15px;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.redirect-text {
|
|
366
|
+
color: #166534;
|
|
367
|
+
font-size: 14px;
|
|
368
|
+
font-weight: 500;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
#countdown {
|
|
372
|
+
font-weight: 700;
|
|
373
|
+
color: #10b981;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
@keyframes fadeIn {
|
|
377
|
+
from { opacity: 0; }
|
|
378
|
+
to { opacity: 1; }
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
@keyframes slideUp {
|
|
382
|
+
from {
|
|
383
|
+
transform: translateY(30px);
|
|
384
|
+
opacity: 0;
|
|
385
|
+
}
|
|
386
|
+
to {
|
|
387
|
+
transform: translateY(0);
|
|
388
|
+
opacity: 1;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
@keyframes stroke {
|
|
393
|
+
100% {
|
|
394
|
+
stroke-dashoffset: 0;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
@keyframes scale {
|
|
399
|
+
0%, 100% {
|
|
400
|
+
transform: none;
|
|
401
|
+
}
|
|
402
|
+
50% {
|
|
403
|
+
transform: scale3d(1.1, 1.1, 1);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
@keyframes fill {
|
|
408
|
+
100% {
|
|
409
|
+
box-shadow: inset 0px 0px 0px 30px #10b981;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
`;
|
|
413
|
+
document.head.appendChild(style);
|
|
414
|
+
document.body.appendChild(modal);
|
|
415
|
+
|
|
416
|
+
// Countdown and redirect
|
|
417
|
+
let countdown = 3;
|
|
418
|
+
const countdownEl = document.getElementById('countdown');
|
|
419
|
+
const interval = setInterval(() => {
|
|
420
|
+
countdown--;
|
|
421
|
+
if (countdownEl) {
|
|
422
|
+
countdownEl.textContent = countdown;
|
|
423
|
+
}
|
|
424
|
+
if (countdown === 0) {
|
|
425
|
+
clearInterval(interval);
|
|
426
|
+
window.location.href = '/';
|
|
427
|
+
}
|
|
428
|
+
}, 1000);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
|
|
182
432
|
async function getAuthToken() {
|
|
183
433
|
const storedToken = localStorage.getItem("authToken");
|
|
184
434
|
if (storedToken) return storedToken;
|
|
@@ -201,11 +451,21 @@
|
|
|
201
451
|
|
|
202
452
|
async function loadPricingPlans() {
|
|
203
453
|
try {
|
|
454
|
+
|
|
455
|
+
const overlay = createLoadingOverlays();
|
|
456
|
+
document.body.appendChild(overlay);
|
|
457
|
+
|
|
204
458
|
const res = await fetch(
|
|
205
459
|
"https://us-central1-appscms-develop.cloudfunctions.net/payment_api/api/v1/payment-routes/image-toolkit-plans"
|
|
206
460
|
);
|
|
207
461
|
const data = await res.json();
|
|
208
462
|
|
|
463
|
+
// Remove loading overlay
|
|
464
|
+
const loadingOverlay = document.getElementById("pricingLoadingOverlay");
|
|
465
|
+
if (loadingOverlay) {
|
|
466
|
+
loadingOverlay.remove();
|
|
467
|
+
}
|
|
468
|
+
|
|
209
469
|
const container = document.getElementById("pricingContainer");
|
|
210
470
|
container.innerHTML = "";
|
|
211
471
|
|
|
@@ -222,7 +482,7 @@
|
|
|
222
482
|
${isPopular ? `<span class="popular-badge">Most Popular</span>` : ""}
|
|
223
483
|
|
|
224
484
|
<div class="plan-header">
|
|
225
|
-
<h2 class="plan-name">${plan.plan}</h2>
|
|
485
|
+
<h2 class="plan-name">${plan.plan.toLowerCase()}</h2>
|
|
226
486
|
<p class="plan-description">
|
|
227
487
|
${isPopular ? "For creators and professionals" : "Perfect for beginners"}
|
|
228
488
|
</p>
|
|
@@ -235,7 +495,7 @@
|
|
|
235
495
|
</div>
|
|
236
496
|
</div>
|
|
237
497
|
|
|
238
|
-
<button class="buy-button"
|
|
498
|
+
<button class="buy-button" id=${plan.plan.toLowerCase()}
|
|
239
499
|
onclick="buyPlan('${plan.razorpay_plan_id}', '${plan.plan}')">
|
|
240
500
|
Buy Now
|
|
241
501
|
</button>
|
|
@@ -254,6 +514,21 @@
|
|
|
254
514
|
container.insertAdjacentHTML("beforeend", card);
|
|
255
515
|
});
|
|
256
516
|
|
|
517
|
+
// After rendering all plans, disable the button for the user's active plan
|
|
518
|
+
if (typeof firebase !== "undefined" && firebase.auth) {
|
|
519
|
+
const user = firebase.auth().currentUser;
|
|
520
|
+
if (user) {
|
|
521
|
+
user.getIdTokenResult().then(tokenResult => {
|
|
522
|
+
const customClaims = tokenResult.claims;
|
|
523
|
+
if (customClaims.plan && window.disableActivePlanButton) {
|
|
524
|
+
window.disableActivePlanButton(customClaims.plan);
|
|
525
|
+
}
|
|
526
|
+
}).catch(err => {
|
|
527
|
+
console.error("Error getting user claims:", err);
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
257
532
|
} catch (err) {
|
|
258
533
|
console.error("Pricing load error:", err);
|
|
259
534
|
}
|
|
@@ -262,7 +537,7 @@
|
|
|
262
537
|
const PAYMENT_API_URL = "https://us-central1-appscms-develop.cloudfunctions.net/payment_api";
|
|
263
538
|
|
|
264
539
|
async function checkSubscriptionStatus(subscriptionId) {
|
|
265
|
-
const POLL_INTERVAL =
|
|
540
|
+
const POLL_INTERVAL = 5000; // 3 sec (OK to keep)
|
|
266
541
|
const TIMEOUT = 2 * 60 * 1000; // 2 minutes max
|
|
267
542
|
|
|
268
543
|
const startTime = Date.now();
|
|
@@ -287,8 +562,9 @@
|
|
|
287
562
|
|
|
288
563
|
// ✅ ACTIVE → STOP
|
|
289
564
|
if (data.status === "activated") {
|
|
290
|
-
|
|
291
|
-
|
|
565
|
+
hideLoadingOverlay();
|
|
566
|
+
showSubscriptionSuccess();
|
|
567
|
+
refreshFirebaseToken();
|
|
292
568
|
return;
|
|
293
569
|
}
|
|
294
570
|
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
{% assign file = page.fileName %} {% assign lang = page.lang %} {% assign folder
|
|
2
|
+
= page.folderName %} {% assign pageData = site.data[folder][lang][file] %} {%-
|
|
3
|
+
assign boxColor = site.data[page.folderName][page.lang][page.fileName].color -%}
|
|
4
|
+
|
|
5
|
+
<!DOCTYPE html>
|
|
6
|
+
<html lang="{{ page.lang }}">
|
|
7
|
+
{%- include appscms/head/head.html -%}
|
|
8
|
+
<link rel="stylesheet" href="/css/profile.css" />
|
|
9
|
+
<link rel="stylesheet" href="/ai-tools/assets/css/content-tool-ai.css" />
|
|
10
|
+
|
|
11
|
+
<body data-developer-key="{{ site.developerKey }}" data-client-id="{{ site.clientId }}" data-app-id="{{ site.appId }}"
|
|
12
|
+
data-dropbox-apikey="{{ site.dropboxapikey }}">
|
|
13
|
+
|
|
14
|
+
<div class="container">
|
|
15
|
+
{%- include /appscms/navbars/ai-image-tools-navbar.html -%}
|
|
16
|
+
|
|
17
|
+
<div class="container user-profile-section mt-5">
|
|
18
|
+
<!-- Sidebar -->
|
|
19
|
+
<div class="profile-sidebar">
|
|
20
|
+
<div class="sidebar-header">
|
|
21
|
+
<div class="avatar-large"></div>
|
|
22
|
+
</div>
|
|
23
|
+
<ul class="sidebar-menu">
|
|
24
|
+
<li class="tab-link active" data-tab="account">Account</li>
|
|
25
|
+
<li class="tab-link" data-tab="subscription">Subscription</li>
|
|
26
|
+
<!-- <li class="tab-link" data-tab="invoices">Invoices</li>
|
|
27
|
+
<li class="tab-link" data-tab="company">Company Information</li>
|
|
28
|
+
<li class="tab-link" data-tab="team">Team</li>
|
|
29
|
+
<li class="tab-link" data-tab="settings">Settings</li> -->
|
|
30
|
+
</ul>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<!-- Content Area -->
|
|
34
|
+
<div class="content">
|
|
35
|
+
<!-- Account Tab Content -->
|
|
36
|
+
<div id="account" class="tab-content active">
|
|
37
|
+
<h2 class="content-title">Account</h2>
|
|
38
|
+
|
|
39
|
+
<!-- Email Section -->
|
|
40
|
+
<div class="form-section">
|
|
41
|
+
<div class="form-title">
|
|
42
|
+
Email <span class="verified-badge">Verified</span>
|
|
43
|
+
</div>
|
|
44
|
+
<div class="form-group">
|
|
45
|
+
<input id="user-email-input" type="email" class="form-input" value="" readonly />
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Name Section -->
|
|
50
|
+
<div class="form-section">
|
|
51
|
+
<div class="form-title">Name</div>
|
|
52
|
+
<div class="form-group">
|
|
53
|
+
<label class="form-label">Name</label>
|
|
54
|
+
<input type="text" class="form-input username-input" value="" />
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<!-- Subscription Tab Content -->
|
|
60
|
+
<div id="subscription" class="tab-content">
|
|
61
|
+
<h2 class="content-title">Subscription</h2>
|
|
62
|
+
|
|
63
|
+
<!-- Current Plan Section -->
|
|
64
|
+
<div class="form-section">
|
|
65
|
+
<div class="form-title">Current Plan</div>
|
|
66
|
+
<div class="subscription-card">
|
|
67
|
+
<div class="plan-header">
|
|
68
|
+
<div class="plan-info">
|
|
69
|
+
<h3 class="current-plan-name" style="text-transform: capitalize">
|
|
70
|
+
Free Plan
|
|
71
|
+
</h3>
|
|
72
|
+
<!-- <span class="plan-badge current-plan-badge">Free</span> -->
|
|
73
|
+
</div>
|
|
74
|
+
<div class="plan-status">
|
|
75
|
+
<span class="subscription-status active">Loading...</span>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="plan-details">
|
|
79
|
+
<!-- <div class="detail-item">
|
|
80
|
+
<span class="detail-label">Token Limit:</span>
|
|
81
|
+
<span class="token-limit">Loading...</span>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="detail-item">
|
|
84
|
+
<span class="detail-label">Plan Duration:</span>
|
|
85
|
+
<span class="plan-duration">Loading...</span>
|
|
86
|
+
</div> -->
|
|
87
|
+
<div class="detail-item">
|
|
88
|
+
<span class="detail-label">Expires On:</span>
|
|
89
|
+
<span class="plan-expiry">Loading...</span>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="detail-item">
|
|
92
|
+
<span class="detail-label">Subscription ID:</span>
|
|
93
|
+
<span class="subscription-id">Loading...</span>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<!-- Usage Section -->
|
|
100
|
+
<div class="form-section d-none">
|
|
101
|
+
<div class="form-title">Usage Statistics</div>
|
|
102
|
+
<div class="usage-card">
|
|
103
|
+
<div class="usage-item">
|
|
104
|
+
<div class="usage-header">
|
|
105
|
+
<span class="usage-label">Tokens Used This Month</span>
|
|
106
|
+
<span class="usage-value">
|
|
107
|
+
<span class="tokens-used">0</span> /
|
|
108
|
+
<span class="token-limit-display">0</span>
|
|
109
|
+
tokens
|
|
110
|
+
</span>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="usage-progress">
|
|
113
|
+
<div class="progress-bar">
|
|
114
|
+
<div class="progress-fill" style="width: 0%"></div>
|
|
115
|
+
</div>
|
|
116
|
+
<span class="usage-percentage">0%</span>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="usage-item">
|
|
120
|
+
<div class="usage-header">
|
|
121
|
+
<span class="usage-label">Days Remaining</span>
|
|
122
|
+
<span class="usage-value days-remaining">Loading...</span>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
<!-- Plan Features Section -->
|
|
129
|
+
<div class="form-section d-none">
|
|
130
|
+
<div class="form-title">Plan Features</div>
|
|
131
|
+
<div class="features-card">
|
|
132
|
+
<div class="features-list" id="current-plan-features">
|
|
133
|
+
<!-- Features will be populated by JavaScript -->
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<!-- Actions Section -->
|
|
139
|
+
<div class="form-section">
|
|
140
|
+
<div class="form-title">Actions</div>
|
|
141
|
+
<div class="actions-card">
|
|
142
|
+
<button class="btn-manage" onclick="window.location.href='/pricing'">
|
|
143
|
+
Manage Subscription
|
|
144
|
+
</button>
|
|
145
|
+
<button class="btn-cancel-subscription" id="cancelSubscriptionBtn"
|
|
146
|
+
onclick="showCancelConfirmation()" style="display: none;">
|
|
147
|
+
Cancel Subscription
|
|
148
|
+
</button>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<!-- Expiry Warning -->
|
|
153
|
+
<div class="expiry-warning" style="display: none">
|
|
154
|
+
<div class="warning-content">
|
|
155
|
+
<i class="warning-icon">⚠️</i>
|
|
156
|
+
<span class="warning-text">Your plan expires soon!</span>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<!-- Cancel Subscription Confirmation Modal -->
|
|
166
|
+
<div id="cancelConfirmationModal" class="cancel-modal" style="display: none;">
|
|
167
|
+
<div class="cancel-modal-overlay" onclick="hideCancelConfirmation()"></div>
|
|
168
|
+
<div class="cancel-modal-content">
|
|
169
|
+
<div class="cancel-modal-header">
|
|
170
|
+
<div class="cancel-icon-wrapper">
|
|
171
|
+
<svg class="cancel-warning-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
172
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
173
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
174
|
+
</svg>
|
|
175
|
+
</div>
|
|
176
|
+
<h3 class="cancel-modal-title">Cancel Subscription?</h3>
|
|
177
|
+
<p class="cancel-modal-description">
|
|
178
|
+
Are you sure you want to cancel your subscription? You will lose access to all premium features at
|
|
179
|
+
the end of your current billing period.
|
|
180
|
+
</p>
|
|
181
|
+
</div>
|
|
182
|
+
<div class="cancel-modal-body">
|
|
183
|
+
<div class="cancel-warning-box">
|
|
184
|
+
<strong>⚠️ What you'll lose:</strong>
|
|
185
|
+
<ul class="cancel-loss-list">
|
|
186
|
+
<li>Access to premium AI image generation</li>
|
|
187
|
+
<li>Higher token limits</li>
|
|
188
|
+
<li>Priority support</li>
|
|
189
|
+
<li>Advanced features</li>
|
|
190
|
+
</ul>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
<div class="cancel-modal-footer">
|
|
194
|
+
<button class="btn-cancel-action" onclick="hideCancelConfirmation()">
|
|
195
|
+
Keep Subscription
|
|
196
|
+
</button>
|
|
197
|
+
<button class="btn-confirm-cancel" onclick="confirmCancelSubscription()">
|
|
198
|
+
Yes, Cancel Subscription
|
|
199
|
+
</button>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<style>
|
|
205
|
+
/* Cancel Subscription Button */
|
|
206
|
+
.btn-cancel-subscription {
|
|
207
|
+
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
|
208
|
+
color: white;
|
|
209
|
+
border: none;
|
|
210
|
+
border-radius: 8px;
|
|
211
|
+
font-size: 14px;
|
|
212
|
+
font-weight: 600;
|
|
213
|
+
cursor: pointer;
|
|
214
|
+
transition: all 0.3s ease;
|
|
215
|
+
padding: 10px 20px;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.btn-cancel-subscription:hover {
|
|
219
|
+
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
|
|
220
|
+
transform: translateY(-2px);
|
|
221
|
+
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Cancel Modal */
|
|
225
|
+
.cancel-modal {
|
|
226
|
+
position: fixed;
|
|
227
|
+
top: 0;
|
|
228
|
+
left: 0;
|
|
229
|
+
width: 100%;
|
|
230
|
+
height: 100%;
|
|
231
|
+
z-index: 10000;
|
|
232
|
+
display: flex;
|
|
233
|
+
align-items: center;
|
|
234
|
+
justify-content: center;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.cancel-modal-overlay {
|
|
238
|
+
position: absolute;
|
|
239
|
+
top: 0;
|
|
240
|
+
left: 0;
|
|
241
|
+
width: 100%;
|
|
242
|
+
height: 100%;
|
|
243
|
+
background: rgba(0, 0, 0, 0.6);
|
|
244
|
+
backdrop-filter: blur(4px);
|
|
245
|
+
animation: fadeIn 0.3s ease;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.cancel-modal-content {
|
|
249
|
+
position: relative;
|
|
250
|
+
background: white;
|
|
251
|
+
border-radius: 16px;
|
|
252
|
+
max-width: 500px;
|
|
253
|
+
width: 90%;
|
|
254
|
+
padding: 30px;
|
|
255
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
256
|
+
animation: slideUp 0.3s ease;
|
|
257
|
+
z-index: 10001;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.cancel-modal-header {
|
|
261
|
+
text-align: center;
|
|
262
|
+
margin-bottom: 25px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.cancel-icon-wrapper {
|
|
266
|
+
width: 80px;
|
|
267
|
+
height: 80px;
|
|
268
|
+
margin: 0 auto 20px;
|
|
269
|
+
background: #fef2f2;
|
|
270
|
+
border-radius: 50%;
|
|
271
|
+
display: flex;
|
|
272
|
+
align-items: center;
|
|
273
|
+
justify-content: center;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.cancel-warning-icon {
|
|
277
|
+
width: 40px;
|
|
278
|
+
height: 40px;
|
|
279
|
+
color: #ef4444;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.cancel-modal-title {
|
|
283
|
+
font-size: 24px;
|
|
284
|
+
font-weight: 700;
|
|
285
|
+
color: #1f2937;
|
|
286
|
+
margin-bottom: 10px;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.cancel-modal-description {
|
|
290
|
+
font-size: 15px;
|
|
291
|
+
color: #6b7280;
|
|
292
|
+
line-height: 1.6;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.cancel-modal-body {
|
|
296
|
+
margin-bottom: 25px;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.cancel-warning-box {
|
|
300
|
+
background: #fef2f2;
|
|
301
|
+
border: 1px solid #fecaca;
|
|
302
|
+
border-radius: 10px;
|
|
303
|
+
padding: 15px;
|
|
304
|
+
color: #991b1b;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.cancel-warning-box strong {
|
|
308
|
+
display: block;
|
|
309
|
+
margin-bottom: 10px;
|
|
310
|
+
font-size: 14px;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.cancel-loss-list {
|
|
314
|
+
margin: 0;
|
|
315
|
+
padding-left: 20px;
|
|
316
|
+
font-size: 13px;
|
|
317
|
+
line-height: 1.8;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.cancel-loss-list li {
|
|
321
|
+
margin-bottom: 5px;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.cancel-modal-footer {
|
|
325
|
+
display: flex;
|
|
326
|
+
gap: 12px;
|
|
327
|
+
flex-direction: column-reverse;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.btn-cancel-action,
|
|
331
|
+
.btn-confirm-cancel {
|
|
332
|
+
padding: 12px 24px;
|
|
333
|
+
border-radius: 8px;
|
|
334
|
+
font-size: 14px;
|
|
335
|
+
font-weight: 600;
|
|
336
|
+
cursor: pointer;
|
|
337
|
+
transition: all 0.3s ease;
|
|
338
|
+
border: none;
|
|
339
|
+
width: 100%;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.btn-cancel-action {
|
|
343
|
+
background: #f3f4f6;
|
|
344
|
+
color: #374151;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.btn-cancel-action:hover {
|
|
348
|
+
background: #e5e7eb;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.btn-confirm-cancel {
|
|
352
|
+
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
|
353
|
+
color: white;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.btn-confirm-cancel:hover {
|
|
357
|
+
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
@keyframes fadeIn {
|
|
361
|
+
from {
|
|
362
|
+
opacity: 0;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
to {
|
|
366
|
+
opacity: 1;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
@keyframes slideUp {
|
|
371
|
+
from {
|
|
372
|
+
transform: translateY(30px);
|
|
373
|
+
opacity: 0;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
to {
|
|
377
|
+
transform: translateY(0);
|
|
378
|
+
opacity: 1;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
@media (min-width: 640px) {
|
|
383
|
+
.cancel-modal-footer {
|
|
384
|
+
flex-direction: row;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
</style>
|
|
388
|
+
|
|
389
|
+
<script>
|
|
390
|
+
// Tab functionality
|
|
391
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
392
|
+
const tabLinks = document.querySelectorAll(".tab-link");
|
|
393
|
+
const tabContents = document.querySelectorAll(".tab-content");
|
|
394
|
+
|
|
395
|
+
tabLinks.forEach((link) => {
|
|
396
|
+
link.addEventListener("click", () => {
|
|
397
|
+
// Remove active class from all tabs
|
|
398
|
+
tabLinks.forEach((l) => l.classList.remove("active"));
|
|
399
|
+
tabContents.forEach((c) => c.classList.remove("active"));
|
|
400
|
+
|
|
401
|
+
// Add active class to clicked tab
|
|
402
|
+
link.classList.add("active");
|
|
403
|
+
|
|
404
|
+
// Show corresponding content
|
|
405
|
+
const tabId = link.getAttribute("data-tab");
|
|
406
|
+
document.getElementById(tabId).classList.add("active");
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
// Password visibility toggle
|
|
411
|
+
const toggleButtons = document.querySelectorAll(".password-toggle");
|
|
412
|
+
toggleButtons.forEach((button) => {
|
|
413
|
+
button.addEventListener("click", () => {
|
|
414
|
+
const input = button.previousElementSibling;
|
|
415
|
+
const icon = button.querySelector(".material-icons");
|
|
416
|
+
|
|
417
|
+
if (input.type === "password") {
|
|
418
|
+
input.type = "text";
|
|
419
|
+
icon.textContent = "visibility_off";
|
|
420
|
+
} else {
|
|
421
|
+
input.type = "password";
|
|
422
|
+
icon.textContent = "visibility";
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
</script>
|
|
429
|
+
|
|
430
|
+
{%- include appscms/scripts/script.html -%}
|
|
431
|
+
</body>
|
|
432
|
+
|
|
433
|
+
</html>
|
|
434
|
+
```
|
|
@@ -27,6 +27,9 @@ body {
|
|
|
27
27
|
.nav-item .nav-link {
|
|
28
28
|
color: var(--black-color);
|
|
29
29
|
}
|
|
30
|
+
.logged-in-user-email{
|
|
31
|
+
font-size: 12px;
|
|
32
|
+
}
|
|
30
33
|
|
|
31
34
|
.btn-generate,
|
|
32
35
|
.login-btn {
|
|
@@ -404,8 +407,8 @@ body {
|
|
|
404
407
|
}
|
|
405
408
|
|
|
406
409
|
.profile-user-avatar {
|
|
407
|
-
width:
|
|
408
|
-
height:
|
|
410
|
+
width: 50px;
|
|
411
|
+
height: 50px;
|
|
409
412
|
border-radius: 50%;
|
|
410
413
|
background-color: var(--primary-color);
|
|
411
414
|
color: white;
|
data/assets/js/get-credits.js
CHANGED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
async function getAuthToken() {
|
|
3
|
-
return new Promise((resolve) => {
|
|
4
|
-
// First try to get from localStorage (set by Firebase auth)
|
|
5
|
-
const storedToken = localStorage.getItem("authToken");
|
|
6
|
-
if (storedToken) {
|
|
7
|
-
resolve(storedToken);
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// If Firebase is available and user is logged in, get fresh token
|
|
12
|
-
if (typeof firebase !== "undefined" && firebase.auth) {
|
|
13
|
-
try {
|
|
14
|
-
const user = firebase.auth().currentUser;
|
|
15
|
-
if (user) {
|
|
16
|
-
user
|
|
17
|
-
.getIdToken(true) // Force refresh
|
|
18
|
-
.then((token) => {
|
|
19
|
-
// Save to localStorage for faster access
|
|
20
|
-
localStorage.setItem("authToken", token);
|
|
21
|
-
resolve(token);
|
|
22
|
-
})
|
|
23
|
-
.catch((error) => {
|
|
24
|
-
console.warn("Failed to get auth token:", error);
|
|
25
|
-
resolve(null);
|
|
26
|
-
});
|
|
27
|
-
} else {
|
|
28
|
-
console.warn("User not logged in");
|
|
29
|
-
resolve(null);
|
|
30
|
-
}
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.warn("Firebase check error:", error);
|
|
33
|
-
resolve(null);
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
// Fallback to session storage
|
|
37
|
-
const sessionToken = sessionStorage.getItem("authToken");
|
|
38
|
-
resolve(sessionToken || null);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
const BACKEND_API_URL = 'https://us-central1-appscms-develop.cloudfunctions.net/ai_image_tools/api/v1/image-tools-routes';
|
|
43
|
-
|
|
44
|
-
async function getUserCredits() {
|
|
45
|
-
try {
|
|
46
|
-
const authToken = await getAuthToken();
|
|
47
|
-
if (!authToken) {
|
|
48
|
-
throw new Error("User not authenticated");
|
|
49
|
-
}
|
|
50
|
-
const res = await fetch(`${BACKEND_API_URL}/remaining-credits`, {
|
|
51
|
-
method: "GET",
|
|
52
|
-
headers: {
|
|
53
|
-
"Authorization": `Bearer ${authToken}`,
|
|
54
|
-
"Content-Type": "application/json"
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (!res.ok) {
|
|
59
|
-
const errorText = await res.text();
|
|
60
|
-
let errorMsg = "Failed to fetch credits";
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
const errorJson = JSON.parse(errorText);
|
|
64
|
-
errorMsg = errorJson.detail || errorMsg;
|
|
65
|
-
} catch { }
|
|
66
|
-
|
|
67
|
-
throw new Error(errorMsg);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const data = await res.json();
|
|
71
|
-
|
|
72
|
-
return data;
|
|
73
|
-
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error("Get credits error:", error);
|
|
76
|
-
showError(error.message || "Unable to fetch credits");
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
(async () => {
|
|
82
|
-
const creditData = await getUserCredits();
|
|
83
|
-
|
|
84
|
-
if (creditData) {
|
|
85
|
-
const creditEl = document.querySelector("#showCredits");
|
|
86
|
-
if (creditEl) {
|
|
87
|
-
creditEl.innerHTML = `Credits: ${creditData.credits}`;
|
|
88
|
-
console.log("Credits:", creditData.credits);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
})();
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appscms-tools-theme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.2.
|
|
4
|
+
version: 5.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- vivek-appscms
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -266,6 +266,7 @@ files:
|
|
|
266
266
|
- _layouts/ai-image-generator.html
|
|
267
267
|
- _layouts/ai-image-home.html
|
|
268
268
|
- _layouts/ai-image-pricing.html
|
|
269
|
+
- _layouts/ai-image-profile.html
|
|
269
270
|
- _layouts/allAuthors.html
|
|
270
271
|
- _layouts/appscms-about.html
|
|
271
272
|
- _layouts/appscms-audio.html
|