§10 split landing into a public "/" + gated "/dashboard", both plugin-replaceable (todo §10 follow-up); per human feedback, "/" is now an ungated public landing (default views/home.ejs: brand + intro + prominent Log in / Create account links, or "go to dashboard" when signed in) and "/dashboard" is the gated post-login app home (anonymous → /login?return_to=/dashboard). Both are fully replaceable via two optional RouteHandlers on PluginManifest — home? (public /) and dashboard? (gated /dashboard) — rendered against the plugin's own views with the native shell via ctx.chrome (full route parity: HEAD, void-return, response hooks, fresh CSRF cookie; a home handler is public so ctx.user may be null). Single-slot + loud: findConflicts errors on >1 owner of either slot (new "home"/"dashboard" kinds), discovery rejects a non-function handler, and "dashboard" is reserved so a plugin folder can't shadow it ("/" can't be shadowed — route paths carry the /<id> prefix). Post-login + already-signed-in redirects and the global Dashboard/People nav hrefs moved to /dashboard. Tests-first (348 units): public-/ + gated-/dashboard + dual plugin-override in app.test; per-slot conflict in plugin.test; non-function/reserved/two-owners in discovery.test. Docs: plugin-contract "The landing pages" section + README. E2E: visual.spec plants a session for /dashboard design-system tests + a cookie-free public-landing test; full-flow repointed to /dashboard. stability-reviewer: APPROVE, no Critical/High/Medium. typecheck + 348 units + visual(10) + full-flow(7) green.
This commit is contained in:
43
views/home.ejs
Normal file
43
views/home.ejs
Normal file
@@ -0,0 +1,43 @@
|
||||
<%#
|
||||
Public landing page (todo §10): the ungated "/", what an anonymous visitor sees. A brief intro to
|
||||
the product and prominent paths to sign in / register — or to the app dashboard when already signed
|
||||
in. Standalone (no app shell — the sidebar/menu belong to the signed-in app). A plugin may replace
|
||||
this via its `home` handler. Auto theme follows the OS (styles.css). Data: brand, user (or null).
|
||||
%><%
|
||||
const brand = locals.brand || "Plainpages";
|
||||
%><!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title><%= brand %></title>
|
||||
<link rel="stylesheet" href="/public/css/styles.css" />
|
||||
<link rel="stylesheet" href="/public/css/auth.css" />
|
||||
<link rel="icon" href="/public/favicon.svg" />
|
||||
</head>
|
||||
<body>
|
||||
<%- include("partials/icons") %>
|
||||
<main class="auth-stage">
|
||||
<div class="landing">
|
||||
<div class="auth-brand">
|
||||
<span class="brand-mark"><svg class="ico ico-sm"><use href="#i-box" /></svg></span>
|
||||
<span class="brand-name"><%= brand %></span>
|
||||
</div>
|
||||
<h1 class="landing-title">Operational web apps, without the boilerplate.</h1>
|
||||
<p class="landing-lead">
|
||||
<%= brand %> is a self-hostable foundation for admin and operational UIs — sign-in,
|
||||
a config-driven menu, and a server-rendered, zero-JS design system. You add the
|
||||
domain-specific screens by dropping in plugin folders.
|
||||
</p>
|
||||
<div class="landing-actions">
|
||||
<% if (locals.user) { %>
|
||||
<a class="btn btn-primary" href="/dashboard">Go to your dashboard</a>
|
||||
<% } else { %>
|
||||
<a class="btn btn-primary" href="/login">Log in</a>
|
||||
<a class="btn" href="/registration">Create account</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user