ReviewOS

also looking at this

stacks/reportshq

fix(ui): align component theme and login step visibility

#39
Merged glennmichael123 wants to merge fix/reportshq-component-theme into main
4 files +163 -77
resources/views/login.stxmodified+67-63
Changes to resources/views/login.stx
@@ -37,74 +37,78 @@ const signedIn = session.user !== null
3737 {{-- A real form, so a password manager recognises it and the enter key
3838 submits. The script intercepts it; without the script it still
3939 posts somewhere sensible rather than nowhere. --}}
40 <form id="signin" method="post" action="/api/auth/login" class="grid gap-4">
41 <label class="block">
42 <span class="block mb-1 text-muted text-sm">Email</span>
43 <input
44 id="email"
45 name="email"
46 type="email"
47 autocomplete="username"
48 required
49 class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error"
50 />
51 </label>
52
53 <label class="block">
54 <span class="block mb-1 text-muted text-sm">Password</span>
55 <input
56 id="password"
57 name="password"
58 type="password"
59 autocomplete="current-password"
60 required
61 class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error"
62 />
63 </label>
64
65 {{-- Off by default: a shared machine should not opt into a month-long
66 session by accident. Checked lengthens the session to 30 days;
67 unchecked is the one-week baseline. --}}
68 <label class="flex gap-2 items-center text-muted text-sm cursor-pointer select-none">
69 <input id="remember" name="remember" type="checkbox" class="h-4 w-4 accent-accent" />
70 <span>Keep me signed in for 30 days</span>
71 </label>
72
73 <p id="error" class="text-sm text-warn" role="alert" hidden></p>
74
75 <button
76 id="submit"
77 type="submit"
78 class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60"
79 >Sign in</button>
40 <form id="signin" method="post" action="/api/auth/login">
41 <div class="grid gap-4">
42 <label class="block">
43 <span class="block mb-1 text-muted text-sm">Email</span>
44 <input
45 id="email"
46 name="email"
47 type="email"
48 autocomplete="username"
49 required
50 class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error"
51 />
52 </label>
53
54 <label class="block">
55 <span class="block mb-1 text-muted text-sm">Password</span>
56 <input
57 id="password"
58 name="password"
59 type="password"
60 autocomplete="current-password"
61 required
62 class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error"
63 />
64 </label>
65
66 {{-- Off by default: a shared machine should not opt into a month-long
67 session by accident. Checked lengthens the session to 30 days;
68 unchecked is the one-week baseline. --}}
69 <label class="flex gap-2 items-center text-muted text-sm cursor-pointer select-none">
70 <input id="remember" name="remember" type="checkbox" class="h-4 w-4 accent-accent" />
71 <span>Keep me signed in for 30 days</span>
72 </label>
73
74 <p id="error" class="text-sm text-warn" role="alert" hidden></p>
75
76 <button
77 id="submit"
78 type="submit"
79 class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60"
80 >Sign in</button>
81 </div>
8082 </form>
8183
8284 {{-- Second step, revealed only when the account has 2FA enabled. Dormant
8385 until an enrollment surface ships, but present so a 2FA account can
8486 never sign in halfway and stall. --}}
85 <form id="twofa" method="post" action="/api/auth/verify-two-factor-login" class="grid gap-4" hidden>
86 <h2 class="font-semibold text-lg tracking-tight">Two-factor code</h2>
87 <p class="-mt-2 text-muted text-sm">Enter the 6-digit code from your authenticator app.</p>
88 <label class="block">
89 <span class="block mb-1 text-muted text-sm">Authentication code</span>
90 <input
91 id="code"
92 name="code"
93 type="text"
94 inputmode="numeric"
95 autocomplete="one-time-code"
96 maxlength="6"
97 class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg"
98 />
99 </label>
100
101 <p id="twofa-error" class="text-sm text-warn" role="alert" hidden></p>
102
103 <button
104 id="twofa-submit"
105 type="submit"
106 class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60"
107 >Verify and sign in</button>
87 <form id="twofa" method="post" action="/api/auth/verify-two-factor-login" hidden>
88 <div class="grid gap-4">
89 <h2 class="font-semibold text-lg tracking-tight">Two-factor code</h2>
90 <p class="-mt-2 text-muted text-sm">Enter the 6-digit code from your authenticator app.</p>
91 <label class="block">
92 <span class="block mb-1 text-muted text-sm">Authentication code</span>
93 <input
94 id="code"
95 name="code"
96 type="text"
97 inputmode="numeric"
98 autocomplete="one-time-code"
99 maxlength="6"
100 class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg"
101 />
102 </label>
103
104 <p id="twofa-error" class="text-sm text-warn" role="alert" hidden></p>
105
106 <button
107 id="twofa-submit"
108 type="submit"
109 class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60"
110 >Verify and sign in</button>
111 </div>
108112 </form>
109113
110114 <p class="mt-6 text-muted text-sm">