diff --git a/apple-touch-icon.png b/apple-touch-icon.png new file mode 100644 index 0000000..8059d79 Binary files /dev/null and b/apple-touch-icon.png differ diff --git a/icon-192.png b/icon-192.png new file mode 100644 index 0000000..a4485db Binary files /dev/null and b/icon-192.png differ diff --git a/icon-512.png b/icon-512.png new file mode 100644 index 0000000..a1db264 Binary files /dev/null and b/icon-512.png differ diff --git a/icon-maskable-192.png b/icon-maskable-192.png new file mode 100644 index 0000000..add2cf3 Binary files /dev/null and b/icon-maskable-192.png differ diff --git a/icon-maskable-512.png b/icon-maskable-512.png new file mode 100644 index 0000000..e8887a1 Binary files /dev/null and b/icon-maskable-512.png differ diff --git a/index.html b/index.html index 797127b..35c2f0b 100644 --- a/index.html +++ b/index.html @@ -17,7 +17,16 @@ - + + + + + + + + + + @@ -350,5 +359,20 @@ + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..b92214e --- /dev/null +++ b/manifest.json @@ -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": "https://auth.auraajenticai.cloud/login?next=https%3A%2F%2Fclient.auraajenticai.cloud", + "icons": [{ "src": "/icon-192.png", "sizes": "192x192" }] + }, + { + "name": "Courier Logistics Hub", + "short_name": "Courier Hub", + "description": "Steadfast, Pathao & RedX Logistics Automation", + "url": "https://client.auraajenticai.cloud#view-courier", + "icons": [{ "src": "/icon-192.png", "sizes": "192x192" }] + }, + { + "name": "AI Agent Studio", + "short_name": "AI Studio", + "description": "Omnichannel AI Agent Copilot & Inbox", + "url": "https://client.auraajenticai.cloud#view-inbox", + "icons": [{ "src": "/icon-192.png", "sizes": "192x192" }] + } + ], + "categories": ["business", "productivity", "utilities"], + "prefer_related_applications": false +} diff --git a/src/nav.jsx b/src/nav.jsx index 00d14ea..44dcb3b 100644 --- a/src/nav.jsx +++ b/src/nav.jsx @@ -1,24 +1,43 @@ -// 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 [clientModalOpen, setClientModalOpen] = 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 +48,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 ( <>