Add tiled homepage; rename Business→Businesses; link footer copyright
- Home page (home.html) at / shows the sidebar sections as tiles; reachable by clicking the 'SimpleX Manager' brand in the sidebar (was redirecting to /users). - Rename the category to 'Businesses' (route /businesses, tab/nav/_category), keeping the per-account bot_type 'business'. Fix profile back-link label. - Footer: link 'Bournemouth Technology Ltd' -> bournemouthtechnology.co.uk and 'SimpleX Network' -> simplex.chat. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -71,9 +71,9 @@ def _enrich(profiles: list[dict]) -> list[dict]:
|
|||||||
|
|
||||||
|
|
||||||
def _category(bot_type: str) -> str:
|
def _category(bot_type: str) -> str:
|
||||||
"""Which sidebar category a profile belongs to: users / business / bots."""
|
"""Which sidebar category a profile belongs to: users / businesses / bots."""
|
||||||
if bot_type in pm.BUSINESS_TYPES:
|
if bot_type in pm.BUSINESS_TYPES:
|
||||||
return "business"
|
return "businesses"
|
||||||
if bot_type in pm.USER_TYPES:
|
if bot_type in pm.USER_TYPES:
|
||||||
return "users"
|
return "users"
|
||||||
return "bots"
|
return "bots"
|
||||||
@@ -106,7 +106,9 @@ async def logout():
|
|||||||
|
|
||||||
@app.get("/", response_class=HTMLResponse)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
async def index(request: Request):
|
async def index(request: Request):
|
||||||
return RedirectResponse("/users", status_code=302)
|
if redir := _redirect_if_unauth(request):
|
||||||
|
return redir
|
||||||
|
return TEMPLATES.TemplateResponse(request, "home.html", {"nav_active": "home"})
|
||||||
|
|
||||||
|
|
||||||
@app.get("/users", response_class=HTMLResponse)
|
@app.get("/users", response_class=HTMLResponse)
|
||||||
@@ -120,14 +122,14 @@ async def users_page(request: Request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@app.get("/business", response_class=HTMLResponse)
|
@app.get("/businesses", response_class=HTMLResponse)
|
||||||
async def business_page(request: Request):
|
async def businesses_page(request: Request):
|
||||||
if redir := _redirect_if_unauth(request):
|
if redir := _redirect_if_unauth(request):
|
||||||
return redir
|
return redir
|
||||||
items = _enrich([p for p in db.list_profiles() if p["bot_type"] in pm.BUSINESS_TYPES])
|
items = _enrich([p for p in db.list_profiles() if p["bot_type"] in pm.BUSINESS_TYPES])
|
||||||
return TEMPLATES.TemplateResponse(request, "list.html", {
|
return TEMPLATES.TemplateResponse(request, "list.html", {
|
||||||
"tab": "business", "items": items, "create_types": pm.BUSINESS_TYPES,
|
"tab": "businesses", "items": items, "create_types": pm.BUSINESS_TYPES,
|
||||||
"nav_active": "business",
|
"nav_active": "businesses",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -264,12 +264,12 @@
|
|||||||
<button class="mobile-menu-btn" onclick="toggleSidebar()" aria-label="Menu">☰</button>
|
<button class="mobile-menu-btn" onclick="toggleSidebar()" aria-label="Menu">☰</button>
|
||||||
<div class="app">
|
<div class="app">
|
||||||
<aside class="sidebar" id="sidebar">
|
<aside class="sidebar" id="sidebar">
|
||||||
<a class="nav-brand" href="/users">
|
<a class="nav-brand" href="/">
|
||||||
<span class="brand-icon">◆</span><span class="brand-text">SimpleX Manager</span>
|
<span class="brand-icon">◆</span><span class="brand-text">SimpleX Manager</span>
|
||||||
</a>
|
</a>
|
||||||
<nav class="side-nav">
|
<nav class="side-nav">
|
||||||
<a href="/users" {% if nav_active == 'users' %}class="active"{% endif %}><span class="ico">👤</span><span class="lbl">Users</span></a>
|
<a href="/users" {% if nav_active == 'users' %}class="active"{% endif %}><span class="ico">👤</span><span class="lbl">Users</span></a>
|
||||||
<a href="/business" {% if nav_active == 'business' %}class="active"{% endif %}><span class="ico">💼</span><span class="lbl">Business</span></a>
|
<a href="/businesses" {% if nav_active == 'businesses' %}class="active"{% endif %}><span class="ico">💼</span><span class="lbl">Businesses</span></a>
|
||||||
<a href="/bots" {% if nav_active == 'bots' %}class="active"{% endif %}><span class="ico">🤖</span><span class="lbl">Bots</span></a>
|
<a href="/bots" {% if nav_active == 'bots' %}class="active"{% endif %}><span class="ico">🤖</span><span class="lbl">Bots</span></a>
|
||||||
<a href="https://simplex.chat/file/" target="_blank" rel="noopener"><span class="ico">📁</span><span class="lbl">File upload</span></a>
|
<a href="https://simplex.chat/file/" target="_blank" rel="noopener"><span class="ico">📁</span><span class="lbl">File upload</span></a>
|
||||||
<a href="/notifications" class="nav-sep {% if nav_active == 'notifications' %}active{% endif %}"><span class="ico">🔔</span><span class="lbl">Notifications</span><span class="notif-badge" id="notif-badge" style="display:none;"></span></a>
|
<a href="/notifications" class="nav-sep {% if nav_active == 'notifications' %}active{% endif %}"><span class="ico">🔔</span><span class="lbl">Notifications</span><span class="notif-badge" id="notif-badge" style="display:none;"></span></a>
|
||||||
@@ -297,9 +297,9 @@
|
|||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
© Bournemouth Technology Ltd
|
© <a href="https://bournemouthtechnology.co.uk" target="_blank" rel="noopener">Bournemouth Technology Ltd</a>
|
||||||
<span class="sep">·</span>
|
<span class="sep">·</span>
|
||||||
built on © SimpleX Network
|
built on © <a href="https://simplex.chat" target="_blank" rel="noopener">SimpleX Network</a>
|
||||||
<span class="sep">·</span>
|
<span class="sep">·</span>
|
||||||
<a href="https://simplex.chat/downloads/" target="_blank" rel="noopener">Get SimpleX App</a>
|
<a href="https://simplex.chat/downloads/" target="_blank" rel="noopener">Get SimpleX App</a>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
69
manager/templates/home.html
Normal file
69
manager/templates/home.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}Home — SimpleX Manager{% endblock %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<style>
|
||||||
|
.home-head { margin-bottom: 28px; }
|
||||||
|
.home-head h1 { margin-bottom: 6px; }
|
||||||
|
.home-head p { color: var(--muted); font-size: 14px; }
|
||||||
|
|
||||||
|
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
|
||||||
|
.tile {
|
||||||
|
display: flex; flex-direction: column; gap: 8px;
|
||||||
|
background: var(--card); border: 1px solid var(--border); border-radius: 12px;
|
||||||
|
padding: 22px; text-decoration: none; color: var(--text);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
transition: border-color 0.15s, transform 0.05s;
|
||||||
|
}
|
||||||
|
.tile:hover { border-color: var(--accent); }
|
||||||
|
.tile:active { transform: translateY(1px); }
|
||||||
|
.tile .t-ico { font-size: 28px; line-height: 1; }
|
||||||
|
.tile .t-title { font-size: 16px; font-weight: 700; }
|
||||||
|
.tile .t-desc { font-size: 13px; color: var(--muted); }
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="home-head">
|
||||||
|
<h1>SimpleX Manager</h1>
|
||||||
|
<p>Manage your SimpleX accounts, business inboxes and bots — pick a section to get started.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tiles">
|
||||||
|
<a class="tile" href="/users">
|
||||||
|
<span class="t-ico">👤</span>
|
||||||
|
<span class="t-title">Users</span>
|
||||||
|
<span class="t-desc">Personal SimpleX accounts — contacts, groups and channels.</span>
|
||||||
|
</a>
|
||||||
|
<a class="tile" href="/businesses">
|
||||||
|
<span class="t-ico">💼</span>
|
||||||
|
<span class="t-title">Businesses</span>
|
||||||
|
<span class="t-desc">Business inboxes — each customer gets their own group chat.</span>
|
||||||
|
</a>
|
||||||
|
<a class="tile" href="/bots">
|
||||||
|
<span class="t-ico">🤖</span>
|
||||||
|
<span class="t-title">Bots</span>
|
||||||
|
<span class="t-desc">Echo, broadcast, support, directory and dead-man's-switch bots.</span>
|
||||||
|
</a>
|
||||||
|
<a class="tile" href="/network">
|
||||||
|
<span class="t-ico">📡</span>
|
||||||
|
<span class="t-title">Network</span>
|
||||||
|
<span class="t-desc">SimpleX servers and connection status.</span>
|
||||||
|
</a>
|
||||||
|
<a class="tile" href="/notifications">
|
||||||
|
<span class="t-ico">🔔</span>
|
||||||
|
<span class="t-title">Notifications</span>
|
||||||
|
<span class="t-desc">Recent messages received across all profiles.</span>
|
||||||
|
</a>
|
||||||
|
<a class="tile" href="/settings">
|
||||||
|
<span class="t-ico">⚙️</span>
|
||||||
|
<span class="t-title">Settings</span>
|
||||||
|
<span class="t-desc">Theme and manager preferences.</span>
|
||||||
|
</a>
|
||||||
|
<a class="tile" href="https://simplex.chat/file/" target="_blank" rel="noopener">
|
||||||
|
<span class="t-ico">📁</span>
|
||||||
|
<span class="t-title">File upload</span>
|
||||||
|
<span class="t-desc">Share files over SimpleX (opens simplex.chat).</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% set new_label = 'User' if tab == 'users' else ('Business' if tab == 'business' else 'Bot') %}
|
{% set new_label = 'User' if tab == 'users' else ('Business' if tab == 'businesses' else 'Bot') %}
|
||||||
<div class="flex-between" style="margin-bottom: 24px;">
|
<div class="flex-between" style="margin-bottom: 24px;">
|
||||||
<h1 style="margin:0;">{{ tab | title }}</h1>
|
<h1 style="margin:0;">{{ tab | title }}</h1>
|
||||||
<button class="btn btn-primary" onclick="openCreate()">
|
<button class="btn btn-primary" onclick="openCreate()">
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if tab == 'business' %}
|
{% if tab == 'businesses' %}
|
||||||
<div class="card bot-types-card" style="margin-bottom:24px;">
|
<div class="card bot-types-card" style="margin-bottom:24px;">
|
||||||
<h2 style="font-size:15px;margin-bottom:8px;">Business accounts</h2>
|
<h2 style="font-size:15px;margin-bottom:8px;">Business accounts</h2>
|
||||||
<p class="muted" style="font-size:13px;">
|
<p class="muted" style="font-size:13px;">
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
{% if tab == 'users' %}
|
{% if tab == 'users' %}
|
||||||
<strong>No users yet</strong>
|
<strong>No users yet</strong>
|
||||||
<p>Create a SimpleX user account to manage contacts and channels.</p>
|
<p>Create a SimpleX user account to manage contacts and channels.</p>
|
||||||
{% elif tab == 'business' %}
|
{% elif tab == 'businesses' %}
|
||||||
<strong>No business accounts yet</strong>
|
<strong>No business accounts yet</strong>
|
||||||
<p>Create a business account; each customer who connects gets their own group chat.</p>
|
<p>Create a business account; each customer who connects gets their own group chat.</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
<form id="create-form">
|
<form id="create-form">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Name</label>
|
<label>Name</label>
|
||||||
<input type="text" name="name" placeholder="{{ 'Alice' if tab == 'users' else ('Acme Inc' if tab == 'business' else 'My Bot') }}" required>
|
<input type="text" name="name" placeholder="{{ 'Alice' if tab == 'users' else ('Acme Inc' if tab == 'businesses' else 'My Bot') }}" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Bio / Description <span class="muted" style="font-weight:400;">(optional)</span></label>
|
<label>Bio / Description <span class="muted" style="font-weight:400;">(optional)</span></label>
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
<input type="file" name="avatar_file" accept="image/*" onchange="onAvatarChange(this)" style="flex:1;">
|
<input type="file" name="avatar_file" accept="image/*" onchange="onAvatarChange(this)" style="flex:1;">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if tab == 'business' %}
|
{% if tab == 'businesses' %}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Welcome Message <span class="muted" style="font-weight:400;">(optional auto-reply to new customers)</span></label>
|
<label>Welcome Message <span class="muted" style="font-weight:400;">(optional auto-reply to new customers)</span></label>
|
||||||
<input type="text" name="welcome_message" placeholder="Thanks for reaching out! How can we help?">
|
<input type="text" name="welcome_message" placeholder="Thanks for reaching out! How can we help?">
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="flex-between" style="margin-bottom: 20px;">
|
<div class="flex-between" style="margin-bottom: 20px;">
|
||||||
<div class="flex gap-8">
|
<div class="flex gap-8">
|
||||||
<a href="{{ back }}" class="muted" style="text-decoration:none;">← {{ 'Users' if back == '/users' else 'Bots' }}</a>
|
<a href="{{ back }}" class="muted" style="text-decoration:none;">← {{ 'Users' if back == '/users' else ('Businesses' if back == '/businesses' else 'Bots') }}</a>
|
||||||
<span class="muted">/</span>
|
<span class="muted">/</span>
|
||||||
<strong>{{ profile.name }}</strong>
|
<strong>{{ profile.name }}</strong>
|
||||||
<span class="tag {% if profile.bot_type == 'user' %}tag-user{% endif %}">{{ profile.bot_type }}</span>
|
<span class="tag {% if profile.bot_type == 'user' %}tag-user{% endif %}">{{ profile.bot_type }}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user