Menu
Public repository / 7c2481f3029b7b2f8b01818af3d8e5fa55a3ea0b
AkurAI-Platform / frontend/suite-tiles.js
Latest change 7c98a6fe64be6cf4971a37c541e219b5dfcd684b - OLI-105: baseline snapshot of live platform.olibuijr.com frontend (source was missing from repo) by DevLead
// Checked-in product directory. No runtime API or account required.
const BUILD_BASE = "https://akurai-build.olibuijr.com/repos/";
const PRODUCTS = [{"id":"mail","name":"AkurAI Mail","kind":"Email","description":"Private email and a clean inbox for your own domain — no ads, no scanning.","category":"communication","visibility":"visible","url":"https://mail.olibuijr.com","buildRepo":"AkurAI-Mail","secondaryBuildRepo":"AkurAI-MailAPI","actionKey":null},{"id":"auth","name":"AkurAI Auth","kind":"Single sign-on","description":"One secure login for every AkurAI app — accounts you control, not a vendor.","category":"security","visibility":"visible","url":"https://auth.olibuijr.com","buildRepo":"AkurAI-IDP","secondaryBuildRepo":null,"actionKey":null},{"id":"vpn","name":"AkurAI VPN","kind":"Private network","description":"A private mesh network of your own — reach your machines anywhere, encrypted end to end.","category":"security","visibility":"visible","url":"https://akurai-vpn.olibuijr.com","buildRepo":"AkurAI-VPN","secondaryBuildRepo":null,"actionKey":null},{"id":"passvault","name":"AkurAI PassVault","kind":"Secret management","description":"Encrypted secrets you control, with CLI, web and MCP access.","category":"security","visibility":"visible","url":"https://akurai-passvault.olibuijr.com","buildRepo":"AkurAI-PassVault","secondaryBuildRepo":null,"actionKey":null},{"id":"drive","name":"AkurAI Drive","kind":"Cloud storage","description":"Private cloud storage — store and share files without handing them to anyone.","category":"storage","visibility":"visible","url":"https://akurai-drive.olibuijr.com","buildRepo":"AkurAI-Drive","secondaryBuildRepo":null,"actionKey":null},{"id":"notes","name":"AkurAI Notes","kind":"Note-taking with semantic search","description":"Private notes with semantic search. Runtime and data-handling details depend on the deployed workspace configuration.","category":"knowledge","visibility":"visible","url":"https://akurai-notes.olibuijr.com","buildRepo":"AkurAI-Notes","secondaryBuildRepo":null,"actionKey":null},{"id":"crm","name":"AkurAI CRM","kind":"Customer relationships","description":"Contacts, deals and follow-ups in one place — a lightweight CRM you own outright.","category":"business","visibility":"dev","url":null,"buildRepo":"AkurAI-CRM","secondaryBuildRepo":null,"actionKey":null},{"id":"tasks","name":"AkurAI Tasks","kind":"Project management","description":"Durable task tracking with boards, MCP, CLI and web access.","category":"business","visibility":"visible","url":"https://akurai-tasks.olibuijr.com","buildRepo":"akurai-tasks","secondaryBuildRepo":null,"actionKey":null},{"id":"router","name":"AkurAI Router","kind":"API gateway","description":"A single front door for AI and API traffic — routes every request to the right service.","category":"infrastructure","visibility":"visible","url":"https://akurai-router.olibuijr.com/health","buildRepo":"AkurAI-Router","secondaryBuildRepo":null,"actionKey":"app.action.status"},{"id":"monitor","name":"AkurAI Monitor","kind":"Status & uptime","description":"Service-status information when a monitored deployment reports it; unavailable or stale status remains visibly unknown.","category":"infrastructure","visibility":"visible","url":"https://monitor.olibuijr.com","buildRepo":"AkurAI-Monitor","secondaryBuildRepo":null,"actionKey":null},{"id":"dns","name":"AkurAI DNS","kind":"Domain service","description":"Authoritative DNS under your own control — your domains answer to you.","category":"infrastructure","visibility":"visible","url":null,"buildRepo":"AkurAI-DNS","secondaryBuildRepo":null,"actionKey":null},{"id":"build","name":"AkurAI Build","kind":"CI/CD","description":"The open build, artifact, and deployment pipeline for AkurAI services.","category":"infrastructure","visibility":"visible","url":"https://akurai-build.olibuijr.com","buildRepo":"AkurAI-Build","secondaryBuildRepo":null,"actionKey":null},{"id":"framework","name":"AkurAI Framework","kind":"Web runtime","description":"The shared Framework runtime used by AkurAI apps. Implementation and dependency details are documented per release.","category":"developer","visibility":"visible","url":"https://akurai-framework.olibuijr.com","buildRepo":"AkurAI-Framework","secondaryBuildRepo":null,"actionKey":null},{"id":"platform","name":"AkurAI Platform","kind":"App directory","description":"This front door — every app, its source, and its real footprint in one place.","category":"developer","visibility":"visible","url":"https://platform.olibuijr.com","buildRepo":"AkurAI-Platform","secondaryBuildRepo":null,"actionKey":null}];
const LABELS = { open: "Open", status: "Status", inDev: "In development", source: "Source" };
function tileHtml(product) {
const isDev = product.visibility === "dev";
const hasUrl = product.url && !isDev;
const action = isDev
? `<span class="tile-flag">${LABELS.inDev}</span>`
: hasUrl
? `<a class="tile-open" href="${product.url}">${product.actionKey === "app.action.status" ? LABELS.status : LABELS.open}<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 17 17 7M9 7h8v8"/></svg></a>`
: `<span class="tile-flag">${product.kind}</span>`;
let sources = `<a class="tile-src" href="${BUILD_BASE}${product.buildRepo}">${LABELS.source}: ${product.buildRepo}</a>`;
if (product.secondaryBuildRepo) sources += `<a class="tile-src" href="${BUILD_BASE}${product.secondaryBuildRepo}">${LABELS.source}: ${product.secondaryBuildRepo}</a>`;
return `<article class="tile"><span class="tile-icon"><img src="/img/icons/${product.id}.svg" alt="" width="48" height="48" loading="lazy"></span><div class="tile-body"><div class="tile-top"><h4>${product.name}</h4><span class="tile-kind">${product.kind}</span></div><p class="tile-prop">${product.description}</p></div><div class="tile-foot">${action}${sources}</div></article>`;
}
const suiteRoot = document.querySelector(".suite");
if (suiteRoot) {
for (const product of PRODUCTS) {
const grid = suiteRoot.querySelector(`.cat-grid[data-cat="${product.category}"]`);
if (grid) grid.insertAdjacentHTML("beforeend", tileHtml(product));
}
}