Compare commits

..

3 Commits

10 changed files with 481 additions and 42 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

+27 -3
View File
@@ -17,7 +17,16 @@
<meta name="twitter:image" content="https://auraajenticai.cloud/logo.png" />
<link rel="canonical" href="https://auraajenticai.cloud" />
<link rel="icon" type="image/png" href="logo.png" />
<link rel="apple-touch-icon" href="logo.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/icon-192.png" />
<link rel="icon" type="image/png" sizes="512x512" href="/icon-512.png" />
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#080d1a" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Aura Cloud" />
<meta name="google-site-verification" content="vEK4vy89hAbckU9sUlqn7mZlMxLjNT--CvuLruocMfQ" />
@@ -340,7 +349,7 @@
<script type="text/babel" src="tweaks-panel.jsx?v=9"></script>
<script type="text/babel" src="src/icons.jsx?v=9"></script>
<script type="text/babel" src="src/data.jsx?v=9"></script>
<script type="text/babel" src="src/nav.jsx?v=9"></script>
<script type="text/babel" src="src/nav.jsx?v=11"></script>
<script type="text/babel" src="src/hero.jsx?v=9"></script>
<script type="text/babel" src="src/sections.jsx?v=9"></script>
<script type="text/babel" src="src/projects.jsx?v=9"></script>
@@ -349,6 +358,21 @@
<script type="text/babel" src="src/command-palette.jsx?v=9"></script>
<script type="text/babel" src="src/chatbox.jsx?v=9"></script>
<script type="text/babel" src="src/pages.jsx?v=9"></script>
<script type="text/babel" src="src/app.jsx?v=9"></script>
<script type="text/babel" src="src/app.jsx?v=11"></script>
<!-- PWA Service Worker Registration -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js', { scope: '/' })
.then(function(reg) {
console.log('[Aura PWA] Service Worker registered with scope:', reg.scope);
})
.catch(function(err) {
console.warn('[Aura PWA] Service Worker registration failed:', err);
});
});
}
</script>
</body>
</html>
+64
View File
@@ -0,0 +1,64 @@
{
"name": "Aura Ajentic AI — Enterprise AI & Logistics Platform",
"short_name": "Aura Cloud",
"description": "Autonomous AI Sales Agents, Courier MCP logistics engine, and real-time COD fraud defense.",
"start_url": "/?source=pwa",
"scope": "/",
"display": "standalone",
"orientation": "any",
"background_color": "#080d1a",
"theme_color": "#080d1a",
"lang": "en",
"dir": "ltr",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"shortcuts": [
{
"name": "Client Portal Login",
"short_name": "Client Login",
"description": "Sign in to Aura Client Dashboard",
"url": "/?action=client-login",
"icons": [{ "src": "/icon-192.png", "sizes": "192x192" }]
},
{
"name": "Courier Logistics Hub",
"short_name": "Courier Hub",
"description": "Steadfast, Pathao & RedX Logistics Automation",
"url": "/?action=courier-hub",
"icons": [{ "src": "/icon-192.png", "sizes": "192x192" }]
},
{
"name": "AI Agent Studio",
"short_name": "AI Studio",
"description": "Omnichannel AI Agent Copilot & Inbox",
"url": "/?action=ai-studio",
"icons": [{ "src": "/icon-192.png", "sizes": "192x192" }]
}
],
"categories": ["business", "productivity", "utilities"],
"prefer_related_applications": false
}
+255 -19
View File
@@ -1,24 +1,42 @@
// Top nav — minimal, sticky, blurred — mobile-responsive
// Top nav — minimal, sticky, blurred — mobile-responsive + PWA Install & Client Gateway
const NAV_LINKS = [
{ id: "services", label: "Services", labelBn: "সার্ভিস", url: "#/services" },
{ id: "case-studies", label: "Case Studies", labelBn: "কেস স্টাডি", url: "#/case-studies" },
{ id: "pricing", label: "Pricing", labelBn: "মূল্য", url: "#/pricing" },
{ id: "blog", label: "Blog", labelBn: "ব্লগ", url: "#/blog" },
{ id: "contact", label: "Contact", labelBn: "যোগাযোগ", url: "#/contact" },
]
];
const NAV_TXT = {
en: { search: "Search", getQuote: "Get a Quote", clientLogin: "Client Login", getStarted: "Get Started" },
bn: { search: "খুঁজুন", getQuote: "কোট নিন", clientLogin: "ক্লায়েন্ট লগইন", getStarted: "শুরু করুন" },
en: {
search: "Search",
getQuote: "Get a Quote",
clientLogin: "Client Login",
getStarted: "Get Started",
installApp: "Install App",
appInstalled: "App Installed",
},
bn: {
search: "খুঁজুন",
getQuote: "কোট নিন",
clientLogin: "ক্লায়েন্ট লগইন",
getStarted: "শুরু করুন",
installApp: "অ্যাপ ইনস্টল",
appInstalled: "অ্যাপ ইনস্টলড",
},
};
// Where a self-serve account should land right after signing up -- the client portal's own
// service catalog, not a blank dashboard. aura-auth's /register already reads and honors `next`.
// Next redirects ensure clients land seamlessly in the right SaaS portal
const REGISTER_URL = "https://auth.auraajenticai.cloud/register?next=" + encodeURIComponent("https://client.auraajenticai.cloud/services");
const CLIENT_LOGIN_URL = "https://auth.auraajenticai.cloud/login?next=" + encodeURIComponent("https://client.auraajenticai.cloud");
const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }) => {
const [scrolled, setScrolled] = React.useState(false);
const [menuOpen, setMenuOpen] = React.useState(false);
const [installModalOpen, setInstallModalOpen] = React.useState(false);
const [deferredPrompt, setDeferredPrompt] = React.useState(null);
const [isInstalled, setIsInstalled] = React.useState(false);
const links = NAV_LINKS;
const t = NAV_TXT[lang] || NAV_TXT.en;
const bn = lang === "bn";
@@ -29,6 +47,49 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
return () => window.removeEventListener("scroll", onScroll);
}, []);
// PWA standalone detection & prompt listener
React.useEffect(() => {
const isStandalone = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true;
if (isStandalone) {
setIsInstalled(true);
}
const handleBeforeInstall = (e) => {
e.preventDefault();
setDeferredPrompt(e);
};
const handleAppInstalled = () => {
setIsInstalled(true);
setDeferredPrompt(null);
};
window.addEventListener("beforeinstallprompt", handleBeforeInstall);
window.addEventListener("appinstalled", handleAppInstalled);
return () => {
window.removeEventListener("beforeinstallprompt", handleBeforeInstall);
window.removeEventListener("appinstalled", handleAppInstalled);
};
}, []);
const handleInstallClick = async () => {
if (deferredPrompt) {
try {
deferredPrompt.prompt();
const choice = await deferredPrompt.userChoice;
if (choice && choice.outcome === "accepted") {
setIsInstalled(true);
setDeferredPrompt(null);
}
} catch (err) {
console.warn("PWA install prompt error:", err);
}
} else {
setInstallModalOpen(true);
}
};
return (
<>
<nav style={{
@@ -138,6 +199,32 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
{lang === "en" ? "বাং" : "EN"}
</button>
{/* PWA Install Button (Desktop) */}
{!isInstalled && (
<button
onClick={handleInstallClick}
className="nav-install-btn"
title={bn ? "Aura Cloud অ্যাপ আপনার ডিভাইসে ইনস্টল করুন" : "Install Aura Cloud App on your device"}
style={{
display: "inline-flex",
alignItems: "center",
gap: 6,
padding: "6px 11px",
background: "linear-gradient(135deg, rgba(124,92,255,0.16), rgba(0,212,255,0.16))",
border: "1px solid rgba(124,92,255,0.45)",
borderRadius: 8,
color: "var(--text)",
fontSize: 12.5,
fontWeight: 600,
cursor: "pointer",
whiteSpace: "nowrap",
}}
>
<span>📲</span>
<span>{t.installApp}</span>
</button>
)}
<a href="mailto:ceo@auraajenticai.cloud?subject=Project Quote" className="nav-quote-btn" style={{
padding: "7px 13px",
background: "transparent",
@@ -152,17 +239,21 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
{t.getQuote}
</a>
<a href="https://auth.auraajenticai.cloud/login" className="nav-login-btn" style={{
padding: "8px 12px",
background: "transparent",
border: "1px solid var(--line)",
borderRadius: 8,
color: "var(--text-dim)",
fontSize: 13,
fontWeight: 500,
textDecoration: "none",
whiteSpace: "nowrap",
}}>
<a
href={CLIENT_LOGIN_URL}
className="nav-login-btn"
style={{
padding: "8px 12px",
background: "transparent",
border: "1px solid var(--line)",
borderRadius: 8,
color: "var(--text-dim)",
fontSize: 13,
fontWeight: 500,
textDecoration: "none",
whiteSpace: "nowrap",
}}
>
{t.clientLogin}
</a>
@@ -220,6 +311,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
@media (max-width: 640px) {
.nav-search-btn { display: none !important; }
.nav-quote-btn { display: none !important; }
.nav-install-btn { display: none !important; }
.nav-badge { display: none !important; }
}
@media (max-width: 480px) {
@@ -246,7 +338,51 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
display: "flex",
flexDirection: "column",
gap: 2,
maxHeight: "calc(100vh - 64px)",
overflowY: "auto",
}}>
{/* Mobile PWA Install Banner */}
{!isInstalled && (
<div style={{
padding: "12px 14px",
borderRadius: 12,
background: "linear-gradient(135deg, rgba(124,92,255,0.18), rgba(0,212,255,0.18))",
border: "1px solid rgba(124,92,255,0.35)",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
marginBottom: 10,
}}>
<div>
<div style={{ fontWeight: 600, fontSize: 13, color: "var(--text)" }}>
{bn ? "📲 Aura Cloud অ্যাপ" : "📲 Aura Cloud App"}
</div>
<div style={{ fontSize: 11, color: "var(--text-dim)", marginTop: 2 }}>
{bn ? "হোমস্ক্রিনে ১-ট্যাপে ইনস্টল করুন" : "Install to home screen for 1-tap launch"}
</div>
</div>
<button
onClick={() => {
setMenuOpen(false);
handleInstallClick();
}}
style={{
padding: "6px 12px",
background: "var(--text)",
color: "var(--bg)",
border: "none",
borderRadius: 8,
fontSize: 12,
fontWeight: 600,
cursor: "pointer",
whiteSpace: "nowrap",
}}
>
{bn ? "ইনস্টল" : "Install"}
</button>
</div>
)}
{links.map(l => (
<a
key={l.id}
@@ -298,9 +434,9 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
fontSize: 13,
textDecoration: "none",
}}
>{t.getQuote}</a>
>{t.quote}</a>
<a
href="https://auth.auraajenticai.cloud/login"
href={CLIENT_LOGIN_URL}
onClick={() => setMenuOpen(false)}
style={{
padding: "8px 14px",
@@ -329,6 +465,106 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }
</div>
</div>
)}
{/* PWA Install Help Modal (iOS & Fallback) */}
{installModalOpen && (
<div
onClick={() => setInstallModalOpen(false)}
style={{
position: "fixed",
inset: 0,
zIndex: 100,
background: "rgba(0, 0, 0, 0.72)",
backdropFilter: "blur(10px)",
WebkitBackdropFilter: "blur(10px)",
display: "grid",
placeItems: "center",
padding: 16,
}}
>
<div
onClick={(e) => e.stopPropagation()}
style={{
position: "relative",
width: "100%",
maxWidth: 440,
background: "var(--bg-card, #0c1222)",
border: "1px solid rgba(0, 212, 255, 0.35)",
borderRadius: 16,
padding: "24px 22px",
boxShadow: "0 24px 60px rgba(0, 0, 0, 0.6)",
}}
>
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<span style={{ fontSize: 22 }}>📲</span>
<h3 style={{ margin: 0, fontSize: 16, fontWeight: 600, color: "var(--text)" }}>
{bn ? "Aura Cloud অ্যাপ ইনস্টল গাইড" : "Install Aura Cloud App"}
</h3>
</div>
<button
onClick={() => setInstallModalOpen(false)}
style={{ background: "transparent", border: "none", color: "var(--text-dim)", cursor: "pointer", fontSize: 18 }}
>
✕
</button>
</div>
<p style={{ fontSize: 13, color: "var(--text-dim)", lineHeight: 1.5, margin: "0 0 16px" }}>
{bn
? "Aura Cloud অ্যাপ আপনার মোবাইল বা কম্পিউটারে ইনস্টল করে সরাসরি ১-ট্যাপে ওপেন করুন:"
: "Install the Aura Cloud App directly to your device for 1-tap instant launch and offline access:"}
</p>
<div style={{ display: "flex", flexDirection: "column", gap: 10, fontSize: 12.5, color: "var(--text)" }}>
<div style={{ padding: "10px 12px", background: "rgba(255,255,255,0.03)", borderRadius: 8, border: "1px solid var(--line)" }}>
<strong>🍏 iOS / iPhone (Safari):</strong>
<div style={{ color: "var(--text-dim)", marginTop: 4 }}>
{bn
? "সাফারি ব্রাউজারের নিচে শেয়ার বাটনে (Share ⎋) ট্যাপ করুন, এরপর নিচে স্ক্রল করে 'Add to Home Screen ⊞' সিলেক্ট করুন।"
: "Tap the Share icon (⎋) at bottom of Safari, scroll down and tap 'Add to Home Screen ⊞'."}
</div>
</div>
<div style={{ padding: "10px 12px", background: "rgba(255,255,255,0.03)", borderRadius: 8, border: "1px solid var(--line)" }}>
<strong>🤖 Android (Chrome):</strong>
<div style={{ color: "var(--text-dim)", marginTop: 4 }}>
{bn
? "ব্রাউজারের উপরের ডান কোণায় ৩-ডট মেনুতে (⋮) ট্যাপ করে 'Install app' বা 'Add to Home screen' নির্বাচন করুন।"
: "Tap the 3 dots menu (⋮) in Chrome and select 'Install app' or 'Add to Home screen'."}
</div>
</div>
<div style={{ padding: "10px 12px", background: "rgba(255,255,255,0.03)", borderRadius: 8, border: "1px solid var(--line)" }}>
<strong>💻 Windows / Mac (Chrome & Edge):</strong>
<div style={{ color: "var(--text-dim)", marginTop: 4 }}>
{bn
? "ব্রাউজারের অ্যাড্রেস বারের ডানপাশে ইনস্টল আইকন (⊕) ক্লিক করে ইনস্টল করুন।"
: "Click the Install icon (⊕) in the browser address bar to install to desktop."}
</div>
</div>
</div>
<button
onClick={() => setInstallModalOpen(false)}
style={{
width: "100%",
marginTop: 18,
padding: "10px",
background: "var(--text)",
color: "var(--bg)",
border: "none",
borderRadius: 8,
fontWeight: 600,
fontSize: 13,
cursor: "pointer",
}}
>
{bn ? "ঠিক আছে, বুঝেছি" : "Got it"}
</button>
</div>
</div>
)}
</>
);
};
+81
View File
@@ -0,0 +1,81 @@
// Aura Cloud Service Worker — High-Performance Offline & Shell Cache v2.0
const CACHE_NAME = 'aura-cloud-pwa-v3';
const STATIC_PRECACHE = [
'/',
'/index.html',
'/manifest.json',
'/logo.png',
'/apple-touch-icon.png',
'/icon-192.png',
'/icon-512.png',
'/icon-maskable-192.png',
'/icon-maskable-512.png',
'/privacy.html',
'/terms.html'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(STATIC_PRECACHE).catch((err) => {
console.warn('[Aura PWA SW] Pre-cache initial warning:', err);
});
}).then(() => self.skipWaiting())
);
});
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) => {
return Promise.all(
keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k))
);
}).then(() => self.clients.claim())
);
});
self.addEventListener('fetch', (event) => {
const req = event.request;
const url = new URL(req.url);
// 1. Bypass external/cross-origin requests (Auth, Analytics, Fonts, APIs)
if (url.origin !== self.location.origin) {
return;
}
// 2. Network-first strategy for navigation / HTML routes (instant updates)
if (req.mode === 'navigate' || req.headers.get('accept')?.includes('text/html')) {
event.respondWith(
fetch(req)
.then((networkRes) => {
if (networkRes && networkRes.ok) {
const clone = networkRes.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(req, clone));
}
return networkRes;
})
.catch(() => {
return caches.match(req).then((cached) => cached || caches.match('/index.html'));
})
);
return;
}
// 3. Stale-while-revalidate for same-origin static assets
event.respondWith(
caches.match(req).then((cached) => {
const fetchPromise = fetch(req)
.then((networkRes) => {
if (networkRes && networkRes.ok) {
const clone = networkRes.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(req, clone));
}
return networkRes;
})
.catch(() => null);
return cached || fetchPromise;
})
);
});
+54 -20
View File
@@ -1,6 +1,51 @@
{
"cleanUrls": false,
"trailingSlash": false,
"headers": [
{
"source": "/sw.js",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache, no-store, must-revalidate"
},
{
"key": "Service-Worker-Allowed",
"value": "/"
}
]
},
{
"source": "/manifest.json",
"headers": [
{
"key": "Content-Type",
"value": "application/manifest+json; charset=utf-8"
},
{
"key": "Cache-Control",
"value": "public, max-age=3600"
}
]
},
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
}
]
}
],
"rewrites": [
{
"source": "/privacy",
@@ -19,27 +64,16 @@
"destination": "/terms.html"
},
{
"source": "/((?!privacy|terms).*)",
"destination": "/index.html"
}
],
"headers": [
"source": "/manifest.json",
"destination": "/manifest.json"
},
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
}
]
"source": "/sw.js",
"destination": "/sw.js"
},
{
"source": "/((?!privacy|terms|manifest\\.json|sw\\.js|.*\\.(?:png|jpg|jpeg|svg|ico|json|js|css|webmanifest)).*)",
"destination": "/index.html"
}
]
}