Skip to content

Commit 09e0a6d

Browse files
committed
added show password functionality and also added how rules work button
1 parent b6c63b0 commit 09e0a6d

6 files changed

Lines changed: 149 additions & 22 deletions

File tree

web/register.html

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,32 +88,72 @@ <h1 class="nf-title">Take control of your finances.</h1>
8888
/>
8989

9090
<label for="password">Password</label>
91-
<input
92-
type="password"
93-
id="password"
94-
name="password"
95-
class="nf-input"
96-
placeholder="Create a strong password"
97-
autocomplete="new-password"
98-
minlength="8"
99-
required
100-
/>
91+
<div class="password-field">
92+
<input
93+
type="password"
94+
id="password"
95+
name="password"
96+
class="nf-input"
97+
placeholder="Create a strong password"
98+
autocomplete="new-password"
99+
minlength="8"
100+
required
101+
/>
102+
<button
103+
type="button"
104+
class="password-toggle"
105+
data-target="password"
106+
aria-label="Show password"
107+
aria-pressed="false"
108+
>
109+
<svg class="password-toggle-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110+
<path
111+
class="eye"
112+
d="M12 5c5.5 0 9.5 4.5 10 6.1-.5 1.6-4.5 6.9-10 6.9S2.5 12.7 2 11.1C2.5 9.5 6.5 5 12 5zm0 2C8 7 4.8 9.9 4.1 11.1 4.8 12.4 8 15 12 15s7.2-2.6 7.9-3.9C19.2 9.9 16 7 12 7zm0 1.5A2.5 2.5 0 1 1 9.5 11 2.5 2.5 0 0 1 12 8.5z"
113+
/>
114+
<path
115+
class="eye-off"
116+
d="M4.2 4.2a1 1 0 0 1 1.4 0l14.2 14.2a1 1 0 0 1-1.4 1.4l-2.4-2.4A10.8 10.8 0 0 1 12 19c-5.5 0-9.5-4.5-10-6.1.3-1 1.9-3.4 4.4-5.1L4.2 5.6a1 1 0 0 1 0-1.4zm4.3 4.3 1.9 1.9a2.5 2.5 0 0 0 3.2 3.2l1.9 1.9A6 6 0 0 1 8.5 8.5zm3.5-3.4A10.7 10.7 0 0 1 22 11.1c-.3 1-1.9 3.4-4.4 5.1l-1.5-1.5c1.9-1.1 3.4-2.6 3.9-3.6-.7-1.2-3.9-4.1-7.9-4.1-.9 0-1.8.1-2.6.4l-1.5-1.5c1-.3 2.1-.6 3.3-.6z"
117+
/>
118+
</svg>
119+
</button>
120+
</div>
101121

102122
<p class="subtle" style="margin: -0.25rem 0 0.75rem;">
103123
Use at least 8 characters.
104124
</p>
105125

