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:
Jon
2026-06-05 17:45:28 +01:00
parent 2194aa0f82
commit 270766b99b
5 changed files with 88 additions and 17 deletions

View File

@@ -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",
}) })

View File

@@ -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>

View 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 %}

View File

@@ -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?">

View File

@@ -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>