Rework app bar, notes layout, Settings/Admin/login restyle
Build and Push Docker Image / build-and-push (push) Failing after 20s

App bar: brand, Studies / Read Bible / Reading Plans, and one account menu
(theme, Settings, Admin, Log out). Study stage: notes get their own box above
the resources in the right column. Settings, Admin and the login page use the
reader themes; add a theme-aware danger colour.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-09-29 10:27:02 -04:00
1 parent 31abee0695
commit ecb1c701fa
22 files changed
+351 -289

No files matched your search

+38 -36
View File
@@ -1,9 +1,11 @@
import { useState } from 'react';
import { useApp } from '../context/AppContext.js';
import { themeVars } from '../components/reader/readerThemes.js';
import { loginUser, registerUser, verifyMfaLogin, logoutUser } from '../syncService.js';
export default function AuthPage() {
const { signIn } = useApp();
const { signIn, readerTheme } = useApp();
const shell = { style: themeVars(readerTheme) };
const [authMode, setAuthMode] = useState('login'); // 'login' | 'register'
const [authForm, setAuthForm] = useState({ email: '', password: '' });
const [authError, setAuthError] = useState('');
@@ -49,11 +51,11 @@ export default function AuthPage() {
if (authMfaPending) {
return (
<div className="flex min-h-screen items-center justify-center bg-slate-900 px-4">
<div className="w-full max-w-sm rounded-3xl border border-white/10 bg-white p-8 shadow-panel">
<p className="text-sm uppercase tracking-[0.24em] text-slate-400">Bible Study Project</p>
<h1 className="mt-2 text-xl font-semibold text-slate-900">Two-factor verification</h1>
<p className="mt-2 text-sm text-slate-500">
<div {...shell} className="flex min-h-screen items-center justify-center bg-[var(--r-bg)] px-4 text-[var(--r-text)]">
<div className="w-full max-w-sm rounded-2xl border border-[var(--r-line)] bg-[var(--r-bar)] p-8">
<p className="text-sm uppercase tracking-[0.24em] text-[var(--r-sub)]">Bible Study Project</p>
<h1 className="mt-2 text-xl font-medium text-[var(--r-text)]">Two-factor verification</h1>
<p className="mt-2 text-sm text-[var(--r-sub)]">
{authMfaUseBackup
? 'Enter one of your saved backup codes.'
: 'Enter the 6-digit code from your authenticator app.'}
@@ -67,13 +69,13 @@ export default function AuthPage() {
placeholder={authMfaUseBackup ? 'xxxxxxxxxx' : '123456'}
value={authMfaCode}
onChange={(e) => setAuthMfaCode(e.target.value)}
className="block w-full rounded-xl border border-slate-300 px-3 py-2 text-center text-lg tracking-widest shadow-sm focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-200"
className="block w-full rounded-xl border border-[var(--r-line)] bg-[var(--r-bg)] px-3 py-2 text-[var(--r-text)] text-center text-lg tracking-widest focus:outline-none focus:ring-2 focus:ring-[var(--r-line)]"
/>
{authError && <p className="text-sm text-rose-600">{authError}</p>}
{authError && <p className="text-sm text-[var(--r-danger,#b42318)]">{authError}</p>}
<button
type="submit"
disabled={authBusy}
className="w-full rounded-md bg-sky-500 px-4 py-2 text-sm font-medium text-white shadow-sm transition hover:bg-sky-400 disabled:cursor-not-allowed disabled:bg-slate-300"
className="w-full rounded-full bg-[var(--r-accent)] px-4 py-2.5 text-sm font-medium text-[var(--r-on)] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
>
{authBusy ? 'Verifying…' : 'Verify'}
</button>
@@ -85,7 +87,7 @@ export default function AuthPage() {
setAuthMfaCode('');
setAuthError('');
}}
className="mt-4 w-full text-center text-sm text-slate-500 underline hover:text-slate-700"
className="mt-4 w-full text-center text-sm text-[var(--r-sub)] underline hover:text-[var(--r-text)]"
>
{authMfaUseBackup ? 'Use your authenticator app instead' : "Lost your device? Use a backup code"}
</button>
@@ -97,7 +99,7 @@ export default function AuthPage() {
setAuthMfaCode('');
setAuthError('');
}}
className="mt-2 w-full text-center text-sm text-slate-400 underline hover:text-slate-600"
className="mt-2 w-full text-center text-sm text-[var(--r-sub)] underline hover:text-[var(--r-sub)]"
>
Cancel
</button>
@@ -107,41 +109,41 @@ export default function AuthPage() {
}
return (
<div className="flex min-h-screen items-center justify-center bg-slate-900 px-4 py-12">
<div {...shell} className="flex min-h-screen items-center justify-center bg-[var(--r-bg)] px-4 py-12 text-[var(--r-text)]">
<div className="grid w-full max-w-5xl items-center gap-16 lg:grid-cols-2">
{/* Branding / feature panel — hidden on small screens to keep the form front and center there */}
<div className="hidden lg:block">
<p className="text-sm uppercase tracking-[0.24em] text-slate-400">Bible Study Project</p>
<h1 className="mt-4 text-3xl font-semibold leading-tight text-white">
Deep Bible study,<br />organized chunk by chunk.
<p className="text-sm uppercase tracking-[0.24em] text-[var(--r-sub)]">Bible Study Project</p>
<h1 className="mt-4 text-3xl font-semibold leading-tight text-[var(--r-text)]">
Deep Bible study,<br />one chunk at a time.
</h1>
<p className="mt-4 max-w-sm text-slate-300">
Split any passage into chunks and work through Observation, Interpretation, and
Application notes alongside Greek &amp; Hebrew word studies, cross-references, and commentary.
<p className="mt-4 max-w-sm text-[var(--r-sub)]">
Read Scripture in six translations, follow a reading plan into the text, and study a passage one chunk
at a time with commentary, word studies, and cross-references beside it.
</p>
<ul className="mt-8 space-y-4 text-sm text-slate-300">
<li className="flex items-center gap-3"><span className="text-lg">📖</span> Chunk-by-chunk OIA notes on any passage</li>
<li className="flex items-center gap-3"><span className="text-lg">🔤</span> Greek &amp; Hebrew word studies with pronunciation</li>
<li className="flex items-center gap-3"><span className="text-lg">🔗</span> Cross-references and commentary, one click away</li>
<li className="flex items-center gap-3"><span className="text-lg">🎙</span> Turn your notes into a podcast-ready script</li>
<li className="flex items-center gap-3"><span className="text-lg">🔒</span> Your studies stay private to your account, with optional 2FA</li>
<ul className="mt-8 space-y-3 text-sm text-[var(--r-sub)]">
<li>Read in BSB, ESV, NLT, CSB, NASB, or NET, with audio and search</li>
<li>Reading plans that open straight into the Reader</li>
<li>Observe, Interpret, Apply notes with Greek &amp; Hebrew word studies</li>
<li>Turn your notes into a script, then export or share</li>
<li>Your studies stay private to your account, with optional 2FA</li>
</ul>
<blockquote className="mt-8 border-l-2 border-slate-700 pl-4 text-sm italic text-slate-400">
<blockquote className="mt-8 border-l-2 border-[var(--r-line)] pl-4 text-sm italic text-[var(--r-sub)]">
"Make every effort to present yourself approved to God, an unashamed workman who accurately
handles the word of truth."
<footer className="mt-1 not-italic text-slate-500">— 2 Timothy 2:15 (BSB)</footer>
<footer className="mt-1 not-italic text-[var(--r-sub)]">— 2 Timothy 2:15 (BSB)</footer>
</blockquote>
</div>
{/* Sign in / register form */}
<div className="flex justify-center lg:justify-start">
<div className="w-full max-w-sm rounded-3xl border border-white/10 bg-white p-8 shadow-panel">
<p className="text-sm uppercase tracking-[0.24em] text-slate-400 lg:hidden">Bible Study Project</p>
<h1 className="mt-2 text-xl font-semibold text-slate-900">
<div className="w-full max-w-sm rounded-2xl border border-[var(--r-line)] bg-[var(--r-bar)] p-8">
<p className="text-sm uppercase tracking-[0.24em] text-[var(--r-sub)] lg:hidden">Bible Study Project</p>
<h1 className="mt-2 text-xl font-medium text-[var(--r-text)]">
{authMode === 'login' ? 'Sign in' : 'Create an account'}
</h1>
<form onSubmit={submitAuth} className="mt-6 space-y-4">
<label className="block text-sm font-medium text-slate-700">
<label className="block text-sm">
Email
<input
type="email"
@@ -149,10 +151,10 @@ export default function AuthPage() {
autoComplete="email"
value={authForm.email}
onChange={(e) => setAuthForm((f) => ({ ...f, email: e.target.value }))}
className="mt-1 block w-full rounded-xl border border-slate-300 px-3 py-2 text-sm shadow-sm focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-200"
className="mt-1 block w-full rounded-xl border border-[var(--r-line)] bg-[var(--r-bg)] px-3 py-2 text-[var(--r-text)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--r-line)]"
/>
</label>
<label className="block text-sm font-medium text-slate-700">
<label className="block text-sm font-medium text-[var(--r-text)]">
Password
<input
type="password"
@@ -161,14 +163,14 @@ export default function AuthPage() {
autoComplete={authMode === 'login' ? 'current-password' : 'new-password'}
value={authForm.password}
onChange={(e) => setAuthForm((f) => ({ ...f, password: e.target.value }))}
className="mt-1 block w-full rounded-xl border border-slate-300 px-3 py-2 text-sm shadow-sm focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-200"
className="mt-1 block w-full rounded-xl border border-[var(--r-line)] bg-[var(--r-bg)] px-3 py-2 text-[var(--r-text)] text-sm focus:outline-none focus:ring-2 focus:ring-[var(--r-line)]"
/>
</label>
{authError && <p className="text-sm text-rose-600">{authError}</p>}
{authError && <p className="text-sm text-[var(--r-danger,#b42318)]">{authError}</p>}
<button
type="submit"
disabled={authBusy}
className="w-full rounded-md bg-sky-500 px-4 py-2 text-sm font-medium text-white shadow-sm transition hover:bg-sky-400 disabled:cursor-not-allowed disabled:bg-slate-300"
className="w-full rounded-full bg-[var(--r-accent)] px-4 py-2.5 text-sm font-medium text-[var(--r-on)] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
>
{authBusy ? 'Please wait…' : authMode === 'login' ? 'Sign in' : 'Create account'}
</button>
@@ -179,7 +181,7 @@ export default function AuthPage() {
setAuthMode((m) => (m === 'login' ? 'register' : 'login'));
setAuthError('');
}}
className="mt-4 w-full text-center text-sm text-slate-500 underline hover:text-slate-700"
className="mt-4 w-full text-center text-sm text-[var(--r-sub)] underline hover:text-[var(--r-text)]"
>
{authMode === 'login' ? "Need an account? Sign up" : 'Already have an account? Sign in'}
</button>