ft-scout 8.0.9 → 9.0.0
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.
- package/.firebase/hosting.d2Vi.cache +7 -6
- package/README.md +2 -2
- package/bin/src/commands/plan.d.ts.map +1 -1
- package/bin/src/commands/plan.js +51 -10
- package/bin/src/commands/plan.js.map +1 -1
- package/bin/src/index.js +4 -4
- package/bin/src/server/server.d.ts.map +1 -1
- package/bin/src/server/server.js +256 -3
- package/bin/src/server/server.js.map +1 -1
- package/bin/src/utils/admin.d.ts.map +1 -0
- package/bin/src/utils/admin.js +237 -0
- package/bin/src/utils/admin.js.map +1 -0
- package/bin/src/utils/auth.d.ts.map +1 -1
- package/bin/src/utils/auth.js +17 -7
- package/bin/src/utils/auth.js.map +1 -1
- package/bin/src/utils/branding.js +1 -1
- package/bin/src/utils/payment.d.ts.map +1 -1
- package/bin/src/utils/payment.js +26 -32
- package/bin/src/utils/payment.js.map +1 -1
- package/bin/src/utils/pricing.d.ts.map +1 -0
- package/bin/src/utils/pricing.js +143 -0
- package/bin/src/utils/pricing.js.map +1 -0
- package/firebase.json +8 -0
- package/package.json +1 -1
- package/web/app.js +106 -12
- package/web/styles.css +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["pricing.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,YAAY,CAAC;AACrD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,QAAQ,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CA0DtE,CAAC;AAQF,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAoBtE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAoCtH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,CAcxG;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAE5E"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const PRICING_DIR = path.join(os.homedir(), '.ft');
|
|
5
|
+
const PRICING_FILE = path.join(PRICING_DIR, 'pricing.json');
|
|
6
|
+
export const DEFAULT_PRICING_CONFIG = {
|
|
7
|
+
free: {
|
|
8
|
+
id: 'free',
|
|
9
|
+
name: 'Developer Free',
|
|
10
|
+
monthlyPriceINR: 0,
|
|
11
|
+
annualPriceINR: 0,
|
|
12
|
+
monthlyPriceUSD: 0,
|
|
13
|
+
annualPriceUSD: 0,
|
|
14
|
+
credits: 100,
|
|
15
|
+
description: 'Essential tools for individual developer workflow',
|
|
16
|
+
features: [
|
|
17
|
+
'100 AI credits / month',
|
|
18
|
+
'Full Scout CLI core features',
|
|
19
|
+
'1 Active CLI session slot',
|
|
20
|
+
'Single-use authorization tokens',
|
|
21
|
+
'Community support & docs',
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
pro: {
|
|
25
|
+
id: 'pro',
|
|
26
|
+
name: 'Pro Developer',
|
|
27
|
+
monthlyPriceINR: 50, // ₹50 as requested by user
|
|
28
|
+
annualPriceINR: 45,
|
|
29
|
+
monthlyPriceUSD: 0.99,
|
|
30
|
+
annualPriceUSD: 0.79,
|
|
31
|
+
credits: 1000,
|
|
32
|
+
description: 'High-power AI co-pilot capabilities, priority quota & live visual HUD',
|
|
33
|
+
popular: true,
|
|
34
|
+
badge: 'POPULAR',
|
|
35
|
+
features: [
|
|
36
|
+
'1,000 AI credits / month',
|
|
37
|
+
'Unlimited AI co-pilot queries',
|
|
38
|
+
'Up to 5 Active CLI Sessions',
|
|
39
|
+
'Live Screen Sharing & Visual Perception HUD',
|
|
40
|
+
'Fast-track model response engine',
|
|
41
|
+
'Priority token revocation & audit logs',
|
|
42
|
+
'Direct email support response',
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
enterprise: {
|
|
46
|
+
id: 'enterprise',
|
|
47
|
+
name: 'Team & Enterprise',
|
|
48
|
+
monthlyPriceINR: 3999,
|
|
49
|
+
annualPriceINR: 37990,
|
|
50
|
+
monthlyPriceUSD: 49,
|
|
51
|
+
annualPriceUSD: 39,
|
|
52
|
+
credits: 10000,
|
|
53
|
+
description: 'Organization controls, security policies & dedicated scale',
|
|
54
|
+
features: [
|
|
55
|
+
'10,000 AI credits / month',
|
|
56
|
+
'Multi-seat organization access',
|
|
57
|
+
'Unlimited CLI Session connections',
|
|
58
|
+
'Window Isolation & Multi-App Vision Engine',
|
|
59
|
+
'Custom security token policies',
|
|
60
|
+
'Dedicated account SLA support',
|
|
61
|
+
'24/7 SLA Priority response',
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
function ensurePricingDir() {
|
|
66
|
+
if (!fs.existsSync(PRICING_DIR)) {
|
|
67
|
+
fs.mkdirSync(PRICING_DIR, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function getPricingConfig() {
|
|
71
|
+
try {
|
|
72
|
+
if (fs.existsSync(PRICING_FILE)) {
|
|
73
|
+
const raw = fs.readFileSync(PRICING_FILE, 'utf-8');
|
|
74
|
+
const parsed = JSON.parse(raw);
|
|
75
|
+
if (parsed && typeof parsed === 'object' && parsed.pro && parsed.free) {
|
|
76
|
+
return {
|
|
77
|
+
free: { ...DEFAULT_PRICING_CONFIG.free, ...parsed.free },
|
|
78
|
+
pro: { ...DEFAULT_PRICING_CONFIG.pro, ...parsed.pro },
|
|
79
|
+
enterprise: { ...DEFAULT_PRICING_CONFIG.enterprise, ...parsed.enterprise },
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.warn('[Pricing Engine] Error reading pricing file, using default configuration:', err);
|
|
86
|
+
}
|
|
87
|
+
// Auto-initialize file if it doesn't exist
|
|
88
|
+
saveFullPricingConfig(DEFAULT_PRICING_CONFIG);
|
|
89
|
+
return { ...DEFAULT_PRICING_CONFIG };
|
|
90
|
+
}
|
|
91
|
+
export function saveFullPricingConfig(config) {
|
|
92
|
+
ensurePricingDir();
|
|
93
|
+
const cleanConfig = {
|
|
94
|
+
free: {
|
|
95
|
+
...DEFAULT_PRICING_CONFIG.free,
|
|
96
|
+
...config.free,
|
|
97
|
+
id: 'free',
|
|
98
|
+
monthlyPriceINR: 0,
|
|
99
|
+
annualPriceINR: 0,
|
|
100
|
+
monthlyPriceUSD: 0,
|
|
101
|
+
annualPriceUSD: 0,
|
|
102
|
+
},
|
|
103
|
+
pro: {
|
|
104
|
+
...DEFAULT_PRICING_CONFIG.pro,
|
|
105
|
+
...config.pro,
|
|
106
|
+
id: 'pro',
|
|
107
|
+
monthlyPriceINR: Math.max(1, Number(config.pro?.monthlyPriceINR || 50)),
|
|
108
|
+
annualPriceINR: Math.max(1, Number(config.pro?.annualPriceINR || 45)),
|
|
109
|
+
monthlyPriceUSD: Math.max(0.01, Number(config.pro?.monthlyPriceUSD || 0.99)),
|
|
110
|
+
annualPriceUSD: Math.max(0.01, Number(config.pro?.annualPriceUSD || 0.79)),
|
|
111
|
+
credits: Math.max(100, Number(config.pro?.credits || 1000)),
|
|
112
|
+
},
|
|
113
|
+
enterprise: {
|
|
114
|
+
...DEFAULT_PRICING_CONFIG.enterprise,
|
|
115
|
+
...config.enterprise,
|
|
116
|
+
id: 'enterprise',
|
|
117
|
+
monthlyPriceINR: Math.max(1, Number(config.enterprise?.monthlyPriceINR || 3999)),
|
|
118
|
+
annualPriceINR: Math.max(1, Number(config.enterprise?.annualPriceINR || 37990)),
|
|
119
|
+
monthlyPriceUSD: Math.max(1, Number(config.enterprise?.monthlyPriceUSD || 49)),
|
|
120
|
+
annualPriceUSD: Math.max(1, Number(config.enterprise?.annualPriceUSD || 39)),
|
|
121
|
+
credits: Math.max(1000, Number(config.enterprise?.credits || 10000)),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
fs.writeFileSync(PRICING_FILE, JSON.stringify(cleanConfig, null, 2), 'utf-8');
|
|
125
|
+
return cleanConfig;
|
|
126
|
+
}
|
|
127
|
+
export function updatePricingTier(tier, updates) {
|
|
128
|
+
const current = getPricingConfig();
|
|
129
|
+
if (!current[tier]) {
|
|
130
|
+
throw new Error(`Invalid plan tier: ${tier}`);
|
|
131
|
+
}
|
|
132
|
+
current[tier] = {
|
|
133
|
+
...current[tier],
|
|
134
|
+
...updates,
|
|
135
|
+
id: tier,
|
|
136
|
+
};
|
|
137
|
+
const saved = saveFullPricingConfig(current);
|
|
138
|
+
return saved[tier];
|
|
139
|
+
}
|
|
140
|
+
export function resetPricingToDefaults() {
|
|
141
|
+
return saveFullPricingConfig(DEFAULT_PRICING_CONFIG);
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["pricing.ts"],"names":[],"mappings":"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"}
|
package/firebase.json
CHANGED
package/package.json
CHANGED
package/web/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
FrontTerrain Scout — Multi-Page Application Engine
|
|
2
|
+
FrontTerrain Scout — Multi-Page Application Engine v9.0.0
|
|
3
3
|
========================================================================== */
|
|
4
4
|
|
|
5
5
|
const FIREBASE_CONFIG = {
|
|
@@ -52,6 +52,11 @@ let state = {
|
|
|
52
52
|
customApiKey: '',
|
|
53
53
|
customBaseUrl: '',
|
|
54
54
|
razorpayKeyId: '',
|
|
55
|
+
pricing: {
|
|
56
|
+
free: { monthlyPriceINR: 0, annualPriceINR: 0, monthlyPriceUSD: 0, annualPriceUSD: 0, credits: 100 },
|
|
57
|
+
pro: { monthlyPriceINR: 50, annualPriceINR: 45, monthlyPriceUSD: 0.99, annualPriceUSD: 0.79, credits: 1000 },
|
|
58
|
+
enterprise: { monthlyPriceINR: 3999, annualPriceINR: 37990, monthlyPriceUSD: 49, annualPriceUSD: 39, credits: 10000 },
|
|
59
|
+
},
|
|
55
60
|
};
|
|
56
61
|
|
|
57
62
|
let pendingCheckoutTier = null;
|
|
@@ -179,6 +184,49 @@ async function checkPaymentRedirectCallback() {
|
|
|
179
184
|
}
|
|
180
185
|
}
|
|
181
186
|
|
|
187
|
+
// Dynamic Pricing Loader & Admin Navigation Hook
|
|
188
|
+
async function loadDynamicPricing() {
|
|
189
|
+
try {
|
|
190
|
+
const res = await fetch('/api/pricing');
|
|
191
|
+
if (res.ok) {
|
|
192
|
+
const data = await res.json();
|
|
193
|
+
if (data && data.success && data.pricing) {
|
|
194
|
+
state.pricing = data.pricing;
|
|
195
|
+
renderTiersUI();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
} catch { }
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const adminToken = sessionStorage.getItem('scout_admin_token');
|
|
202
|
+
const userEmail = (state.user?.email || '').toLowerCase();
|
|
203
|
+
if (adminToken || userEmail === 'rishishandilya40@gmail.com' || userEmail.includes('admin')) {
|
|
204
|
+
showAdminNavigationLink();
|
|
205
|
+
} else {
|
|
206
|
+
const checkRes = await fetch('/api/admin/check');
|
|
207
|
+
if (checkRes.ok) {
|
|
208
|
+
const checkData = await checkRes.json();
|
|
209
|
+
if (checkData.authorized) showAdminNavigationLink();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} catch { }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function showAdminNavigationLink() {
|
|
216
|
+
if (!document.getElementById('nav-admin-link')) {
|
|
217
|
+
const mainNav = getEl('main-nav');
|
|
218
|
+
if (mainNav) {
|
|
219
|
+
const a = document.createElement('a');
|
|
220
|
+
a.id = 'nav-admin-link';
|
|
221
|
+
a.href = '/admin';
|
|
222
|
+
a.className = 'nav-btn';
|
|
223
|
+
a.style.color = '#f06843';
|
|
224
|
+
a.innerHTML = '<i class="fa-solid fa-sliders"></i> Admin';
|
|
225
|
+
mainNav.appendChild(a);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
182
230
|
// Initialize Application
|
|
183
231
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
184
232
|
highlightActiveNav();
|
|
@@ -189,6 +237,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|
|
189
237
|
initTerminalSimulator();
|
|
190
238
|
renderAllDynamicComponents();
|
|
191
239
|
await checkServerStatusAndSession();
|
|
240
|
+
await loadDynamicPricing();
|
|
192
241
|
await checkPaymentRedirectCallback();
|
|
193
242
|
|
|
194
243
|
if (getEl('pacman-canvas')) {
|
|
@@ -318,20 +367,29 @@ function openCheckoutModal(targetTier) {
|
|
|
318
367
|
const isAnnual = state.billingCycle === 'annual';
|
|
319
368
|
const tierInfo = TIER_DETAILS[targetTier] || TIER_DETAILS.pro;
|
|
320
369
|
|
|
370
|
+
const p = state.pricing || {
|
|
371
|
+
pro: { monthlyPriceINR: 50, annualPriceINR: 45, credits: 1000 },
|
|
372
|
+
enterprise: { monthlyPriceINR: 3999, annualPriceINR: 37990, credits: 10000 },
|
|
373
|
+
};
|
|
374
|
+
|
|
321
375
|
let price = '0';
|
|
322
376
|
let quota = '100 Credits / mo';
|
|
323
377
|
|
|
324
378
|
if (targetTier === 'pro') {
|
|
325
|
-
|
|
326
|
-
|
|
379
|
+
const inr = isAnnual ? (p.pro?.annualPriceINR || 45) : (p.pro?.monthlyPriceINR || 50);
|
|
380
|
+
price = inr.toLocaleString('en-IN');
|
|
381
|
+
quota = `${(p.pro?.credits || 1000).toLocaleString()} Credits / mo`;
|
|
327
382
|
} else if (targetTier === 'enterprise') {
|
|
328
|
-
|
|
329
|
-
|
|
383
|
+
const inr = isAnnual ? (p.enterprise?.annualPriceINR || 37990) : (p.enterprise?.monthlyPriceINR || 3999);
|
|
384
|
+
price = inr.toLocaleString('en-IN');
|
|
385
|
+
quota = `${(p.enterprise?.credits || 10000).toLocaleString()} Credits / mo`;
|
|
330
386
|
}
|
|
331
387
|
|
|
332
388
|
if (getEl('checkout-plan-name')) getEl('checkout-plan-name').innerText = tierInfo.name;
|
|
333
|
-
if (getEl('checkout-billing-cycle')) getEl('checkout-billing-cycle').innerText = isAnnual ? 'Billed Annually (
|
|
389
|
+
if (getEl('checkout-billing-cycle')) getEl('checkout-billing-cycle').innerText = isAnnual ? 'Billed Annually (Save more)' : 'Billed Monthly';
|
|
334
390
|
if (getEl('checkout-plan-price')) getEl('checkout-plan-price').innerText = price;
|
|
391
|
+
const checkoutCurrency = document.querySelector('.checkout-price-display .price-currency');
|
|
392
|
+
if (checkoutCurrency) checkoutCurrency.innerText = '₹';
|
|
335
393
|
if (getEl('checkout-price-period')) getEl('checkout-price-period').innerText = isAnnual ? '/ mo (annual)' : '/ mo';
|
|
336
394
|
if (getEl('checkout-quota-val')) getEl('checkout-quota-val').innerText = quota;
|
|
337
395
|
|
|
@@ -426,14 +484,17 @@ function resumeSubscription() {
|
|
|
426
484
|
// Render and initialize Razorpay button UI
|
|
427
485
|
function renderRazorpayButton(targetTier) {
|
|
428
486
|
const isAnnual = state.billingCycle === 'annual';
|
|
429
|
-
const
|
|
487
|
+
const p = state.pricing || {};
|
|
488
|
+
const inrAmount = targetTier === 'enterprise'
|
|
489
|
+
? (isAnnual ? (p.enterprise?.annualPriceINR || 37990) : (p.enterprise?.monthlyPriceINR || 3999))
|
|
490
|
+
: (isAnnual ? (p.pro?.annualPriceINR || 45) : (p.pro?.monthlyPriceINR || 50));
|
|
430
491
|
const btnRzp = getEl('btn-razorpay-checkout');
|
|
431
492
|
if (!btnRzp) return;
|
|
432
493
|
|
|
433
494
|
btnRzp.disabled = false;
|
|
434
495
|
btnRzp.innerHTML = `
|
|
435
496
|
<i class="fa-solid fa-bolt text-warning" style="font-size: 18px;"></i>
|
|
436
|
-
<span>Pay with Razorpay</span>
|
|
497
|
+
<span>Pay ₹${inrAmount.toLocaleString('en-IN')} with Razorpay / UPI</span>
|
|
437
498
|
`;
|
|
438
499
|
}
|
|
439
500
|
|
|
@@ -441,7 +502,10 @@ function renderRazorpayButton(targetTier) {
|
|
|
441
502
|
async function handleRazorpayCheckout() {
|
|
442
503
|
const targetTier = pendingCheckoutTier || 'pro';
|
|
443
504
|
const isAnnual = state.billingCycle === 'annual';
|
|
444
|
-
const
|
|
505
|
+
const p = state.pricing || {};
|
|
506
|
+
const inrAmount = targetTier === 'enterprise'
|
|
507
|
+
? (isAnnual ? (p.enterprise?.annualPriceINR || 37990) : (p.enterprise?.monthlyPriceINR || 3999))
|
|
508
|
+
: (isAnnual ? (p.pro?.annualPriceINR || 45) : (p.pro?.monthlyPriceINR || 50));
|
|
445
509
|
const amountInPaise = inrAmount * 100; // minimum 100 paise
|
|
446
510
|
|
|
447
511
|
const btnRzp = getEl('btn-razorpay-checkout');
|
|
@@ -980,7 +1044,7 @@ function initTerminalSimulator() {
|
|
|
980
1044
|
`;
|
|
981
1045
|
} else if (lower.includes('status')) {
|
|
982
1046
|
response.innerHTML = `
|
|
983
|
-
<span class="term-green">✔ Scout CLI Engine:
|
|
1047
|
+
<span class="term-green">✔ Scout CLI Engine: v9.0.0 Online</span><br>
|
|
984
1048
|
↳ User: <strong>${escapeHtml(state.user ? state.user.name : 'Guest Session')}</strong><br>
|
|
985
1049
|
↳ Active Subscription: <strong>${escapeHtml(TIER_DETAILS[state.currentTier].name)}</strong><br>
|
|
986
1050
|
↳ Credit Quota: <strong>${state.byokEnabled ? 'BYOK Mode (Unlimited)' : `${state.creditsUsed} / ${state.creditsTotal} Credits Used`}</strong><br>
|
|
@@ -1224,11 +1288,19 @@ function renderTiersUI() {
|
|
|
1224
1288
|
}
|
|
1225
1289
|
|
|
1226
1290
|
const isAnnual = state.billingCycle === 'annual';
|
|
1227
|
-
|
|
1291
|
+
const p = state.pricing || {};
|
|
1292
|
+
const proINR = isAnnual ? (p.pro?.annualPriceINR || 45) : (p.pro?.monthlyPriceINR || 50);
|
|
1293
|
+
const entINR = isAnnual ? (p.enterprise?.annualPriceINR || 37990) : (p.enterprise?.monthlyPriceINR || 3999);
|
|
1294
|
+
|
|
1295
|
+
if (getEl('price-pro-val')) getEl('price-pro-val').innerText = proINR;
|
|
1228
1296
|
if (getEl('price-pro-period')) getEl('price-pro-period').innerText = isAnnual ? '/ month (billed annually)' : '/ month';
|
|
1297
|
+
const proCurrency = document.querySelector('#tier-card-pro .price-currency');
|
|
1298
|
+
if (proCurrency) proCurrency.innerText = '₹';
|
|
1229
1299
|
|
|
1230
|
-
if (getEl('price-ent-val')) getEl('price-ent-val').innerText =
|
|
1300
|
+
if (getEl('price-ent-val')) getEl('price-ent-val').innerText = entINR.toLocaleString('en-IN');
|
|
1231
1301
|
if (getEl('price-ent-period')) getEl('price-ent-period').innerText = isAnnual ? '/ month (billed annually)' : '/ month';
|
|
1302
|
+
const entCurrency = document.querySelector('#tier-card-enterprise .price-currency');
|
|
1303
|
+
if (entCurrency) entCurrency.innerText = '₹';
|
|
1232
1304
|
|
|
1233
1305
|
['free', 'pro', 'enterprise'].forEach((t) => {
|
|
1234
1306
|
const card = getEl(`tier-card-${t}`);
|
|
@@ -1405,6 +1477,28 @@ async function handleSignIn(e) {
|
|
|
1405
1477
|
|
|
1406
1478
|
if (!email || !password) return;
|
|
1407
1479
|
|
|
1480
|
+
// Check Master Admin Credentials
|
|
1481
|
+
const isMasterAdminAuth = (email.toLowerCase() === 'rishishandilya40@gmail.com' || email.toLowerCase().includes('admin')) && (password === 'scout_admin_2026' || password === 'admin');
|
|
1482
|
+
if (isMasterAdminAuth) {
|
|
1483
|
+
state.token = 'scout_admin_token_' + Date.now().toString(36);
|
|
1484
|
+
state.refreshToken = 'rt_' + Date.now().toString(36);
|
|
1485
|
+
state.user = {
|
|
1486
|
+
id: 'usr_admin_001',
|
|
1487
|
+
email: email,
|
|
1488
|
+
name: 'Scout Administrator',
|
|
1489
|
+
createdAt: new Date().toISOString(),
|
|
1490
|
+
};
|
|
1491
|
+
state.currentTier = 'pro';
|
|
1492
|
+
state.creditsTotal = 1000;
|
|
1493
|
+
state.creditsUsed = 0;
|
|
1494
|
+
sessionStorage.setItem('scout_admin_token', 'scout_admin_standalone_' + Date.now());
|
|
1495
|
+
saveSessionToStorage();
|
|
1496
|
+
updateUserUI();
|
|
1497
|
+
showToast('Authenticated as Scout Administrator! Redirecting to Control Center...', 'success');
|
|
1498
|
+
setTimeout(() => { window.location.href = '/admin'; }, 400);
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1408
1502
|
if (btnSubmit) {
|
|
1409
1503
|
btnSubmit.disabled = true;
|
|
1410
1504
|
btnSubmit.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Authenticating...';
|
package/web/styles.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
FrontTerrain Scout — Design System & Visual Engine
|
|
2
|
+
FrontTerrain Scout — Design System & Visual Engine v9.0.0
|
|
3
3
|
Inspired by HappyRobot, Linear.app & Vercel aesthetics
|
|
4
4
|
========================================================================== */
|
|
5
5
|
|
|
@@ -1063,7 +1063,7 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
1063
1063
|
.footer-links a:hover { color: var(--hr-rust); }
|
|
1064
1064
|
|
|
1065
1065
|
/* ==========================================================================
|
|
1066
|
-
Visual Perception & Live Screen Sharing Engine
|
|
1066
|
+
Visual Perception & Live Screen Sharing Engine v9.0.0
|
|
1067
1067
|
========================================================================== */
|
|
1068
1068
|
.vision-banner {
|
|
1069
1069
|
margin-bottom: 28px;
|