ft/adds phone and mail validation to clues

TODO: signup/register
This commit is contained in:
itsscb 2024-05-31 21:52:59 +02:00
parent 59c400906b
commit 08b0b058f2
12 changed files with 113 additions and 22 deletions

View File

@ -13,3 +13,4 @@ gloo-console = "0.3.0"
yewdux = "0.10.0" yewdux = "0.10.0"
serde = "1.0.198" serde = "1.0.198"
serde_json = "1.0.116" serde_json = "1.0.116"
regex = "1.10.4"

View File

@ -571,6 +571,16 @@ function __wbg_get_imports() {
getInt32Memory0()[arg0 / 4 + 1] = len1; getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1; getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}; };
imports.wbg.__wbg_className_5d3a8bc179d8555f = function(arg0, arg1) {
const ret = getObject(arg1).className;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setclassName_9fee267eae0d8ddc = function(arg0, arg1, arg2) {
getObject(arg0).className = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setinnerHTML_26d69b59e1af99c7 = function(arg0, arg1, arg2) { imports.wbg.__wbg_setinnerHTML_26d69b59e1af99c7 = function(arg0, arg1, arg2) {
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2); getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
}; };
@ -936,16 +946,16 @@ function __wbg_get_imports() {
const ret = wasm.memory; const ret = wasm.memory;
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_closure_wrapper6624 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper14859 = function(arg0, arg1, arg2) {
const ret = makeClosure(arg0, arg1, 740, __wbg_adapter_40); const ret = makeClosure(arg0, arg1, 1516, __wbg_adapter_40);
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_closure_wrapper8507 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper16840 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 868, __wbg_adapter_43); const ret = makeMutClosure(arg0, arg1, 1650, __wbg_adapter_43);
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_closure_wrapper8704 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper17039 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 881, __wbg_adapter_46); const ret = makeMutClosure(arg0, arg1, 1663, __wbg_adapter_46);
return addHeapObject(ret); return addHeapObject(ret);
}; };
@ -988,7 +998,7 @@ async function __wbg_init(input) {
if (wasm !== undefined) return wasm; if (wasm !== undefined) return wasm;
if (typeof input === 'undefined') { if (typeof input === 'undefined') {
input = new URL('digitaler-frieden-23bb9eba3fb849f290b6e7e45997c57afdeccc3b773f7f82ee309a94e1387dda091e56509bc08920e251645096b7194c_bg.wasm', import.meta.url); input = new URL('digitaler-frieden-66f4a2f1dfe699d158fb216baa50f09298585f4829c65922dcdfe4324ea2e6d37b258786aad38b71270f40b7bef9e4d0_bg.wasm', import.meta.url);
} }
const imports = __wbg_get_imports(); const imports = __wbg_get_imports();

10
dist/index.html vendored
View File

@ -2,20 +2,20 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Digitaler Frieden</title> <title>Digitaler Frieden</title>
<link rel="stylesheet" href="/styles-25689c825de51fae.css" integrity="sha384-idDVKeYHrC3A1H5zUTTAuwnknbi8drZxZR0VadSO3YLJXXibjztmCcFlXMYb8nj2"> <link rel="stylesheet" href="/styles-2f497d8ef19829ea.css" integrity="sha384-xjbFA5YII5ii4ycMp1VG9QYAac57eQoe_5ODSF-7wl5-9HE4Y1gF6bNlX9x-yPi6">
<link rel="icon" href="/favicon-928ba63f33046eed.ico" integrity="sha384-Neq57jnFrTfqAN1JvKAVVVcH1EW3__cZHmK2NRXRlNrxAZR6ErTvXzbOLSyHzkA4"> <link rel="icon" href="/favicon-928ba63f33046eed.ico" integrity="sha384-Neq57jnFrTfqAN1JvKAVVVcH1EW3__cZHmK2NRXRlNrxAZR6ErTvXzbOLSyHzkA4">
<link rel="manifest" href="public/manifest.json"> <link rel="manifest" href="public/manifest.json">
<link rel="preload" href="/digitaler-frieden-23bb9eba3fb849f290b6e7e45997c57afdeccc3b773f7f82ee309a94e1387dda091e56509bc08920e251645096b7194c_bg.wasm" as="fetch" type="application/wasm" crossorigin="anonymous" integrity="sha384-I7ueuj-4SfKQtufkWZfFev3szDt3P3-C7jCalOE4fdoJHlZQm8CJIOJRZFCWtxlM"> <link rel="preload" href="/digitaler-frieden-66f4a2f1dfe699d158fb216baa50f09298585f4829c65922dcdfe4324ea2e6d37b258786aad38b71270f40b7bef9e4d0_bg.wasm" as="fetch" type="application/wasm" crossorigin="anonymous" integrity="sha384-ZvSi8d_mmdFY-yFrqlDwkphYX0gpxlki3N_kMk6i5tN7JYeGqtOLcScPQLe--eTQ">
<link rel="modulepreload" href="/digitaler-frieden-23bb9eba3fb849f290b6e7e45997c57afdeccc3b773f7f82ee309a94e1387dda091e56509bc08920e251645096b7194c.js" crossorigin="anonymous" integrity="sha384-WA_9K_FUqzGPcLlhTBcSsHpY4reSZs6Ea87HOPH1hj0hTYxLP-xpwqE9AV2SsgMO"></head> <link rel="modulepreload" href="/digitaler-frieden-66f4a2f1dfe699d158fb216baa50f09298585f4829c65922dcdfe4324ea2e6d37b258786aad38b71270f40b7bef9e4d0.js" crossorigin="anonymous" integrity="sha384-wp6sqTySFAnU_e-tFtq2_-hxFMNiD46wtXFfn9-N_Sucj0pEppfQsGk2x10MkLQC"></head>
<body class="bg-black text-white"> <body class="bg-black text-white">
<script type="module"> <script type="module">
import init, * as bindings from '/digitaler-frieden-23bb9eba3fb849f290b6e7e45997c57afdeccc3b773f7f82ee309a94e1387dda091e56509bc08920e251645096b7194c.js'; import init, * as bindings from '/digitaler-frieden-66f4a2f1dfe699d158fb216baa50f09298585f4829c65922dcdfe4324ea2e6d37b258786aad38b71270f40b7bef9e4d0.js';
init('/digitaler-frieden-23bb9eba3fb849f290b6e7e45997c57afdeccc3b773f7f82ee309a94e1387dda091e56509bc08920e251645096b7194c_bg.wasm'); init('/digitaler-frieden-66f4a2f1dfe699d158fb216baa50f09298585f4829c65922dcdfe4324ea2e6d37b258786aad38b71270f40b7bef9e4d0_bg.wasm');
window.wasmBindings = bindings; window.wasmBindings = bindings;
</script><script>"use strict"; </script><script>"use strict";

View File

@ -891,6 +891,11 @@ video {
animation: logo-fadein-right 1s ; animation: logo-fadein-right 1s ;
} }
.validation-error {
border-style: solid;
border-color: rgba(255, 82, 82,1.0);
}
@keyframes logo-fadein-right { @keyframes logo-fadein-right {
0% { 0% {
transform: translateX(-200%); transform: translateX(-200%);
@ -1059,6 +1064,10 @@ video {
border-color: rgba(51,217,178,1.0); border-color: rgba(51,217,178,1.0);
} }
.border-error {
border-color: rgba(255, 82, 82,1.0) !important;
}
.accent-primary { .accent-primary {
accent-color: rgba(51, 217, 178,1.0); accent-color: rgba(51, 217, 178,1.0);
} }

View File

@ -891,6 +891,11 @@ video {
animation: logo-fadein-right 1s ; animation: logo-fadein-right 1s ;
} }
.validation-error {
border-style: solid;
border-color: rgba(255, 82, 82,1.0);
}
@keyframes logo-fadein-right { @keyframes logo-fadein-right {
0% { 0% {
transform: translateX(-200%); transform: translateX(-200%);
@ -1059,6 +1064,10 @@ video {
border-color: rgba(51,217,178,1.0); border-color: rgba(51,217,178,1.0);
} }
.border-error {
border-color: rgba(255, 82, 82,1.0) !important;
}
.accent-primary { .accent-primary {
accent-color: rgba(51, 217, 178,1.0); accent-color: rgba(51, 217, 178,1.0);
} }

View File

@ -11,6 +11,10 @@
animation: logo-fadein-right 1s ; animation: logo-fadein-right 1s ;
} }
.validation-error {
@apply border-solid border-error;
}
@keyframes logo-fadein-right { @keyframes logo-fadein-right {
0% { 0% {
transform: translateX(-200%); transform: translateX(-200%);
@ -157,6 +161,9 @@ opacity:1}
border-color: rgba(51,217,178,1.0); border-color: rgba(51,217,178,1.0);
} }
.border-error {
border-color: rgba(255, 82, 82,1.0) !important;
}
.accent-primary { .accent-primary {
accent-color: rgba(51, 217, 178,1.0); accent-color: rgba(51, 217, 178,1.0);
} }

View File

@ -891,6 +891,11 @@ video {
animation: logo-fadein-right 1s ; animation: logo-fadein-right 1s ;
} }
.validation-error {
border-style: solid;
border-color: rgba(255, 82, 82,1.0);
}
@keyframes logo-fadein-right { @keyframes logo-fadein-right {
0% { 0% {
transform: translateX(-200%); transform: translateX(-200%);
@ -1059,6 +1064,10 @@ video {
border-color: rgba(51,217,178,1.0); border-color: rgba(51,217,178,1.0);
} }
.border-error {
border-color: rgba(255, 82, 82,1.0) !important;
}
.accent-primary { .accent-primary {
accent-color: rgba(51, 217, 178,1.0); accent-color: rgba(51, 217, 178,1.0);
} }

View File

@ -1,3 +1,4 @@
pub mod pages; pub mod pages;
pub mod router; pub mod router;
pub mod storage; pub mod storage;
mod validation;

View File

@ -2,7 +2,7 @@ use web_sys::{KeyboardEvent, MouseEvent};
use yew::{classes, function_component, html, Html}; use yew::{classes, function_component, html, Html};
use yew_router::components::Link; use yew_router::components::Link;
use crate::router::Route; use crate::{router::Route, validation};
#[function_component] #[function_component]
pub fn Clues() -> Html { pub fn Clues() -> Html {
@ -16,11 +16,24 @@ pub fn Clues() -> Html {
if let Some(input) = mail.cast::<web_sys::HtmlInputElement>() { if let Some(input) = mail.cast::<web_sys::HtmlInputElement>() {
let mut m = mails_callback.to_vec(); let mut m = mails_callback.to_vec();
let mail = input.value(); let mail = input.value();
if !mail.is_empty() && !m.contains(&mail) { let mut classes = input.class_name();
m.push(mail); match validation::validate_email(&mail) {
input.set_value(""); true => {
} if !m.contains(&mail) {
mails_callback.set(m); m.push(mail);
input.set_value("");
}
input.set_class_name(&classes.replace("validation-error", ""));
mails_callback.set(m);
}
false => match classes.find("validation-error") {
Some(_) => {}
None => {
classes.push_str(" validation-error");
input.set_class_name(&classes);
}
},
};
}; };
}) })
}; };
@ -52,11 +65,27 @@ pub fn Clues() -> Html {
if let Some(input) = phone.cast::<web_sys::HtmlInputElement>() { if let Some(input) = phone.cast::<web_sys::HtmlInputElement>() {
let mut m = phones_callback.to_vec(); let mut m = phones_callback.to_vec();
let phone = input.value(); let phone = input.value();
if !phone.is_empty() && !m.contains(&phone) { let mut classes = input.class_name();
m.push(phone); match validation::validate_phone_number(&phone) {
input.set_value(""); true => {
if !m.contains(&phone) {
m.push(phone);
input.set_value("");
}
input.set_class_name(&classes.replace("validation-error", ""));
phones_callback.set(m);
}
false => {
match classes.find("validation-error") {
Some(_) => {}
None => {
classes.push_str(" validation-error");
input.set_class_name(&classes);
}
}
// classes.retain("validation_error");
}
} }
phones_callback.set(m);
}; };
}) })
}; };
@ -142,6 +171,7 @@ pub fn Clues() -> Html {
<div class="flex justify-center items-center space-x-4 w-full"> <div class="flex justify-center items-center space-x-4 w-full">
<input <input
onkeypress={on_mail_add_press} onkeypress={on_mail_add_press}
type="email"
id="email" id="email"
ref={mail} ref={mail}
class={classes!( class={classes!(

15
src/validation.rs Normal file
View File

@ -0,0 +1,15 @@
use regex::Regex;
pub fn validate_email(email: &str) -> bool {
// Regular expression pattern for email validation
let email_regex = Regex::new(r"^[\w\.-]+@[\w\.-]+\.\w+$").unwrap();
email_regex.is_match(email)
}
pub fn validate_phone_number(phone_number: &str) -> bool {
// Regular expression pattern for phone number validation (all countries)
let phone_regex = Regex::new(r"^[\+0][\-.,\(\)\d\s]*$").unwrap();
phone_regex.is_match(phone_number)
}