- Update UI server module - Update suite index and JavaScript files - Add public directory Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2422 lines
118 KiB
HTML
2422 lines
118 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>Chat - General Bots</title>
|
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
|
<meta
|
|
name="description"
|
|
content="General Bots - AI-powered workspace"
|
|
/>
|
|
<meta name="theme-color" content="#d4f505" />
|
|
|
|
<!-- Critical CSS - minimal styles for shell/layout (loaded sync) -->
|
|
<link rel="stylesheet" href="suite/css/app.css" />
|
|
<link rel="stylesheet" href="suite/css/base.css" />
|
|
<link rel="stylesheet" href="suite/css/theme-sentient.css" />
|
|
|
|
<!-- Non-critical CSS - loaded async for faster initial paint -->
|
|
<link
|
|
rel="stylesheet"
|
|
href="suite/css/components.css"
|
|
media="print"
|
|
onload="this.media='all'"
|
|
/>
|
|
<link
|
|
rel="stylesheet"
|
|
href="suite/css/partials.css"
|
|
media="print"
|
|
onload="this.media='all'"
|
|
/>
|
|
<link
|
|
rel="stylesheet"
|
|
href="suite/css/apps-extended.css"
|
|
media="print"
|
|
onload="this.media='all'"
|
|
/>
|
|
<noscript>
|
|
<link rel="stylesheet" href="suite/css/components.css" />
|
|
<link rel="stylesheet" href="suite/css/partials.css" />
|
|
<link rel="stylesheet" href="suite/css/apps-extended.css" />
|
|
</noscript>
|
|
|
|
<!-- App-specific CSS loaded lazily by each view via CSSLoader -->
|
|
|
|
<!-- Local Libraries (no external CDN dependencies) -->
|
|
<script src="suite/js/vendor/htmx.min.js"></script>
|
|
<script src="suite/js/vendor/htmx-ws.js"></script>
|
|
<script src="suite/js/vendor/htmx-json-enc.js"></script>
|
|
<script src="suite/js/vendor/marked.min.js"></script>
|
|
|
|
<!-- SECURITY BOOTSTRAP - MUST load immediately after HTMX -->
|
|
<!-- This provides centralized auth for ALL apps: HTMX, fetch, XHR -->
|
|
<script src="suite/js/security-bootstrap.js?v=20260207b"></script>
|
|
|
|
<!-- ERROR REPORTER - Captures JS errors and sends to server log -->
|
|
<script src="suite/js/error-reporter.js?v=20260207c"></script>
|
|
|
|
<!-- i18n -->
|
|
<script src="suite/js/i18n.js"></script>
|
|
|
|
<!-- CSS Lazy Loader - enables per-screen CSS loading -->
|
|
<script src="suite/js/css-loader.js"></script>
|
|
|
|
<!-- Enable HTMX to process inline scripts in swapped content -->
|
|
<script>
|
|
htmx.config.allowEval = true;
|
|
htmx.config.includeIndicatorStyles = false;
|
|
htmx.config.timeout = 300000; // 5 minutes for long-running LLM operations
|
|
|
|
// Global error handler to catch HTMX DOM manipulation errors
|
|
window.addEventListener("error", function (event) {
|
|
// Catch insertBefore errors from HTMX swap operations
|
|
if (
|
|
event.message &&
|
|
event.message.includes("insertBefore") &&
|
|
event.message.includes("null")
|
|
) {
|
|
console.warn(
|
|
"HTMX DOM error caught and suppressed:",
|
|
event.message,
|
|
);
|
|
event.preventDefault();
|
|
return true;
|
|
}
|
|
});
|
|
|
|
// Handle unhandled promise rejections from HTMX
|
|
window.addEventListener("unhandledrejection", function (event) {
|
|
if (
|
|
event.reason &&
|
|
event.reason.message &&
|
|
event.reason.message.includes("insertBefore")
|
|
) {
|
|
console.warn(
|
|
"HTMX promise rejection caught:",
|
|
event.reason.message,
|
|
);
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
</script>
|
|
</head>
|
|
|
|
<body data-theme="light">
|
|
<!-- Loading overlay -->
|
|
<div class="loading-overlay" id="loadingOverlay">
|
|
<div class="loading-spinner"></div>
|
|
</div>
|
|
|
|
<!-- Floating header -->
|
|
<header class="float-header" role="banner">
|
|
<!-- Left: Logo + App Tabs -->
|
|
<div class="header-left">
|
|
<button
|
|
class="logo-wrapper"
|
|
hx-get="/suite/home.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#home"
|
|
title="General Bots"
|
|
aria-label="General Bots - Home"
|
|
>
|
|
<svg
|
|
class="logo-icon"
|
|
width="32"
|
|
height="20"
|
|
viewBox="0 0 140 80"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<!-- Left antenna -->
|
|
<line x1="5" y1="40" x2="25" y2="40" />
|
|
<line x1="25" y1="28" x2="25" y2="52" />
|
|
<!-- Left gear (outer) -->
|
|
<circle cx="50" cy="40" r="16" />
|
|
<!-- Left gear (inner) -->
|
|
<circle cx="50" cy="40" r="6" />
|
|
<!-- Left gear teeth -->
|
|
<line x1="50" y1="20" x2="50" y2="26" />
|
|
<line x1="50" y1="54" x2="50" y2="60" />
|
|
<line x1="30" y1="40" x2="36" y2="40" />
|
|
<line x1="64" y1="40" x2="70" y2="40" />
|
|
<line x1="38" y1="28" x2="42" y2="32" />
|
|
<line x1="58" y1="48" x2="62" y2="52" />
|
|
<line x1="38" y1="52" x2="42" y2="48" />
|
|
<line x1="58" y1="32" x2="62" y2="28" />
|
|
<!-- Right gear (outer) -->
|
|
<circle cx="90" cy="40" r="16" />
|
|
<!-- Right gear (inner) -->
|
|
<circle cx="90" cy="40" r="6" />
|
|
<!-- Right gear teeth -->
|
|
<line x1="90" y1="20" x2="90" y2="26" />
|
|
<line x1="90" y1="54" x2="90" y2="60" />
|
|
<line x1="70" y1="40" x2="76" y2="40" />
|
|
<line x1="104" y1="40" x2="110" y2="40" />
|
|
<line x1="78" y1="28" x2="82" y2="32" />
|
|
<line x1="98" y1="48" x2="102" y2="52" />
|
|
<line x1="78" y1="52" x2="82" y2="48" />
|
|
<line x1="98" y1="32" x2="102" y2="28" />
|
|
<!-- Right antenna -->
|
|
<line x1="115" y1="40" x2="135" y2="40" />
|
|
<line x1="115" y1="28" x2="115" y2="52" />
|
|
</svg>
|
|
</button>
|
|
|
|
<!-- Main App Tabs -->
|
|
<nav class="header-app-tabs">
|
|
<!-- SECTION:chat -->
|
|
<a
|
|
class="app-tab active"
|
|
href="#chat"
|
|
data-section="chat"
|
|
hx-get="/suite/chat/chat.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#chat"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
/>
|
|
</svg>
|
|
<span data-i18n="nav-chat">Chat</span>
|
|
</a>
|
|
<!-- ENDSECTION:chat -->
|
|
<!-- SECTION:mail -->
|
|
<a
|
|
class="app-tab"
|
|
href="#mail"
|
|
data-section="mail"
|
|
hx-get="/suite/mail/mail.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#mail"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"
|
|
/>
|
|
<polyline points="22,6 12,13 2,6" />
|
|
</svg>
|
|
<span data-i18n="nav-mail">E-mail</span>
|
|
</a>
|
|
<!-- ENDSECTION:mail -->
|
|
<!-- SECTION:calendar -->
|
|
<a
|
|
class="app-tab"
|
|
href="#calendar"
|
|
data-section="calendar"
|
|
hx-get="/suite/calendar/calendar.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#calendar"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="4"
|
|
width="18"
|
|
height="18"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="16" y1="2" x2="16" y2="6" />
|
|
<line x1="8" y1="2" x2="8" y2="6" />
|
|
<line x1="3" y1="10" x2="21" y2="10" />
|
|
</svg>
|
|
<span data-i18n="nav-calendar">Calendário</span>
|
|
</a>
|
|
<!-- ENDSECTION:calendar -->
|
|
<!-- SECTION:drive -->
|
|
<a
|
|
class="app-tab"
|
|
href="#drive"
|
|
data-section="drive"
|
|
hx-get="/suite/drive/drive.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#drive"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
|
|
/>
|
|
</svg>
|
|
<span data-i18n="nav-drive">Arquivos</span>
|
|
</a>
|
|
<!-- ENDSECTION:drive -->
|
|
<!-- SECTION:tasks -->
|
|
<a
|
|
class="app-tab"
|
|
href="#tasks"
|
|
data-section="tasks"
|
|
hx-get="/suite/tasks/autotask.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#tasks"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path d="M9 11l3 3L22 4" />
|
|
<path
|
|
d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"
|
|
/>
|
|
</svg>
|
|
<span data-i18n="nav-tasks">Tarefas</span>
|
|
</a>
|
|
<!-- ENDSECTION:tasks -->
|
|
<!-- SECTION:crm -->
|
|
<a
|
|
class="app-tab"
|
|
href="#crm"
|
|
data-section="crm"
|
|
hx-get="/suite/crm/crm.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#crm"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
|
|
/>
|
|
<circle cx="9" cy="7" r="4" />
|
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
|
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
|
</svg>
|
|
<span data-i18n="nav-crm">CRM</span>
|
|
</a>
|
|
<!-- ENDSECTION:crm -->
|
|
<!-- SECTION:docs -->
|
|
<a
|
|
class="app-tab"
|
|
href="#docs"
|
|
data-section="docs"
|
|
hx-get="/suite/docs/docs.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#docs"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
|
|
/>
|
|
<polyline points="14 2 14 8 20 8" />
|
|
<line x1="16" y1="13" x2="8" y2="13" />
|
|
<line x1="16" y1="17" x2="8" y2="17" />
|
|
</svg>
|
|
<span data-i18n="nav-docs">Docs</span>
|
|
</a>
|
|
<!-- ENDSECTION:docs -->
|
|
<!-- SECTION:sheet -->
|
|
<a
|
|
class="app-tab"
|
|
href="#sheet"
|
|
data-section="sheet"
|
|
hx-get="/suite/sheet/sheet.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#sheet"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="3"
|
|
width="18"
|
|
height="18"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="3" y1="9" x2="21" y2="9" />
|
|
<line x1="3" y1="15" x2="21" y2="15" />
|
|
<line x1="9" y1="3" x2="9" y2="21" />
|
|
<line x1="15" y1="3" x2="15" y2="21" />
|
|
</svg>
|
|
<span data-i18n="nav-sheet">Planilhas</span>
|
|
</a>
|
|
<!-- ENDSECTION:sheet -->
|
|
<!-- SECTION:slides -->
|
|
<a
|
|
class="app-tab"
|
|
href="#slides"
|
|
data-section="slides"
|
|
hx-get="/suite/slides/slides.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#slides"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="2"
|
|
y="3"
|
|
width="20"
|
|
height="14"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="8" y1="21" x2="16" y2="21" />
|
|
<line x1="12" y1="17" x2="12" y2="21" />
|
|
</svg>
|
|
<span data-i18n="nav-slides">Apresentações</span>
|
|
</a>
|
|
<!-- ENDSECTION:slides -->
|
|
<!-- SECTION:social -->
|
|
<a
|
|
class="app-tab"
|
|
href="#social"
|
|
data-section="social"
|
|
hx-get="/suite/social/social.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#social"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
|
|
/>
|
|
<circle cx="9" cy="7" r="4" />
|
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
|
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
|
</svg>
|
|
<span data-i18n="nav-social">Social</span>
|
|
</a>
|
|
<!-- ENDSECTION:social -->
|
|
</nav>
|
|
|
|
<!-- Apps menu container (button + dropdown) -->
|
|
<div class="apps-menu-container" style="position: relative">
|
|
<button
|
|
class="icon-button apps-button"
|
|
id="appsButton"
|
|
title="All Applications"
|
|
aria-label="Open applications menu"
|
|
aria-expanded="false"
|
|
aria-haspopup="true"
|
|
>
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="currentColor"
|
|
aria-hidden="true"
|
|
>
|
|
<circle cx="5" cy="12" r="2.5"></circle>
|
|
<circle cx="12" cy="12" r="2.5"></circle>
|
|
<circle cx="19" cy="12" r="2.5"></circle>
|
|
</svg>
|
|
</button>
|
|
|
|
<!-- Apps dropdown menu -->
|
|
<nav
|
|
class="apps-dropdown"
|
|
id="appsDropdown"
|
|
role="menu"
|
|
aria-label="Applications"
|
|
>
|
|
<div
|
|
class="apps-dropdown-title"
|
|
data-i18n="nav-all-apps"
|
|
>
|
|
All Applications
|
|
</div>
|
|
<div class="app-grid" role="group">
|
|
<!-- =================================== -->
|
|
<!-- DYNAMIC ITEMS (Header Tab Apps) -->
|
|
<!-- These hide/show based on screen -->
|
|
<!-- =================================== -->
|
|
|
|
<!-- Chat -->
|
|
<!-- SECTION:chat -->
|
|
<a
|
|
class="app-item active"
|
|
href="#chat"
|
|
data-section="chat"
|
|
role="menuitem"
|
|
aria-label="Chat application"
|
|
hx-get="/suite/chat/chat.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#chat"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-chat">Chat</span>
|
|
</a>
|
|
<!-- ENDSECTION:chat -->
|
|
|
|
<!-- Mail -->
|
|
<!-- SECTION:mail -->
|
|
<a
|
|
class="app-item"
|
|
href="#mail"
|
|
data-section="mail"
|
|
role="menuitem"
|
|
aria-label="Mail application"
|
|
hx-get="/suite/mail/mail.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#mail"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"
|
|
/>
|
|
<polyline points="22,6 12,13 2,6" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-mail">E-mail</span>
|
|
</a>
|
|
<!-- ENDSECTION:mail -->
|
|
|
|
<!-- Calendar -->
|
|
<!-- SECTION:calendar -->
|
|
<a
|
|
class="app-item"
|
|
href="#calendar"
|
|
data-section="calendar"
|
|
role="menuitem"
|
|
aria-label="Calendar application"
|
|
hx-get="/suite/calendar/calendar.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#calendar"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="4"
|
|
width="18"
|
|
height="18"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="16" y1="2" x2="16" y2="6" />
|
|
<line x1="8" y1="2" x2="8" y2="6" />
|
|
<line x1="3" y1="10" x2="21" y2="10" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-calendar">Calendário</span>
|
|
</a>
|
|
<!-- ENDSECTION:calendar -->
|
|
|
|
<!-- Drive -->
|
|
<!-- SECTION:drive -->
|
|
<a
|
|
class="app-item"
|
|
href="#drive"
|
|
data-section="drive"
|
|
role="menuitem"
|
|
aria-label="Drive application"
|
|
hx-get="/suite/drive/drive.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#drive"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-drive">Arquivos</span>
|
|
</a>
|
|
<!-- ENDSECTION:drive -->
|
|
|
|
<!-- Tasks -->
|
|
<!-- SECTION:tasks -->
|
|
<a
|
|
class="app-item"
|
|
href="#tasks"
|
|
data-section="tasks"
|
|
role="menuitem"
|
|
aria-label="Tasks application"
|
|
hx-get="/suite/tasks/autotask.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#tasks"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path d="M9 11l3 3L22 4" />
|
|
<path
|
|
d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-tasks">Tarefas</span>
|
|
</a>
|
|
<!-- ENDSECTION:tasks -->
|
|
|
|
<!-- Docs -->
|
|
<!-- SECTION:docs -->
|
|
<a
|
|
class="app-item"
|
|
href="#docs"
|
|
data-section="docs"
|
|
role="menuitem"
|
|
aria-label="Docs - Documents"
|
|
hx-get="/suite/docs/docs.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#docs"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
|
|
/>
|
|
<polyline points="14 2 14 8 20 8" />
|
|
<line x1="16" y1="13" x2="8" y2="13" />
|
|
<line x1="16" y1="17" x2="8" y2="17" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-docs">Docs</span>
|
|
</a>
|
|
<!-- ENDSECTION:docs -->
|
|
|
|
<!-- Sheet -->
|
|
<!-- SECTION:sheet -->
|
|
<a
|
|
class="app-item"
|
|
href="#sheet"
|
|
data-section="sheet"
|
|
role="menuitem"
|
|
aria-label="Sheet - Spreadsheets"
|
|
hx-get="/suite/sheet/sheet.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#sheet"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="3"
|
|
width="18"
|
|
height="18"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="3" y1="9" x2="21" y2="9" />
|
|
<line x1="3" y1="15" x2="21" y2="15" />
|
|
<line x1="9" y1="3" x2="9" y2="21" />
|
|
<line x1="15" y1="3" x2="15" y2="21" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-sheet">Planilhas</span>
|
|
</a>
|
|
<!-- ENDSECTION:sheet -->
|
|
|
|
<!-- Slides -->
|
|
<!-- SECTION:slides -->
|
|
<a
|
|
class="app-item"
|
|
href="#slides"
|
|
data-section="slides"
|
|
role="menuitem"
|
|
aria-label="Slides - Presentations"
|
|
hx-get="/suite/slides/slides.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#slides"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="2"
|
|
y="3"
|
|
width="20"
|
|
height="14"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="8" y1="21" x2="16" y2="21" />
|
|
<line x1="12" y1="17" x2="12" y2="21" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-slides"
|
|
>Apresentações</span
|
|
>
|
|
</a>
|
|
<!-- ENDSECTION:slides -->
|
|
|
|
<!-- Social -->
|
|
<!-- SECTION:social -->
|
|
<a
|
|
class="app-item"
|
|
href="#social"
|
|
data-section="social"
|
|
role="menuitem"
|
|
aria-label="Social Network"
|
|
hx-get="/suite/social/social.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#social"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
|
|
/>
|
|
<circle cx="9" cy="7" r="4" />
|
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
|
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-social">Social</span>
|
|
</a>
|
|
<!-- ENDSECTION:social -->
|
|
|
|
<!-- =================================== -->
|
|
<!-- STATIC ITEMS (Always visible) -->
|
|
<!-- =================================== -->
|
|
|
|
<!-- People (Contacts) - First static item after dynamic -->
|
|
<!-- SECTION:people -->
|
|
<a
|
|
class="app-item"
|
|
href="#people"
|
|
data-section="people"
|
|
role="menuitem"
|
|
aria-label="People - Contacts"
|
|
hx-get="/suite/people/people.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#people"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
|
|
/>
|
|
<circle cx="9" cy="7" r="4" />
|
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
|
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-people">People</span>
|
|
</a>
|
|
<!-- ENDSECTION:people -->
|
|
|
|
<!-- CRM -->
|
|
<!-- SECTION:crm -->
|
|
<a
|
|
class="app-item"
|
|
href="#crm"
|
|
data-section="crm"
|
|
role="menuitem"
|
|
aria-label="CRM - Customer Relationship Management"
|
|
hx-get="/suite/crm/crm.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#crm"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"
|
|
/>
|
|
<circle cx="9" cy="7" r="4" />
|
|
<path d="M22 21v-2a4 4 0 0 0-3-3.87" />
|
|
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
|
<line x1="19" y1="8" x2="19" y2="14" />
|
|
<line x1="22" y1="11" x2="16" y2="11" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-crm">CRM</span>
|
|
</a>
|
|
<!-- ENDSECTION:crm -->
|
|
|
|
<!-- Billing -->
|
|
<!-- SECTION:billing -->
|
|
<a
|
|
class="app-item"
|
|
href="#billing"
|
|
data-section="billing"
|
|
role="menuitem"
|
|
aria-label="Billing - Invoices & Payments"
|
|
hx-get="/suite/billing/billing.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#billing"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="1"
|
|
y="4"
|
|
width="22"
|
|
height="16"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<line x1="1" y1="10" x2="23" y2="10" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-billing">Billing</span>
|
|
</a>
|
|
<!-- ENDSECTION:billing -->
|
|
|
|
<!-- Products -->
|
|
<!-- SECTION:products -->
|
|
<a
|
|
class="app-item"
|
|
href="#products"
|
|
data-section="products"
|
|
role="menuitem"
|
|
aria-label="Products - Product & Service Catalog"
|
|
hx-get="/suite/products/products.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#products"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
|
/>
|
|
<polyline
|
|
points="3.27 6.96 12 12.01 20.73 6.96"
|
|
/>
|
|
<line
|
|
x1="12"
|
|
y1="22.08"
|
|
x2="12"
|
|
y2="12"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-products">Products</span>
|
|
</a>
|
|
<!-- ENDSECTION:products -->
|
|
|
|
<!-- Tickets -->
|
|
<!-- SECTION:tickets -->
|
|
<a
|
|
class="app-item"
|
|
href="#tickets"
|
|
data-section="tickets"
|
|
role="menuitem"
|
|
aria-label="Tickets - Support Cases"
|
|
hx-get="/suite/tickets/tickets.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#tickets"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
|
|
/>
|
|
<polyline points="14 2 14 8 20 8" />
|
|
<line x1="16" y1="13" x2="8" y2="13" />
|
|
<line x1="16" y1="17" x2="8" y2="17" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-tickets">Tickets</span>
|
|
</a>
|
|
<!-- ENDSECTION:tickets -->
|
|
|
|
<!-- Paper -->
|
|
<!-- SECTION:paper -->
|
|
<a
|
|
class="app-item"
|
|
href="#paper"
|
|
data-section="paper"
|
|
role="menuitem"
|
|
aria-label="Paper"
|
|
hx-get="/suite/paper/paper.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#paper"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"
|
|
/>
|
|
<polyline points="14 2 14 8 20 8" />
|
|
<line x1="16" y1="13" x2="8" y2="13" />
|
|
<line x1="16" y1="17" x2="8" y2="17" />
|
|
<line x1="10" y1="9" x2="8" y2="9" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-paper">Paper</span>
|
|
</a>
|
|
<!-- ENDSECTION:paper -->
|
|
|
|
<!-- Editor -->
|
|
<!-- SECTION:editor -->
|
|
<a
|
|
class="app-item"
|
|
href="#editor"
|
|
data-section="editor"
|
|
role="menuitem"
|
|
aria-label="Editor - Code & Text"
|
|
hx-get="/editor.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#editor"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<polyline points="16 18 22 12 16 6" />
|
|
<polyline points="8 6 2 12 8 18" />
|
|
<line x1="12" y1="2" x2="12" y2="22" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-editor">Editor</span>
|
|
</a>
|
|
<!-- ENDSECTION:editor -->
|
|
|
|
<!-- SECTION:research -->
|
|
|
|
<a
|
|
class="app-item"
|
|
href="#research"
|
|
data-section="research"
|
|
role="menuitem"
|
|
aria-label="Research application"
|
|
hx-get="/suite/research/research.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#research"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="11" cy="11" r="8" />
|
|
<path d="m21 21-4.35-4.35" />
|
|
<path d="M11 8v6M8 11h6" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-research">Pesquisa</span>
|
|
</a>
|
|
|
|
<!-- ENDSECTION:research -->
|
|
|
|
<!-- Meet -->
|
|
<!-- SECTION:meet -->
|
|
<a
|
|
class="app-item"
|
|
href="#meet"
|
|
data-section="meet"
|
|
role="menuitem"
|
|
aria-label="Meet application"
|
|
hx-get="/suite/meet/meet.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#meet"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<polygon
|
|
points="23 7 16 12 23 17 23 7"
|
|
/>
|
|
<rect
|
|
x="1"
|
|
y="5"
|
|
width="15"
|
|
height="14"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-meet">Reuniões</span>
|
|
</a>
|
|
<!-- ENDSECTION:meet -->
|
|
|
|
<!-- Analytics -->
|
|
<!-- SECTION:analytics -->
|
|
<a
|
|
class="app-item"
|
|
href="#analytics"
|
|
data-section="analytics"
|
|
role="menuitem"
|
|
aria-label="Analytics Dashboard"
|
|
hx-get="/suite/analytics/analytics.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#analytics"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<line x1="18" y1="20" x2="18" y2="10" />
|
|
<line x1="12" y1="20" x2="12" y2="4" />
|
|
<line x1="6" y1="20" x2="6" y2="14" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-analytics">Analytics</span>
|
|
</a>
|
|
<!-- ENDSECTION:analytics -->
|
|
|
|
<!-- Dashboards -->
|
|
<!-- SECTION:dashboards -->
|
|
<a
|
|
class="app-item"
|
|
href="#dashboards"
|
|
data-section="dashboards"
|
|
role="menuitem"
|
|
aria-label="Custom Dashboards"
|
|
hx-get="/suite/dashboards/dashboards.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#dashboards"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="3"
|
|
width="7"
|
|
height="7"
|
|
rx="1"
|
|
/>
|
|
<rect
|
|
x="14"
|
|
y="3"
|
|
width="7"
|
|
height="7"
|
|
rx="1"
|
|
/>
|
|
<rect
|
|
x="3"
|
|
y="14"
|
|
width="7"
|
|
height="7"
|
|
rx="1"
|
|
/>
|
|
<rect
|
|
x="14"
|
|
y="14"
|
|
width="7"
|
|
height="7"
|
|
rx="1"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-dashboards"
|
|
>Dashboards</span
|
|
>
|
|
</a>
|
|
<!-- ENDSECTION:dashboards -->
|
|
|
|
<!-- Monitoring -->
|
|
<!-- SECTION:monitoring -->
|
|
<a
|
|
class="app-item"
|
|
href="#monitoring"
|
|
data-section="monitoring"
|
|
role="menuitem"
|
|
aria-label="System Monitoring"
|
|
hx-get="/suite/monitoring/monitoring.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#monitoring"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="12" cy="12" r="10" />
|
|
<circle cx="12" cy="12" r="6" />
|
|
<circle cx="12" cy="12" r="2" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-monitoring"
|
|
>Monitoring</span
|
|
>
|
|
</a>
|
|
<!-- ENDSECTION:monitoring -->
|
|
|
|
<!-- Sources -->
|
|
<!-- SECTION:sources -->
|
|
<a
|
|
class="app-item"
|
|
href="#sources"
|
|
data-section="sources"
|
|
role="menuitem"
|
|
aria-label="Data Sources"
|
|
hx-get="/suite/sources/index.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#sources"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<ellipse cx="12" cy="5" rx="9" ry="3" />
|
|
<path
|
|
d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"
|
|
/>
|
|
<path
|
|
d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-sources">Sources</span>
|
|
</a>
|
|
<!-- ENDSECTION:sources -->
|
|
|
|
<!-- Security -->
|
|
<!-- SECTION:security -->
|
|
<a
|
|
class="app-item"
|
|
href="#security"
|
|
data-section="security"
|
|
role="menuitem"
|
|
aria-label="Security"
|
|
hx-get="/suite/tools/security.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#security"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"
|
|
/>
|
|
<path d="M9 12l2 2 4-4" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-security">Security</span>
|
|
</a>
|
|
<!-- ENDSECTION:security -->
|
|
|
|
<!-- Designer (.bas Editor) -->
|
|
<!-- SECTION:designer -->
|
|
<a
|
|
class="app-item"
|
|
href="#designer"
|
|
data-section="designer"
|
|
role="menuitem"
|
|
aria-label="Dialog Designer"
|
|
hx-get="/designer.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#designer"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path d="M12 2L2 7l10 5 10-5-10-5z" />
|
|
<path d="M2 17l10 5 10-5" />
|
|
<path d="M2 12l10 5 10-5" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-designer">Designer</span>
|
|
</a>
|
|
<!-- ENDSECTION:designer -->
|
|
|
|
<!-- Attendant -->
|
|
<!-- SECTION:attendant -->
|
|
<a
|
|
class="app-item"
|
|
href="#attendant"
|
|
data-section="attendant"
|
|
role="menuitem"
|
|
aria-label="Attendant"
|
|
hx-get="/suite/attendant/index.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#attendant"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"
|
|
/>
|
|
<path d="M13.73 21a2 2 0 0 1-3.46 0" />
|
|
<path d="M12 2v2" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-attendant">Attendant</span>
|
|
</a>
|
|
<!-- ENDSECTION:attendant -->
|
|
|
|
<!-- Project -->
|
|
<!-- SECTION:project -->
|
|
<a
|
|
class="app-item"
|
|
href="#project"
|
|
data-section="project"
|
|
role="menuitem"
|
|
aria-label="Project Management"
|
|
hx-get="/suite/project/project.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#project"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="3"
|
|
width="18"
|
|
height="18"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<path d="M3 9h18" />
|
|
<path d="M9 21V9" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-project">Project</span>
|
|
</a>
|
|
<!-- ENDSECTION:project -->
|
|
|
|
<!-- Canvas -->
|
|
<!-- SECTION:canvas -->
|
|
<a
|
|
class="app-item"
|
|
href="#canvas"
|
|
data-section="canvas"
|
|
role="menuitem"
|
|
aria-label="Canvas Whiteboard"
|
|
hx-get="/suite/canvas/canvas.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#canvas"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="3"
|
|
y="3"
|
|
width="18"
|
|
height="18"
|
|
rx="2"
|
|
/>
|
|
<path d="M8 12h8" />
|
|
<path d="M12 8v8" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-canvas">Canvas</span>
|
|
</a>
|
|
<!-- ENDSECTION:canvas -->
|
|
|
|
<!-- Goals -->
|
|
<!-- SECTION:goals -->
|
|
<a
|
|
class="app-item"
|
|
href="#goals"
|
|
data-section="goals"
|
|
role="menuitem"
|
|
aria-label="Goals & OKRs"
|
|
hx-get="/suite/goals/goals.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#goals"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="12" cy="12" r="10" />
|
|
<circle cx="12" cy="12" r="6" />
|
|
<circle cx="12" cy="12" r="2" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-goals">Goals</span>
|
|
</a>
|
|
<!-- ENDSECTION:goals -->
|
|
|
|
<!-- Player -->
|
|
<!-- SECTION:player -->
|
|
<a
|
|
class="app-item"
|
|
href="#player"
|
|
data-section="player"
|
|
role="menuitem"
|
|
aria-label="Media Player"
|
|
hx-get="/suite/player/player.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#player"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<polygon points="5 3 19 12 5 21 5 3" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-player">Player</span>
|
|
</a>
|
|
<!-- ENDSECTION:player -->
|
|
|
|
<!-- Workspace -->
|
|
<!-- SECTION:workspace -->
|
|
<a
|
|
class="app-item"
|
|
href="#workspace"
|
|
data-section="workspace"
|
|
role="menuitem"
|
|
aria-label="Workspace"
|
|
hx-get="/suite/workspace/workspace.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#workspace"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="2"
|
|
y="7"
|
|
width="20"
|
|
height="14"
|
|
rx="2"
|
|
ry="2"
|
|
/>
|
|
<path
|
|
d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-workspace">Workspace</span>
|
|
</a>
|
|
<!-- ENDSECTION:workspace -->
|
|
|
|
<!-- Video -->
|
|
<!-- SECTION:video -->
|
|
<a
|
|
class="app-item"
|
|
href="#video"
|
|
data-section="video"
|
|
role="menuitem"
|
|
aria-label="Video"
|
|
hx-get="/suite/video/video.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#video"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<rect
|
|
x="2"
|
|
y="2"
|
|
width="20"
|
|
height="20"
|
|
rx="2.18"
|
|
ry="2.18"
|
|
/>
|
|
<line x1="7" y1="2" x2="7" y2="22" />
|
|
<line x1="17" y1="2" x2="17" y2="22" />
|
|
<line x1="2" y1="12" x2="22" y2="12" />
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-video">Video</span>
|
|
</a>
|
|
<!-- ENDSECTION:video -->
|
|
|
|
<!-- Learn -->
|
|
<!-- SECTION:learn -->
|
|
<a
|
|
class="app-item"
|
|
href="#learn"
|
|
data-section="learn"
|
|
role="menuitem"
|
|
aria-label="Learn"
|
|
hx-get="/suite/learn/learn.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#learn"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"
|
|
/>
|
|
<path
|
|
d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-learn">Learn</span>
|
|
</a>
|
|
<!-- ENDSECTION:learn -->
|
|
|
|
<!-- Settings (last) -->
|
|
<!-- SECTION:settings -->
|
|
<a
|
|
class="app-item"
|
|
href="#settings"
|
|
data-section="settings"
|
|
role="menuitem"
|
|
aria-label="Settings"
|
|
hx-get="/suite/settings/index.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="#settings"
|
|
>
|
|
<div class="app-icon" aria-hidden="true">
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="12" cy="12" r="3" />
|
|
<path
|
|
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span data-i18n="nav-settings">Settings</span>
|
|
</a>
|
|
<!-- ENDSECTION:settings -->
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Center: Omnibox (Search + Chat) -->
|
|
<div class="header-center">
|
|
<div class="omnibox" id="omnibox">
|
|
<div class="omnibox-input-area">
|
|
<svg
|
|
class="omnibox-icon search-icon"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="11" cy="11" r="8" />
|
|
<path d="m21 21-4.35-4.35" />
|
|
</svg>
|
|
<svg
|
|
class="omnibox-icon bot-icon"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
style="display: none"
|
|
>
|
|
<rect x="3" y="11" width="18" height="10" rx="2" />
|
|
<circle cx="9" cy="16" r="1" />
|
|
<circle cx="15" cy="16" r="1" />
|
|
<path d="M8 11V7a4 4 0 0 1 8 0v4" />
|
|
</svg>
|
|
<input
|
|
type="text"
|
|
class="omnibox-input"
|
|
placeholder="Search or ask anything..."
|
|
id="omniboxInput"
|
|
autocomplete="off"
|
|
/>
|
|
<div class="omnibox-hints">
|
|
<kbd class="omnibox-shortcut">⌘K</kbd>
|
|
<button
|
|
class="omnibox-mode-toggle"
|
|
id="omniboxModeToggle"
|
|
title="Toggle chat mode"
|
|
>
|
|
<svg
|
|
width="14"
|
|
height="14"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Expandable Results/Chat Panel -->
|
|
<div class="omnibox-panel" id="omniboxPanel">
|
|
<!-- Search Results Section -->
|
|
<div class="omnibox-results" id="omniboxResults">
|
|
<div class="omnibox-section">
|
|
<div class="omnibox-section-title">
|
|
Quick Actions
|
|
</div>
|
|
<div
|
|
class="omnibox-actions"
|
|
id="omniboxActions"
|
|
>
|
|
<button
|
|
class="omnibox-action"
|
|
data-action="chat"
|
|
>
|
|
<span class="action-icon">💬</span>
|
|
<span class="action-text"
|
|
>Chat with Bot</span
|
|
>
|
|
<kbd>↵</kbd>
|
|
</button>
|
|
<button
|
|
class="omnibox-action"
|
|
data-action="navigate"
|
|
data-target="chat"
|
|
>
|
|
<span class="action-icon">📱</span>
|
|
<span class="action-text"
|
|
>Open Chat App</span
|
|
>
|
|
</button>
|
|
<button
|
|
class="omnibox-action"
|
|
data-action="navigate"
|
|
data-target="tasks"
|
|
>
|
|
<span class="action-icon">✓</span>
|
|
<span class="action-text"
|
|
>Go to Tasks</span
|
|
>
|
|
</button>
|
|
<button
|
|
class="omnibox-action"
|
|
data-action="navigate"
|
|
data-target="mail"
|
|
>
|
|
<span class="action-icon">✉️</span>
|
|
<span class="action-text"
|
|
>Go to Mail</span
|
|
>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="omnibox-section"
|
|
id="searchResultsSection"
|
|
style="display: none"
|
|
>
|
|
<div class="omnibox-section-title">
|
|
Search Results
|
|
</div>
|
|
<div
|
|
class="omnibox-search-results"
|
|
id="searchResultsList"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Chat Section -->
|
|
<div
|
|
class="omnibox-chat"
|
|
id="omniboxChat"
|
|
style="display: none"
|
|
>
|
|
<div
|
|
class="omnibox-chat-messages"
|
|
id="omniboxChatMessages"
|
|
>
|
|
<div class="omnibox-chat-welcome">
|
|
<div class="welcome-icon">🤖</div>
|
|
<div class="welcome-text">
|
|
<strong>Hi! I'm your assistant.</strong>
|
|
<p>
|
|
Ask me anything or tell me what
|
|
you'd like to do.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="omnibox-chat-input-area">
|
|
<input
|
|
type="text"
|
|
class="omnibox-chat-input"
|
|
placeholder="Type your message..."
|
|
id="omniboxChatInput"
|
|
/>
|
|
<button
|
|
class="omnibox-send-btn"
|
|
id="omniboxSendBtn"
|
|
>
|
|
<svg
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<line x1="22" y1="2" x2="11" y2="13" />
|
|
<polygon
|
|
points="22 2 15 22 11 13 2 9 22 2"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div class="omnibox-chat-footer">
|
|
<button
|
|
class="omnibox-back-btn"
|
|
id="omniboxBackBtn"
|
|
>
|
|
<svg
|
|
width="12"
|
|
height="12"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path d="M19 12H5M12 19l-7-7 7-7" />
|
|
</svg>
|
|
Back to search
|
|
</button>
|
|
<button
|
|
class="omnibox-expand-btn"
|
|
id="omniboxExpandBtn"
|
|
title="Open full chat"
|
|
>
|
|
<svg
|
|
width="12"
|
|
height="12"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<polyline points="15 3 21 3 21 9" />
|
|
<polyline points="9 21 3 21 3 15" />
|
|
<line x1="21" y1="3" x2="14" y2="10" />
|
|
<line x1="3" y1="21" x2="10" y2="14" />
|
|
</svg>
|
|
Open full chat
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="omnibox-backdrop" id="omniboxBackdrop"></div>
|
|
</div>
|
|
|
|
<!-- Right: Notifications + User -->
|
|
<div class="header-right">
|
|
<!-- Notifications Bell -->
|
|
<div class="notifications-menu">
|
|
<button
|
|
class="icon-button"
|
|
id="notificationsBtn"
|
|
title="Notifications"
|
|
aria-expanded="false"
|
|
>
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path
|
|
d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"
|
|
/>
|
|
<path d="M13.73 21a2 2 0 0 1-3.46 0" />
|
|
</svg>
|
|
<span
|
|
class="notifications-badge"
|
|
id="notificationsBadge"
|
|
style="display: none"
|
|
>0</span
|
|
>
|
|
</button>
|
|
<div class="notifications-panel" id="notificationsPanel">
|
|
<div class="notifications-panel-header">
|
|
<span class="notifications-panel-title"
|
|
>Notifications</span
|
|
>
|
|
<button
|
|
class="notifications-clear-btn"
|
|
id="clearNotificationsBtn"
|
|
>
|
|
Clear all
|
|
</button>
|
|
</div>
|
|
<div class="notifications-list" id="notificationsList">
|
|
<div class="notifications-empty">
|
|
<span>🔔</span>
|
|
<p>No notifications</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button
|
|
class="icon-button"
|
|
id="settingsBtn"
|
|
title="Settings"
|
|
aria-expanded="false"
|
|
aria-haspopup="true"
|
|
>
|
|
<svg
|
|
width="20"
|
|
height="20"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="12" cy="12" r="3" />
|
|
<path
|
|
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
|
|
<!-- Settings/Theme Panel -->
|
|
<div
|
|
class="settings-panel"
|
|
id="settingsPanel"
|
|
role="menu"
|
|
aria-label="Settings"
|
|
>
|
|
<div class="settings-panel-title">Theme</div>
|
|
<div class="theme-grid">
|
|
<!-- Core Themes -->
|
|
<button
|
|
class="theme-option theme-sentient"
|
|
data-theme="sentient"
|
|
title="Sentient"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🤖 Sentient</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-dark"
|
|
data-theme="dark"
|
|
title="Dark"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🌑 Dark</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-light"
|
|
data-theme="light"
|
|
title="Light"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">☀️ Light</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-blue"
|
|
data-theme="blue"
|
|
title="Ocean"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🌊 Ocean</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-purple"
|
|
data-theme="purple"
|
|
title="Violet"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">💜 Violet</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-green"
|
|
data-theme="green"
|
|
title="Forest"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🌲 Forest</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-orange"
|
|
data-theme="orange"
|
|
title="Sunset"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🌅 Sunset</span>
|
|
</button>
|
|
<!-- Retro Themes -->
|
|
<button
|
|
class="theme-option theme-cyberpunk"
|
|
data-theme="cyberpunk"
|
|
title="Cyberpunk"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🌃 Cyberpunk</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-retrowave"
|
|
data-theme="retrowave"
|
|
title="Retrowave"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🌴 Retrowave</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-vapordream"
|
|
data-theme="vapordream"
|
|
title="Vapor Dream"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name"
|
|
>💭 Vapor Dream</span
|
|
>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-y2kglow"
|
|
data-theme="y2kglow"
|
|
title="Y2K"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">✨ Y2K</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-arcadeflash"
|
|
data-theme="arcadeflash"
|
|
title="Arcade"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🕹️ Arcade</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-discofever"
|
|
data-theme="discofever"
|
|
title="Disco"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🪩 Disco</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-grungeera"
|
|
data-theme="grungeera"
|
|
title="Grunge"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🎸 Grunge</span>
|
|
</button>
|
|
<!-- Classic Themes -->
|
|
<button
|
|
class="theme-option theme-jazzage"
|
|
data-theme="jazzage"
|
|
title="Jazz Age"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🎺 Jazz Age</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-mellowgold"
|
|
data-theme="mellowgold"
|
|
title="Mellow Gold"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name"
|
|
>🌻 Mellow Gold</span
|
|
>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-midcenturymod"
|
|
data-theme="midcenturymod"
|
|
title="Mid Century"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name"
|
|
>🏠 Mid Century</span
|
|
>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-polaroidmemories"
|
|
data-theme="polaroidmemories"
|
|
title="Polaroid"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">📷 Polaroid</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-saturdaycartoons"
|
|
data-theme="saturdaycartoons"
|
|
title="Cartoons"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">📺 Cartoons</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-seasidepostcard"
|
|
data-theme="seasidepostcard"
|
|
title="Seaside"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🏖️ Seaside</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-typewriter"
|
|
data-theme="typewriter"
|
|
title="Typewriter"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">⌨️ Typewriter</span>
|
|
</button>
|
|
<!-- Tech Themes -->
|
|
<button
|
|
class="theme-option theme-3dbevel"
|
|
data-theme="3dbevel"
|
|
title="3D Bevel"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">🔲 3D Bevel</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-xeroxui"
|
|
data-theme="xeroxui"
|
|
title="Xerox UI"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">📠 Xerox UI</span>
|
|
</button>
|
|
<button
|
|
class="theme-option theme-xtreegold"
|
|
data-theme="xtreegold"
|
|
title="XTree Gold"
|
|
>
|
|
<div class="theme-option-inner">
|
|
<div class="theme-option-header">
|
|
<div class="theme-option-dot"></div>
|
|
</div>
|
|
<div class="theme-option-body">
|
|
<div class="theme-option-line"></div>
|
|
</div>
|
|
</div>
|
|
<span class="theme-option-name">📁 XTree Gold</span>
|
|
</button>
|
|
</div>
|
|
<a
|
|
class="settings-link"
|
|
href="#settings"
|
|
hx-get="/suite/settings/index.html"
|
|
hx-target="#main-content"
|
|
hx-push-url="/#settings"
|
|
>
|
|
<svg
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<circle cx="12" cy="12" r="3" />
|
|
<path
|
|
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
|
/>
|
|
</svg>
|
|
<span>Settings</span>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- User avatar with dropdown -->
|
|
<div class="user-avatar-container" style="position: relative">
|
|
<button
|
|
class="user-avatar"
|
|
id="userAvatar"
|
|
title="User Account"
|
|
aria-label="User account menu"
|
|
aria-expanded="false"
|
|
aria-haspopup="true"
|
|
>
|
|
<span aria-hidden="true">U</span>
|
|
</button>
|
|
|
|
<!-- User Menu Dropdown -->
|
|
<div class="user-menu" id="userMenu" style="display: none">
|
|
<a
|
|
href="/auth/login.html"
|
|
class="user-menu-item login-item"
|
|
id="authAction"
|
|
style="margin: 8px; color: var(--primary)"
|
|
>
|
|
<svg
|
|
width="18"
|
|
height="18"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
id="authIcon"
|
|
>
|
|
<path
|
|
d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"
|
|
></path>
|
|
<polyline points="10 17 15 12 10 7"></polyline>
|
|
<line x1="15" y1="12" x2="3" y2="12"></line>
|
|
</svg>
|
|
<span id="authText">Sign in</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Main content area -->
|
|
<main id="main-content" role="main">
|
|
<!-- Sections will be loaded dynamically -->
|
|
</main>
|
|
|
|
<!-- Core scripts (auth handled by security-bootstrap.js in head) -->
|
|
<script src="suite/js/api-client.js"></script>
|
|
<script src="suite/js/theme-manager.js"></script>
|
|
<script src="suite/js/htmx-app.js"></script>
|
|
<script src="suite/js/base.js"></script>
|
|
|
|
<!-- Admin module functions (button handlers for HTMX-loaded admin views) -->
|
|
<script src="suite/admin/admin.js"></script>
|
|
<script src="suite/admin/admin-functions.js"></script>
|
|
|
|
<!-- Application initialization -->
|
|
<script src="suite/js/suite_app.js"></script>
|
|
<script>
|
|
(function () {
|
|
const FEATURE_MAPPINGS = {
|
|
crm: "people",
|
|
security: "tools",
|
|
};
|
|
|
|
fetch("/api/product")
|
|
.then(function (r) {
|
|
return r.json();
|
|
})
|
|
.then(function (data) {
|
|
if (!data.apps) return;
|
|
var apps = new Set(
|
|
data.apps.map(function (a) {
|
|
return a.toLowerCase();
|
|
}),
|
|
);
|
|
document
|
|
.querySelectorAll("[data-section]")
|
|
.forEach(function (el) {
|
|
var section = el
|
|
.getAttribute("data-section")
|
|
.toLowerCase();
|
|
if (FEATURE_MAPPINGS[section]) {
|
|
section = FEATURE_MAPPINGS[section];
|
|
}
|
|
if (!apps.has(section)) {
|
|
el.style.display = "none";
|
|
}
|
|
});
|
|
})
|
|
.catch(function (e) {
|
|
console.warn("Feature gating failed:", e);
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|