106126
<label for="confirmPassword">Confirm Password</label>
107-
<input
108-
type="password"
109-
id="confirmPassword"
110-
name="confirmPassword"
111-
class="nf-input"
112-
placeholder="Re-enter your password"
113-
autocomplete="new-password"
114-
minlength="8"
115-
required
116-
/>
127+
<div class="password-field">
128+
<input
129+
type="password"
130+
id="confirmPassword"
131+
name="confirmPassword"
132+
class="nf-input"
133+
placeholder="Re-enter your password"
134+
autocomplete="new-password"
135+
minlength="8"
136+
required
137+
/>
138+
<button
139+
type="button"
140+
class="password-toggle"
141+
data-target="confirmPassword"
142+
aria-label="Show password"
143+
aria-pressed="false"
144+
>
145+
<svg class="password-toggle-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
146+
<path
147+
class="eye"
148+
d="M12 5c5.5 0 9.5 4.5 10 6.1-.5 1.6-4.5 6.9-10 6.9S2.5 12.7 2 11.1C2.5 9.5 6.5 5 12 5zm0 2C8 7 4.8 9.9 4.1 11.1 4.8 12.4 8 15 12 15s7.2-2.6 7.9-3.9C19.2 9.9 16 7 12 7zm0 1.5A2.5 2.5 0 1 1 9.5 11 2.5 2.5 0 0 1 12 8.5z"
149+
/>
150+
<path
151+
class="eye-off"
152+
d="M4.2 4.2a1 1 0 0 1 1.4 0l14.2 14.2a1 1 0 0 1-1.4 1.4l-2.4-2.4A10.8 10.8 0 0 1 12 19c-5.5 0-9.5-4.5-10-6.1.3-1 1.9-3.4 4.4-5.1L4.2 5.6a1 1 0 0 1 0-1.4zm4.3 4.3 1.9 1.9a2.5 2.5 0 0 0 3.2 3.2l1.9 1.9A6 6 0 0 1 8.5 8.5zm3.5-3.4A10.7 10.7 0 0 1 22 11.1c-.3 1-1.9 3.4-4.4 5.1l-1.5-1.5c1.9-1.1 3.4-2.6 3.9-3.6-.7-1.2-3.9-4.1-7.9-4.1-.9 0-1.8.1-2.6.4l-1.5-1.5c1-.3 2.1-.6 3.3-.6z"
153+
/>
154+
</svg>
155+
</button>
156+
</div>
117157

118158
<label style="display:flex; gap:0.5rem; align-items:flex-start; margin-top: 0.25rem;">
119159
<input type="checkbox" id="agree" name="agree" required style="margin-top:0.2rem;" />

web/rules.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ <h1>Rules Engine</h1>
5656
<div class="rules-hero-actions">
5757
<button class="btn btn--primary" id="btnCreateRule" type="button">Create Rule</button>
5858
<button class="btn" id="btnApplyRules" type="button">Apply To Existing</button>
59+
<button class="btn btn--link rules-help-btn" id="btnRulesHelp" type="button">How rules work</button>
5960
</div>
6061
</section>
6162

