96 lines
4.0 KiB
Rust
96 lines
4.0 KiB
Rust
use yew::prelude::*;
|
|
use web_sys::HtmlInputElement;
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct LoginFormProps {
|
|
pub on_submit: Callback<(String, String)>, // (email, password)
|
|
pub error_message: Option<String>,
|
|
}
|
|
|
|
#[function_component(LoginForm)]
|
|
pub fn login_form(props: &LoginFormProps) -> Html {
|
|
let email_ref = use_node_ref();
|
|
let password_ref = use_node_ref();
|
|
let on_submit = props.on_submit.clone();
|
|
|
|
let onsubmit = {
|
|
let email_ref = email_ref.clone();
|
|
let password_ref = password_ref.clone();
|
|
Callback::from(move |e: SubmitEvent| {
|
|
e.prevent_default();
|
|
|
|
let email = email_ref
|
|
.cast::<HtmlInputElement>()
|
|
.map(|input| input.value())
|
|
.unwrap_or_default();
|
|
|
|
let password = password_ref
|
|
.cast::<HtmlInputElement>()
|
|
.map(|input| input.value())
|
|
.unwrap_or_default();
|
|
|
|
on_submit.emit((email, password));
|
|
})
|
|
};
|
|
|
|
html! {
|
|
<div class="login-container">
|
|
<div class="container">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-6">
|
|
<div class="card shadow login-card">
|
|
<div class="card-header bg-primary text-white">
|
|
<h4 class="mb-0">{"Login"}</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
{if let Some(error) = &props.error_message {
|
|
html! {
|
|
<div class="alert alert-danger" role="alert">
|
|
{error}
|
|
</div>
|
|
}
|
|
} else {
|
|
html! {}
|
|
}}
|
|
|
|
<form {onsubmit}>
|
|
<div class="mb-3">
|
|
<label for="email" class="form-label">{"Email address"}</label>
|
|
<input
|
|
type="email"
|
|
class="form-control"
|
|
id="email"
|
|
name="email"
|
|
ref={email_ref}
|
|
required=true
|
|
/>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="password" class="form-label">{"Password"}</label>
|
|
<input
|
|
type="password"
|
|
class="form-control"
|
|
id="password"
|
|
name="password"
|
|
ref={password_ref}
|
|
required=true
|
|
/>
|
|
</div>
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-primary">{"Login"}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="card-footer text-center">
|
|
<p class="mb-0">
|
|
{"Don't have an account? "}
|
|
<a href="/register">{"Register"}</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
} |