auth ux improvements + cloner fix

This commit is contained in:
Your Name 2026-08-19 13:39:32 -04:00
parent 8bcaf264fa
commit 1394ce1e0c
3 changed files with 172 additions and 28 deletions

10
db.js
View file

@ -546,9 +546,14 @@ function cloneStructure(
cloneDbs = [], cloneDbs = [],
) { ) {
const transaction = db.transaction(() => { const transaction = db.transaction(() => {
// Carry over the source's head_injection (viewport meta, PWA tags, favicons,
// mobile-hardening CSS). Without this a clone renders unstyled/unscaled on
// mobile even though its templates are identical.
const source = getStructure(structId);
const cloneStructure = db.prepare(` const cloneStructure = db.prepare(`
INSERT INTO structures (name, user_id, route_prefix, cloned_from) INSERT INTO structures (name, user_id, route_prefix, cloned_from, head_injection)
VALUES (?, ?, ?, ?); VALUES (?, ?, ?, ?, ?);
`); `);
const newStructId = cloneStructure.run( const newStructId = cloneStructure.run(
@ -556,6 +561,7 @@ function cloneStructure(
userId, userId,
routePrefix, routePrefix,
structId, structId,
source ? source.head_injection : null,
).lastInsertRowid; ).lastInsertRowid;
const dbIds = db const dbIds = db

View file

@ -1,13 +1,82 @@
<form action="/login" method="POST"> <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>come home · bliss</title>
<style>
:root { color-scheme: light dark; }
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
min-height: 100dvh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: #f5f5f4;
color: #1c1917;
}
form {
width: 100%;
max-width: 22rem;
display: flex;
flex-direction: column;
gap: 0.85rem;
}
h1 { margin: 0 0 0.25rem; font-size: 1.6rem; }
label {
display: flex;
flex-direction: column;
gap: 0.3rem;
font-size: 0.85rem;
color: #57534e;
}
input {
width: 100%;
padding: 0.75rem;
font-size: 16px; /* >=16px keeps iOS from zooming in on focus */
border: 1px solid #d6d3d1;
border-radius: 0.5rem;
background: #fff;
color: #1c1917;
}
button {
margin-top: 0.35rem;
min-height: 44px; /* comfortable tap target */
padding: 0.85rem;
font-size: 1rem;
font-weight: 600;
border: 0;
border-radius: 0.5rem;
background: #1f6ef0;
color: #fff;
cursor: pointer;
}
button:active { background: #1858c4; }
.error { color: #c0392b; font-size: 0.9rem; }
.alt { font-size: 0.9rem; text-align: center; color: #57534e; }
a { color: #1f6ef0; }
</style>
</head>
<body>
<form action="/login" method="POST">
<h1>come home</h1>
<% if (it.next) { %><input type="hidden" name="next" value="<%= it.next %>"><% } %> <% if (it.next) { %><input type="hidden" name="next" value="<%= it.next %>"><% } %>
<input name="username" placeholder="username"> <label>username
<input name="password" placeholder="password"> <input name="username" type="text" placeholder="username"
<button type="submit"> autocomplete="username" autocapitalize="none" autocorrect="off"
come home spellcheck="false" required autofocus>
</button> </label>
<% if (it.error) { %> <label>password
<%= it.error %> <input name="password" type="password" placeholder="password"
<% } %> autocomplete="current-password" required>
<br> </label>
<div> or you can <a href="/register<%= it.next ? '?next=' + encodeURIComponent(it.next) : '' %>">move in here</a>. <button type="submit">come home</button>
</form> <% if (it.error) { %><div class="error"><%= it.error %></div><% } %>
<div class="alt">or you can <a href="/register<%= it.next ? '?next=' + encodeURIComponent(it.next) : '' %>">move in here</a>.</div>
</form>
</body>
</html>

View file

@ -1,13 +1,82 @@
<form action="/register" method="POST"> <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>move in · bliss</title>
<style>
:root { color-scheme: light dark; }
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
min-height: 100dvh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: #f5f5f4;
color: #1c1917;
}
form {
width: 100%;
max-width: 22rem;
display: flex;
flex-direction: column;
gap: 0.85rem;
}
h1 { margin: 0 0 0.25rem; font-size: 1.6rem; }
label {
display: flex;
flex-direction: column;
gap: 0.3rem;
font-size: 0.85rem;
color: #57534e;
}
input {
width: 100%;
padding: 0.75rem;
font-size: 16px; /* >=16px keeps iOS from zooming in on focus */
border: 1px solid #d6d3d1;
border-radius: 0.5rem;
background: #fff;
color: #1c1917;
}
button {
margin-top: 0.35rem;
min-height: 44px; /* comfortable tap target */
padding: 0.85rem;
font-size: 1rem;
font-weight: 600;
border: 0;
border-radius: 0.5rem;
background: #1f6ef0;
color: #fff;
cursor: pointer;
}
button:active { background: #1858c4; }
.error { color: #c0392b; font-size: 0.9rem; }
.alt { font-size: 0.9rem; text-align: center; color: #57534e; }
a { color: #1f6ef0; }
</style>
</head>
<body>
<form action="/register" method="POST">
<h1>move in</h1>
<% if (it.next) { %><input type="hidden" name="next" value="<%= it.next %>"><% } %> <% if (it.next) { %><input type="hidden" name="next" value="<%= it.next %>"><% } %>
<input name="username" placeholder="username"> <label>username
<input name="password" placeholder="password"> <input name="username" type="text" placeholder="username"
<button type="submit"> autocomplete="username" autocapitalize="none" autocorrect="off"
move in spellcheck="false" required autofocus>
</button> </label>
<% if (it.error) { %> <label>password
<%= it.error %> <input name="password" type="password" placeholder="password"
<% } %> autocomplete="new-password" required>
<br> </label>
<div> or you can <a href="/login<%= it.next ? '?next=' + encodeURIComponent(it.next) : '' %>">come home</a>. <button type="submit">move in</button>
</form> <% if (it.error) { %><div class="error"><%= it.error %></div><% } %>
<div class="alt">or you can <a href="/login<%= it.next ? '?next=' + encodeURIComponent(it.next) : '' %>">come home</a>.</div>
</form>
</body>
</html>