web/scripts/register.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ document.addEventListener("DOMContentLoaded", () => {
1010
const googleRegisterBtn = document.getElementById("googleRegisterBtn");
1111
const passwordInput = document.getElementById("password");
1212
const confirmInput = document.getElementById("confirmPassword");
13+
const passwordToggles = document.querySelectorAll(".password-toggle");
1314
const legalModal = document.getElementById("legalModal");
1415
const legalModalTitle = document.getElementById("legalModalTitle");
1516
const legalModalBody = document.getElementById("legalModalBody");
@@ -97,6 +98,23 @@ document.addEventListener("DOMContentLoaded", () => {
9798
showMsg(googleRedirect.error, "error");
9899
}
99100

101+
passwordToggles.forEach((toggle) => {
102+
toggle.addEventListener("click", () => {
103+
const targetId = toggle.getAttribute("data-target");
104+
const target = targetId ? document.getElementById(targetId) : null;
105+
if (!target) return;
106+
const showing = target.type === "password";
107+
target.type = showing ? "text" : "password";
108+
toggle.classList.toggle("is-active", showing);
109+
toggle.setAttribute("aria-pressed", showing ? "true" : "false");
110+
toggle.setAttribute("aria-label", showing ? "Hide password" : "Show password");
111+
target.focus();
112+
if (target === passwordInput || target === confirmInput) {
113+
updatePasswordStyles();
114+
}
115+
});
116+
});
117+
100118
const syncModalScrollLock = () => {
101119
const legalOpen = legalModal && !legalModal.classList.contains("hidden");
102120
const contactOpen = contactModal && !contactModal.classList.contains("hidden");

web/scripts/rules.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ document.addEventListener("DOMContentLoaded", () => {
99
const btnCreateRule = document.getElementById("btnCreateRule");
1010
const btnCreateRuleEmpty = document.getElementById("btnCreateRuleEmpty");
1111
const btnApplyRules = document.getElementById("btnApplyRules");
12+
const btnRulesHelp = document.getElementById("btnRulesHelp");
1213
const rulesEnabledCount = document.getElementById("rulesEnabledCount");
1314
const rulesTotalCount = document.getElementById("rulesTotalCount");
1415

@@ -58,6 +59,14 @@ document.addEventListener("DOMContentLoaded", () => {
5859
const hideModal = () => ruleModal?.classList.add("hidden");
5960
const showOnboarding = () => rulesOnboardingModal?.classList.remove("hidden");
6061
const hideOnboarding = () => rulesOnboardingModal?.classList.add("hidden");
62+
const syncOnboardingPreference = () => {
63+
if (!rulesOnboardingDontShow) return;
64+
rulesOnboardingDontShow.checked = !!localStorage.getItem(ONBOARDING_KEY);
65+
};
66+
const openOnboarding = () => {
67+
syncOnboardingPreference();
68+
showOnboarding();
69+
};
6170

6271
const getRulePayload = () => {
6372
const conditions = [];
@@ -406,6 +415,7 @@ document.addEventListener("DOMContentLoaded", () => {
406415
ruleCancelBtn?.addEventListener("click", () => hideModal());
407416
btnCreateRule?.addEventListener("click", openCreate);
408417
btnCreateRuleEmpty?.addEventListener("click", openCreate);
418+
btnRulesHelp?.addEventListener("click", openOnboarding);
409419
rulesOnboardingClose?.addEventListener("click", () => {
410420
if (rulesOnboardingDontShow?.checked) {
411421
localStorage.setItem(ONBOARDING_KEY, "true");
@@ -452,8 +462,7 @@ document.addEventListener("DOMContentLoaded", () => {
452462
prefillFromQuery();
453463
updateLiveSummary();
454464
if (!localStorage.getItem(ONBOARDING_KEY)) {
455-
if (rulesOnboardingDontShow) rulesOnboardingDontShow.checked = false;
456-
showOnboarding();
465+
openOnboarding();
457466
}
458467
} catch (err) {
459468
showStatus(`Failed to load rules: ${err?.message || "Unknown error"}`, "error");

web/styles/auth.css

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,61 @@ body.landing-light {
490490
gap: 1rem;
491491
}
492492

493+
.password-field {
494+
position: relative;
495+
display: flex;
496+
align-items: center;
497+
}
498+
499+
.password-field .nf-input {
500+
width: 100%;
501+
padding-right: 2.75rem;
502+
}
503+
504+
.auth-form .password-toggle {
505+
position: absolute;
506+
right: 0.65rem;
507+
top: 50%;
508+
transform: translateY(-50%);
509+
padding: 0.25rem;
510+
border: none;
511+
background: transparent;
512+
color: var(--muted);
513+
border-radius: 999px;
514+
cursor: pointer;
515+
line-height: 0;
516+
box-shadow: none;
517+
}
518+
519+
.auth-form .password-toggle:hover {
520+
color: var(--text);
521+
background: rgba(15,23,42,0.06);
522+
}
523+
524+
.auth-form .password-toggle:focus-visible {
525+
outline: 2px solid var(--accent);
526+
outline-offset: 2px;
527+
}
528+
529+
.password-toggle-icon {
530+
width: 20px;
531+
height: 20px;
532+
display: block;
533+
fill: currentColor;
534+
}
535+
536+
.password-toggle .eye-off {
537+
opacity: 0;
538+
}
539+
540+
.password-toggle.is-active .eye {
541+
opacity: 0;
542+
}
543+
544+
.password-toggle.is-active .eye-off {
545+
opacity: 1;
546+
}
547+
493548
.auth-form input {
494549
padding: 0.75rem;
495550
border-radius: var(--radius);

web/styles/rules.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
flex-wrap: wrap;
6363
}
6464

65+
.rules-help-btn {
66+
padding-inline: 0;
67+
}
68+
6569
.rules-section {
6670
display: grid;
6771
gap: 1rem;

0 commit comments

Comments
 (0)