8.1 KiB
8.1 KiB
admin.derez.ai — UI Reuse Guide
Stripped-down version: Servers page only. No Sales, no CRM, no API Keys.
1. UI Architecture (Single HTML File)
The entire front-end is a single-page app in a single index.html with:
| File | Role |
|---|---|
index.html |
Full DOM layout: sidebar, sections, modals (login, confirm) |
styles.css |
All styles: layout, sidebar, cards, tables, badges, modal, toast, server dashboard |
app.js |
State, auth, API helpers, routing, all CRUD for each section |
The pattern is straightforward — you can keep one file per section or keep it monolithic. The CSS and JS are written in vanilla ES6+ with no build step.
2. Login & Session (Cookie-Based)
How it works
- User fills email + password in
#login-modal(inside#login-backdrop). doSignIn()POSTs to the auth endpoint with{ email, password }.- The backend returns an object with a
sessionidfield. - The session ID and email are saved in cookies:
al_session— the session tokenal_email— the signed-in email
On page load
const _boot = getCookie("al_session");
if (_boot) {
currentSession = _boot;
currentEmail = getCookie("al_email") || "";
showApp(); // hides login modal, shows sidebar
loadData(); // loads your default section data
} else {
showAuth(); // shows login modal
}
Cookie helpers (already in app.js)
setCookie(name, value, days) // SameSite=Strict
getCookie(name)
deleteCookie(name)
API fetch wrapper
async function apiFetch(url, options = {})
- Automatically attaches
X-Session-Idheader fromcurrentSession. - On HTTP 401, deletes cookies, clears local state, and reloads the page (back to login).
Sign out
function doSignOut()
- Sends a
DELETEto the auth endpoint with the session ID. - Deletes cookies (
al_session,al_email). - Clears
localStorage. - Shows the login screen again.
What you need to change for a new project
| Constant / Variable | Change to |
|---|---|
const API_BASE (L2) |
Your backend base URL, e.g. "https://api.yourproject.com/webhook" |
ROUTES.auth (L6) |
Your login endpoint path, e.g. "/auth/login" |
Cookie names al_session / al_email |
Rename to avoid conflicts, e.g. "myapp_session" |
apiFetch 401 handler |
Customize or keep (auto-redirects to login) |
3. How Sections Work (Routing)
Sidebar navigation
Each sidebar item in index.html:
<div class="nav-item" data-section="servers"> ... Servers</div>
The click handler (L175–239 in app.js):
- Reads
el.dataset.section→ e.g."servers" - Toggles
.activeclass on the nav item - Toggles
.activeclass on#section-servers - Sets the page title from a label map
- Shows the refresh button
- Lazy-loads data if empty
Corresponding section element
<div class="section" id="section-servers"> ... </div>
Only one .section has .active at a time.
4. Servers Page (Dashboard)
Data flow
serversLoadData()
├── GET https://n8n.derez.ai/webhook/server ← seat list (fetched directly, no auth)
│ Returns: [{ server: "hostname-01" }, ...]
├── For each server:
│ GET apiUrl(ROUTES.servers) + "?server=<name>" ← full dashboard (authenticated)
│ Parses item.text (JSON string) or item directly
│ Stores in serversData[]
└── serversRenderTabs() + serversRenderDashboard(0)
Dashboard DOM structure
.section#section-servers
├── .card-header
│ ├── Tab bar: .server-tabs / #server-tabs-strip
│ └── Buttons (Update All, Harden All — optional)
└── .card#server-dashboard
├── Summary card (name, OS, kernel, uptime, status badge)
├── KPI row (CPU, RAM, Disk, Security Score)
├── Performance bars (CPU, RAM, Disk usage)
├── Security checks (SSH, Seccomp, AppArmor, SELinux)
├── Exposed ports
├── Action advice (priority items, upgrades)
└── Details: containers, packages, storage, Podman
Key data shape (serversData[i])
{
server: {
name: "hostname-01",
os: "Ubuntu 22.04",
kernel: "5.15.0-xxx",
uptime: "42 days"
},
summary: {
overall_status: "green" | "yellow" | "red"
},
performance: {
cpu_idle_percent: 85.3,
ram_percent: 62,
ram_gb: 7.8,
total_ram_gb: 16
},
storage: {
total_gb: 256,
used_gb: 120,
percent: 47
},
kpis: {
kpi_19_security_score: 72
},
security: {
ssh_password_auth: false,
ssh_root_login: false,
seccomp_enabled: true,
apparmor_enabled: true,
selinux_enabled: false,
firewall_exposed_services: ["22", "80", "443"]
},
action_advice: {
priority_actions: [],
upgrade_needed: true,
ram_upgrade_recommended: false,
container_cleanup_needed: false
},
containers: [ /* … */ ],
packages: [ /* … */ ],
podman: { /* … */ },
seats: { server: "hostname-01", seat: 3 }
}
What you need to change for the servers page
| Item | Change to |
|---|---|
Seat list URL (hardcoded https://n8n.derez.ai/webhook/server in serversLoadData) |
Your server list endpoint |
ROUTES.servers (L10) |
Your server dashboard endpoint path |
The item.text JSON parsing (L918) |
Adjust if your API shape differs |
| Dashboard widget content (render function L983+) | Keep, expand, or trim as needed |
5. What's Stripped: No Sales, No CRM, No Keys
The following have been removed from this consolidated doc — you should delete them from the HTML/CSS/JS when reusing:
index.html — Remove these sidebar nav items
<div class="nav-item" data-section="keys">(L84–100)<div class="nav-item" data-section="crm">(L112–129)<div class="nav-item" data-section="sales">(L130–147)
Also remove the corresponding .section elements:
section-keys(the div near L1060)section-crm(the div near L1098)section-sales(the div near L1098–1106)
app.js — Remove these functions & state
- State:
keysData(L22),crmRecords(L23),crmSortKey(L24),crmSortDir(L25) - Labels:
keys,sales,crmentries from the label map (L192–194) - Lazy-loads: the
if (key === "keys")andif (key === "crm")blocks (L233–237) - Functions:
keysLoadRecords,keysRender,keysDelete(L1303–1398) - Functions:
crmLoadRecords,crmRender,crmClearFilters,crmToggleSort,crmUpdateDeleteBtn,crmToggleAll,crmDeleteContact,crmDeleteSelected,crmSetStageSelected,crmOpenEdit,crmCloseEdit,crmSaveEdit(L1401–1823)
styles.css — Remove CRM-specific styles
.crm-filter-inputand related rules (L824–838+).crm-search-row th(L839–842)
6. What You Keep (Optional Sections)
If you also want DNS, Instances, or Backup in your new project, their patterns are the same:
| Section | Endpoint | Functions (in app.js) |
Section ID |
|---|---|---|---|
| DNS | ROUTES.dns |
dnsLoadRecords, dnsRender, dnsDeleteRecord, dnsAddRecord |
#section-dns |
| Instances | ROUTES.instances |
instancesLoadRecords, instancesRender, instancesCopySSH, instancesDelete, instancesOpenEdit, instancesCloseEdit, instancesSaveEdit |
#section-instances |
| Backup | ROUTES.backup |
backupLoadRecords, backupRender, backupDelete |
#section-backup |
Each follows the same lazy-load, render, CRUD pattern.
7. Quick Start for a New Project
- Copy
index.html,styles.css,app.jsto your project. - In
app.js:- Change
API_BASEto your backend URL. - Change
ROUTESentries to match your API paths. - Update the cookie names if desired.
- Remove
keys,crm,salescode (see §5).
- Change
- In
index.html:- Remove keys, CRM, and Sales nav items and section elements.
- Update the page title in
<head>. - Update the brand text "derez.ai" in the sidebar.
- In
styles.css:- Remove CRM-specific CSS.
- Update the server seat-list URL in
serversLoadData()to your own endpoint. - Serve from any static server — no build step required.