Skip to content

Commit 9a0eaef

Browse files
committed
fix(app): add basic error feedback to login form
1 parent ac49499 commit 9a0eaef

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

crates/site-app/src/hooks/login_hook.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ impl LoginHook {
120120
})
121121
}
122122

123+
pub fn feedback_error_text(&self) -> Signal<Option<&'static str>> {
124+
let value = self.action.value();
125+
Signal::derive(move || match value.get() {
126+
Some(Ok(true)) => None,
127+
Some(Ok(false)) => Some("The credentials you entered don't match."),
128+
Some(Err(_)) => Some("Login failed. Please try again later."),
129+
None => None,
130+
})
131+
}
132+
123133
pub fn action_trigger(&self) -> Callback<()> {
124134
let submit_touched_signal = self.submit_touched_signal;
125135
let email_error_hint = self.email_error_hint();

crates/site-app/src/pages/login.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fn LoginIsland() -> impl IntoView {
2525
signup_trigger.run(());
2626
};
2727
let show_spinner = login_hook.show_spinner();
28+
let error_feedback = login_hook.feedback_error_text();
2829

2930
let _ = login_hook.create_redirect_effect();
3031

@@ -57,17 +58,24 @@ fn LoginIsland() -> impl IntoView {
5758
/>
5859
</div>
5960

60-
<label class="flex flex-row gap-2">
61-
<input type="submit" class="hidden" />
62-
<button class="btn btn-primary w-full max-w-80 justify-between">
63-
<div class="size-4" />
64-
{ login_hook.button_text() }
65-
<LoadingCircle {..}
66-
class="size-4 transition-opacity"
67-
class=("opacity-0", move || { !show_spinner() })
68-
/>
69-
</button>
70-
</label>
61+
<div class="flex flex-col gap-4">
62+
<label class="flex flex-row gap-2">
63+
<input type="submit" class="hidden" />
64+
<button class="btn btn-primary w-full max-w-80 justify-between">
65+
<div class="size-4" />
66+
{ login_hook.button_text() }
67+
<LoadingCircle {..}
68+
class="size-4 transition-opacity"
69+
class=("opacity-0", move || { !show_spinner() })
70+
/>
71+
</button>
72+
</label>
73+
{ move || error_feedback().map(move |text| view! {
74+
<p class="animate-fade-down text-critical-11 text-sm">
75+
{ text }
76+
</p>
77+
})}
78+
</div>
7179
</form>
7280
}
7381
}

0 commit comments

Comments
 (0)