botserver/web/desktop/index.html
Rodrigo Rodriguez (Pragmatismo) 8c2b17c615 Fix messages layout and improve scrollbar styling
Switch messages area to fixed positioning with centered transform for
better layout stability. Enhance scrollbar appearance with thin style,
improved colors
2025-11-20 16:02:48 -03:00

425 lines
14 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>General Bots</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="stylesheet" href="css/app.css" />
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif;
background: #ffffff;
color: #202124;
overflow: hidden;
}
/* Floating minimal header */
.float-header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
z-index: 1000;
background: transparent;
pointer-events: none;
}
.float-header > * {
pointer-events: auto;
}
/* Left side - Logo */
.header-left {
display: flex;
align-items: center;
gap: 12px;
}
.logo-wrapper {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
padding: 8px 12px;
border-radius: 12px;
transition: all 0.3s;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.logo-wrapper:hover {
background: rgba(255, 255, 255, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.logo-icon {
width: 32px;
height: 32px;
background: url("https://pragmatismo.com.br/icons/general-bots.svg")
center/contain no-repeat;
}
.logo-text {
font-size: 18px;
font-weight: 500;
color: #202124;
}
/* Right side - Apps menu and avatar */
.header-right {
display: flex;
align-items: center;
gap: 12px;
}
/* Google-style dots menu button */
.apps-menu-btn {
width: 40px;
height: 40px;
border: none;
background: transparent;
cursor: pointer;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
color: #5f6368;
position: relative;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.apps-menu-btn:hover {
background: rgba(255, 255, 255, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.apps-menu-btn:active {
background: rgba(255, 255, 255, 0.95);
transform: scale(0.95);
}
/* Apps dropdown */
.apps-dropdown {
position: absolute;
top: 60px;
right: 80px;
width: 320px;
background: white;
border-radius: 16px;
box-shadow:
0 1px 2px 0 rgba(60, 64, 67, 0.3),
0 2px 6px 2px rgba(60, 64, 67, 0.15);
padding: 20px;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 1001;
}
.apps-dropdown.show {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.app-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.app-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px 8px;
border-radius: 8px;
cursor: pointer;
text-decoration: none;
color: #202124;
transition: background 0.2s;
border: 1px solid transparent;
}
.app-item:hover {
background: rgba(26, 115, 232, 0.04);
border-color: rgba(26, 115, 232, 0.2);
}
.app-item.active {
background: rgba(26, 115, 232, 0.08);
border-color: rgba(26, 115, 232, 0.3);
}
.app-icon {
width: 48px;
height: 48px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
margin-bottom: 8px;
background: #f8f9fa;
}
.app-item.active .app-icon {
background: #e8f0fe;
}
.app-item span {
font-size: 13px;
color: #5f6368;
}
/* User avatar */
.user-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
background: #1a73e8;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.user-avatar:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
transform: scale(1.05);
}
/* Main content area */
#main-content {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
body {
background: #202124;
color: #e8eaed;
}
.float-header {
background: transparent;
}
.logo-wrapper {
background: rgba(32, 33, 36, 0.9);
}
.logo-wrapper:hover {
background: rgba(32, 33, 36, 1);
}
.logo-text {
color: #e8eaed;
}
.apps-menu-btn {
color: #9aa0a6;
}
.apps-menu-btn {
background: rgba(32, 33, 36, 0.9);
}
.apps-menu-btn:hover {
background: rgba(32, 33, 36, 1);
}
.apps-dropdown {
background: #292a2d;
box-shadow:
0 1px 3px 1px rgba(0, 0, 0, 0.15),
0 4px 8px 3px rgba(0, 0, 0, 0.15);
}
.app-item {
color: #e8eaed;
}
.app-item:hover {
background: rgba(138, 180, 248, 0.08);
border-color: rgba(138, 180, 248, 0.2);
}
.app-icon {
background: #3c4043;
}
.app-item.active .app-icon {
background: #394457;
}
.app-item span {
color: #9aa0a6;
}
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/livekit-client/dist/livekit-client.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
<!-- Minimal floating header -->
<div class="float-header">
<!-- Left: General Bots logo -->
<div class="header-left">
<div class="logo-wrapper" onclick="window.location.reload()">
<div class="logo-icon"></div>
<div class="logo-text">General Bots</div>
</div>
</div>
<!-- Right: Apps menu and user avatar -->
<div class="header-right">
<button class="apps-menu-btn" id="appsMenuBtn" title="Apps">
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
>
<circle cx="5" cy="5" r="2"></circle>
<circle cx="12" cy="5" r="2"></circle>
<circle cx="19" cy="5" r="2"></circle>
<circle cx="5" cy="12" r="2"></circle>
<circle cx="12" cy="12" r="2"></circle>
<circle cx="19" cy="12" r="2"></circle>
<circle cx="5" cy="19" r="2"></circle>
<circle cx="12" cy="19" r="2"></circle>
<circle cx="19" cy="19" r="2"></circle>
</svg>
</button>
<div class="apps-dropdown" id="appsDropdown">
<div class="app-grid">
<a
class="app-item active"
href="#chat"
data-section="chat"
>
<div class="app-icon">💬</div>
<span>Chat</span>
</a>
<a class="app-item" href="#drive" data-section="drive">
<div class="app-icon">📁</div>
<span>Drive</span>
</a>
<a class="app-item" href="#tasks" data-section="tasks">
<div class="app-icon"></div>
<span>Tasks</span>
</a>
<a class="app-item" href="#mail" data-section="mail">
<div class="app-icon"></div>
<span>Mail</span>
</a>
<a
class="app-item"
href="#calendar"
data-section="calendar"
>
<div class="app-icon">📅</div>
<span>Calendar</span>
</a>
<a class="app-item" href="#notes" data-section="notes">
<div class="app-icon">📝</div>
<span>Notes</span>
</a>
</div>
</div>
<div class="user-avatar" id="userAvatar" title="User Account">
<span>U</span>
</div>
</div>
</div>
<div id="main-content">
<!-- Sections will be loaded dynamically -->
</div>
<!-- Load scripts -->
<script src="js/layout.js"></script>
<script>
// Apps menu toggle
document.addEventListener("DOMContentLoaded", () => {
const appsBtn = document.getElementById("appsMenuBtn");
const appsDropdown = document.getElementById("appsDropdown");
const appItems = document.querySelectorAll(".app-item");
// Toggle apps menu
appsBtn.addEventListener("click", (e) => {
e.stopPropagation();
appsDropdown.classList.toggle("show");
});
// Close dropdown when clicking outside
document.addEventListener("click", () => {
appsDropdown.classList.remove("show");
});
// Prevent dropdown from closing when clicking inside
appsDropdown.addEventListener("click", (e) => {
e.stopPropagation();
});
// Handle app selection
appItems.forEach((item) => {
item.addEventListener("click", (e) => {
e.preventDefault();
const section = item.dataset.section;
// Update active state
appItems.forEach((i) => i.classList.remove("active"));
item.classList.add("active");
// Switch section
if (window.switchSection) {
window.switchSection(section);
}
// Close dropdown
appsDropdown.classList.remove("show");
});
});
// Load default section (chat) after a short delay to ensure layout.js is loaded
setTimeout(() => {
if (window.switchSection) {
window.switchSection("chat");
}
}, 100);
});
</script>
</body>
</html>