From 45866ae49eaf43a72255a23829b07e3538c5212d Mon Sep 17 00:00:00 2001 From: fhuber Date: Sun, 24 Dec 2023 12:03:01 +0000 Subject: [PATCH] trying validation in settings --- public/app.js | 65 ++-- public/styles.css | 354 +--------------------- src/auth/middlewares.rs | 7 +- src/routes/profile.rs | 116 +++---- tailwind.config.js | 2 +- templates/article/create.html | 8 +- templates/meta/about.html | 4 +- templates/user/partial/settings_edit.html | 26 ++ templates/user/settings.html | 21 +- templates/user/settings_wrong_input.html | 35 --- 10 files changed, 125 insertions(+), 513 deletions(-) create mode 100644 templates/user/partial/settings_edit.html delete mode 100644 templates/user/settings_wrong_input.html diff --git a/public/app.js b/public/app.js index 04331d6..c058adb 100644 --- a/public/app.js +++ b/public/app.js @@ -111,7 +111,7 @@ function showMap(img:HTMLImageElement) { }); document.getElementById("map").classList.remove("hidden"); -} +}*/ function shareLink(title, url = window.location.href) { if (navigator.share) { @@ -127,47 +127,50 @@ function shareLink(title, url = window.location.href) { } else { // fallback } -} */ -import { Map, View } from "ol"; +} + +import {Map, View} from "ol"; import TileLayer from "ol/layer/Tile"; import OSM from "ol/source/OSM"; + export function replaceImg(img) { - img.onerror = null; - img.src = "/dist/icons/account.svg"; + img.onerror = null; + img.src = "/dist/icons/account.svg"; } + export const registerServiceWorker = async () => { - if ("serviceWorker" in navigator) { - try { - const registration = await navigator.serviceWorker.register( - "/dist/sw.js", - { - scope: "/", + if ("serviceWorker" in navigator) { + try { + const registration = await navigator.serviceWorker.register( + "/dist/sw.js", + { + scope: "/", + } + ); + if (registration.installing) { + console.log("Service worker installing"); + } else if (registration.waiting) { + console.log("Service worker installed"); + } else if (registration.active) { + console.log("Service worker active"); + } + } catch (error) { + console.error(`Registration failed with ${error}`); } - ); - if (registration.installing) { - console.log("Service worker installing"); - } else if (registration.waiting) { - console.log("Service worker installed"); - } else if (registration.active) { - console.log("Service worker active"); - } - } catch (error) { - console.error(`Registration failed with ${error}`); } - } }; //https://www.digitalocean.com/community/tools/minify //const {ol} = require('ol'); export function showMap2() { - console.log("ma2p"); - new Map({ - layers: [new TileLayer({ source: new OSM() })], - view: new View({ - center: [0, 0], - zoom: 2, - }), - target: "map", - }); + console.log("ma2p"); + new Map({ + layers: [new TileLayer({source: new OSM()})], + view: new View({ + center: [0, 0], + zoom: 2, + }), + target: "map", + }); } showMap2(); diff --git a/public/styles.css b/public/styles.css index 1f80a59..9592d36 100644 --- a/public/styles.css +++ b/public/styles.css @@ -3125,6 +3125,18 @@ input.tab:checked + .tab-content, outline-color: var(--fallback-bc,oklch(var(--bc)/0.2)); } +.input-primary { + --tw-border-opacity: 1; + border-color: var(--fallback-p,oklch(var(--p)/var(--tw-border-opacity))); +} + +.input-primary:focus, + .input-primary:focus-within { + --tw-border-opacity: 1; + border-color: var(--fallback-p,oklch(var(--p)/var(--tw-border-opacity))); + outline-color: var(--fallback-p,oklch(var(--p)/1)); +} + .input-error { --tw-border-opacity: 1; border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity))); @@ -4176,10 +4188,6 @@ input.tab:checked + .tab-content, border-width: 0 !important; } -.pointer-events-none { - pointer-events: none !important; -} - .invisible { visibility: hidden !important; } @@ -4196,14 +4204,6 @@ input.tab:checked + .tab-content, position: sticky !important; } -.-top-1 { - top: -0.25rem !important; -} - -.-top-1\.5 { - top: -0.375rem !important; -} - .bottom-0 { bottom: 0px !important; } @@ -4494,10 +4494,6 @@ input.tab:checked + .tab-content, width: 1.5rem !important; } -.w-72 { - width: 18rem !important; -} - .w-8 { width: 2rem !important; } @@ -4506,10 +4502,6 @@ input.tab:checked + .tab-content, width: 100% !important; } -.min-w-\[200px\] { - min-width: 200px !important; -} - .max-w-7xl { max-width: 80rem !important; } @@ -4547,12 +4539,6 @@ input.tab:checked + .tab-content, cursor: pointer !important; } -.select-none { - -webkit-user-select: none !important; - -moz-user-select: none !important; - user-select: none !important; -} - .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } @@ -4662,20 +4648,10 @@ input.tab:checked + .tab-content, overflow: hidden !important; } -.\!overflow-visible { - overflow: visible !important; -} - .overflow-y-auto { overflow-y: auto !important; } -.truncate { - overflow: hidden !important; - text-overflow: ellipsis !important; - white-space: nowrap !important; -} - .overflow-ellipsis { text-overflow: ellipsis !important; } @@ -4684,10 +4660,6 @@ input.tab:checked + .tab-content, border-radius: 0.25rem !important; } -.rounded-\[7px\] { - border-radius: 7px !important; -} - .rounded-full { border-radius: 9999px !important; } @@ -4722,10 +4694,6 @@ input.tab:checked + .tab-content, border-color: rgb(229 231 235 / var(--tw-border-opacity)) !important; } -.border-t-transparent { - border-top-color: transparent !important; -} - .bg-base-100 { --tw-bg-opacity: 1 !important; background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))) !important; @@ -4780,10 +4748,6 @@ input.tab:checked + .tab-content, background-color: var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity))) !important; } -.bg-transparent { - background-color: transparent !important; -} - .bg-white { --tw-bg-opacity: 1 !important; background-color: rgb(255 255 255 / var(--tw-bg-opacity)) !important; @@ -4955,11 +4919,6 @@ input.tab:checked + .tab-content, padding-bottom: 0.5rem !important; } -.py-2\.5 { - padding-top: 0.625rem !important; - padding-bottom: 0.625rem !important; -} - .py-4 { padding-top: 1rem !important; padding-bottom: 1rem !important; @@ -4999,10 +4958,6 @@ input.tab:checked + .tab-content, vertical-align: middle !important; } -.font-sans { - font-family: Inter var, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important; -} - .text-2xl { font-size: 1.5rem !important; line-height: 2rem !important; @@ -5018,10 +4973,6 @@ input.tab:checked + .tab-content, line-height: 2.5rem !important; } -.text-\[11px\] { - font-size: 11px !important; -} - .text-lg { font-size: 1.125rem !important; line-height: 1.75rem !important; @@ -5050,18 +5001,10 @@ input.tab:checked + .tab-content, font-weight: 500 !important; } -.font-normal { - font-weight: 400 !important; -} - .font-semibold { font-weight: 600 !important; } -.leading-tight { - line-height: 1.25 !important; -} - .tracking-tight { letter-spacing: -0.025em !important; } @@ -5171,14 +5114,6 @@ input.tab:checked + .tab-content, --tw-shadow: var(--tw-shadow-colored) !important; } -.outline { - outline-style: solid !important; -} - -.outline-0 { - outline-width: 0px !important; -} - .drop-shadow-md { --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)) !important; filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important; @@ -5303,153 +5238,6 @@ img { font-weight: 500 !important; } -.before\:pointer-events-none::before { - content: var(--tw-content) !important; - pointer-events: none !important; -} - -.before\:mr-1::before { - content: var(--tw-content) !important; - margin-right: 0.25rem !important; -} - -.before\:mt-\[6\.5px\]::before { - content: var(--tw-content) !important; - margin-top: 6.5px !important; -} - -.before\:box-border::before { - content: var(--tw-content) !important; - box-sizing: border-box !important; -} - -.before\:block::before { - content: var(--tw-content) !important; - display: block !important; -} - -.before\:h-1::before { - content: var(--tw-content) !important; - height: 0.25rem !important; -} - -.before\:h-1\.5::before { - content: var(--tw-content) !important; - height: 0.375rem !important; -} - -.before\:w-2::before { - content: var(--tw-content) !important; - width: 0.5rem !important; -} - -.before\:w-2\.5::before { - content: var(--tw-content) !important; - width: 0.625rem !important; -} - -.before\:rounded-tl-md::before { - content: var(--tw-content) !important; - border-top-left-radius: 0.375rem !important; -} - -.before\:border-l::before { - content: var(--tw-content) !important; - border-left-width: 1px !important; -} - -.before\:border-t::before { - content: var(--tw-content) !important; - border-top-width: 1px !important; -} - -.before\:transition-all::before { - content: var(--tw-content) !important; - transition-property: all !important; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !important; - transition-duration: 150ms !important; -} - -.after\:pointer-events-none::after { - content: var(--tw-content) !important; - pointer-events: none !important; -} - -.after\:ml-1::after { - content: var(--tw-content) !important; - margin-left: 0.25rem !important; -} - -.after\:mt-\[6\.5px\]::after { - content: var(--tw-content) !important; - margin-top: 6.5px !important; -} - -.after\:box-border::after { - content: var(--tw-content) !important; - box-sizing: border-box !important; -} - -.after\:block::after { - content: var(--tw-content) !important; - display: block !important; -} - -.after\:h-1::after { - content: var(--tw-content) !important; - height: 0.25rem !important; -} - -.after\:h-1\.5::after { - content: var(--tw-content) !important; - height: 0.375rem !important; -} - -.after\:w-2::after { - content: var(--tw-content) !important; - width: 0.5rem !important; -} - -.after\:w-2\.5::after { - content: var(--tw-content) !important; - width: 0.625rem !important; -} - -.after\:flex-grow::after { - content: var(--tw-content) !important; - flex-grow: 1 !important; -} - -.after\:rounded-tr-md::after { - content: var(--tw-content) !important; - border-top-right-radius: 0.375rem !important; -} - -.after\:border-r::after { - content: var(--tw-content) !important; - border-right-width: 1px !important; -} - -.after\:border-t::after { - content: var(--tw-content) !important; - border-top-width: 1px !important; -} - -.after\:transition-all::after { - content: var(--tw-content) !important; - transition-property: all !important; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !important; - transition-duration: 150ms !important; -} - -.placeholder-shown\:border:-moz-placeholder-shown { - border-width: 1px !important; -} - -.placeholder-shown\:border:placeholder-shown { - border-width: 1px !important; -} - .hover\:bg-accent:hover { --tw-bg-opacity: 1 !important; background-color: var(--fallback-a,oklch(var(--a)/var(--tw-bg-opacity))) !important; @@ -5483,23 +5271,6 @@ img { color: rgb(17 24 39 / var(--tw-text-opacity)) !important; } -.focus\:border-2:focus { - border-width: 2px !important; -} - -.focus\:border-gray-900:focus { - --tw-border-opacity: 1 !important; - border-color: rgb(17 24 39 / var(--tw-border-opacity)) !important; -} - -.focus\:border-t-transparent:focus { - border-top-color: transparent !important; -} - -.focus\:outline-0:focus { - outline-width: 0px !important; -} - .focus\:ring-0:focus { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important; --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important; @@ -5529,10 +5300,6 @@ img { cursor: not-allowed !important; } -.disabled\:border-0:disabled { - border-width: 0px !important; -} - .disabled\:opacity-50:disabled { opacity: 0.5 !important; } @@ -5552,103 +5319,6 @@ img { color: var(--fallback-s,oklch(var(--s)/var(--tw-text-opacity))) !important; } -.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:text-sm { - font-size: 0.875rem !important; - line-height: 1.25rem !important; -} - -.peer:placeholder-shown ~ .peer-placeholder-shown\:text-sm { - font-size: 0.875rem !important; - line-height: 1.25rem !important; -} - -.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:leading-\[3\.75\] { - line-height: 3.75 !important; -} - -.peer:placeholder-shown ~ .peer-placeholder-shown\:leading-\[3\.75\] { - line-height: 3.75 !important; -} - -.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:before\:border-transparent::before { - content: var(--tw-content) !important; - border-color: transparent !important; -} - -.peer:placeholder-shown ~ .peer-placeholder-shown\:before\:border-transparent::before { - content: var(--tw-content) !important; - border-color: transparent !important; -} - -.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:after\:border-transparent::after { - content: var(--tw-content) !important; - border-color: transparent !important; -} - -.peer:placeholder-shown ~ .peer-placeholder-shown\:after\:border-transparent::after { - content: var(--tw-content) !important; - border-color: transparent !important; -} - -.peer:focus ~ .peer-focus\:text-\[11px\] { - font-size: 11px !important; -} - -.peer:focus ~ .peer-focus\:leading-tight { - line-height: 1.25 !important; -} - -.peer:focus ~ .peer-focus\:text-gray-900 { - --tw-text-opacity: 1 !important; - color: rgb(17 24 39 / var(--tw-text-opacity)) !important; -} - -.peer:focus ~ .peer-focus\:before\:border-l-2::before { - content: var(--tw-content) !important; - border-left-width: 2px !important; -} - -.peer:focus ~ .peer-focus\:before\:border-t-2::before { - content: var(--tw-content) !important; - border-top-width: 2px !important; -} - -.peer:focus ~ .peer-focus\:before\:\!border-gray-900::before { - content: var(--tw-content) !important; - --tw-border-opacity: 1 !important; - border-color: rgb(17 24 39 / var(--tw-border-opacity)) !important; -} - -.peer:focus ~ .peer-focus\:after\:border-r-2::after { - content: var(--tw-content) !important; - border-right-width: 2px !important; -} - -.peer:focus ~ .peer-focus\:after\:border-t-2::after { - content: var(--tw-content) !important; - border-top-width: 2px !important; -} - -.peer:focus ~ .peer-focus\:after\:\!border-gray-900::after { - content: var(--tw-content) !important; - --tw-border-opacity: 1 !important; - border-color: rgb(17 24 39 / var(--tw-border-opacity)) !important; -} - -.peer:disabled ~ .peer-disabled\:text-transparent { - color: transparent !important; -} - -.peer:disabled ~ .peer-disabled\:before\:border-transparent::before { - content: var(--tw-content) !important; - border-color: transparent !important; -} - -.peer:disabled ~ .peer-disabled\:after\:border-transparent::after { - content: var(--tw-content) !important; - border-color: transparent !important; -} - :is([dir="rtl"] .rtl\:space-x-reverse) > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 1 !important; } diff --git a/src/auth/middlewares.rs b/src/auth/middlewares.rs index 74d9f72..1f8f6e1 100644 --- a/src/auth/middlewares.rs +++ b/src/auth/middlewares.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use askama::Template; use axum::{async_trait, extract::{Request, State}, Form, middleware::Next, response::{IntoResponse, Redirect}}; use axum::body::Body; @@ -162,10 +163,10 @@ impl IntoResponse for ServerError { #[derive(Template)] -#[template(path = "user/settings_wrong_input.html")] -struct ProfileSettingsInputWrongTemplate { +#[template(path = "user/partial/settings_edit.html")] +struct ProfileSettingsInputWrongTemplate<'a> { user_name: String, user_avatar: String, - error_message: String, + errors: &'a BTreeMap, } \ No newline at end of file diff --git a/src/routes/profile.rs b/src/routes/profile.rs index 924520b..064a756 100644 --- a/src/routes/profile.rs +++ b/src/routes/profile.rs @@ -1,3 +1,4 @@ +use std::collections::{BTreeMap, HashMap}; use askama::Template; use askama_axum::Response; use axum::{extract::{Extension, Path, State}, http::StatusCode, response::{IntoResponse, Redirect}, routing::get, Form, Router, async_trait}; @@ -9,7 +10,7 @@ use reqwest::Client; use reqwest::header::CONTENT_TYPE; use serde::{Deserialize, Serialize}; use sqlx::{PgPool, query}; -use validator::{Validate, ValidationError}; +use validator::{Validate, ValidationError, ValidationErrors}; use crate::auth::error_handling::AppError; use crate::auth::middlewares::ValidatedForm; @@ -90,16 +91,9 @@ async fn profile( struct ProfileSettingsTemplate { user_name: String, user_avatar: String, + errors: BTreeMap, } -#[derive(Template)] -#[template(path = "user/settings_wrong_input.html")] -struct ProfileSettingsInputWrongTemplate { - user_name: String, - user_avatar: String, - - error_message: String, -} async fn profile_settings( Extension(user_data): Extension>, @@ -115,9 +109,20 @@ async fn profile_settings( Ok(ProfileSettingsTemplate { user_name: user.name.unwrap_or("".to_string()), user_avatar: user.avatar.unwrap_or("".to_string()), + errors: Default::default(), }) } +#[derive(Template)] +#[template(path = "user/partial/settings_edit.html")] +struct ProfileSettingsEditTemplate { + user_name: String, + user_avatar: String, + + // error_message: String, + errors: HashMap, +} + #[derive(Clone, Debug, Validate, Deserialize)] struct EditProfile { #[validate(length(min = 10, message = "too short"))] @@ -130,80 +135,39 @@ struct EditProfile { async fn edit_profile( Extension(user_data): Extension>, State(db_pool): State, - ValidatedForm(input): ValidatedForm, -) -> Response { + Form(input): Form, +) -> Result { let user_id = user_data.unwrap().id; - if input.user_name.len() < 5 { - let mut headers = HeaderMap::new(); - // headers.insert(HX_TRIGGER, "close".parse().unwrap()); - - // headers.insert(StatusCode::CREATED) - return ProfileSettingsInputWrongTemplate { - user_name: input.user_name, - - user_avatar: input.user_avatar, - error_message: "Username has to be at least 5 characters long.".to_string(), - }.render().unwrap().into_response(); - } - - if !input.user_avatar.is_empty() && !vec![".png", ".jpg", ".jpeg"].iter().any(|e| input.user_avatar.ends_with(e)) { - /* return ProfileSettingsInputWrongTemplate { - user_name: input.user_name, - - user_avatar: input.user_avatar, - error_message: "Avatar is not a valid image url.".to_string(), - }.render().unwrap().into_response(); - - */ - /// ([(HX_RETARGET, "#my_modal_4")], "testT").into_response(); - // return (StatusCode::BAD_REQUEST, "Test").into_response(); - - let line = stringify!(input.user_avatar); - - let start_bytes = line.find(".").unwrap_or(0) + 1; //index where "pattern" starts - // or beginning of line if - // "pattern" not found - let end_bytes = line.find(":").unwrap_or(line.len()); //index where "<" is found - // or end of line - - let result = &line[start_bytes..end_bytes]; - - - // let elem: &str = stringify!(input.user_avatar).split_once(':').unwrap().rsplit_once(".").unwrap(); - - let mut headers = HeaderMap::new(); - // headers.insert(HX_TRIGGER, "close".parse().unwrap()); - headers.insert(HX_RETARGET, format!(r#"input[name="{}"]"#, result).to_string().parse().unwrap()); - headers.insert(HX_RESWAP, "afterend".to_string().parse().unwrap()); - // headers.insert(StatusCode::CREATED) - - - return - (headers, r#" - Bottom Left label"#.to_string()) - .into_response(); - } - - - query!( + match input.validate() { + Ok(_) => { + query!( r#"UPDATE users SET name = $1, avatar = $2 WHERE id=$3;"#, input.user_name, input.user_avatar, &user_id ) - .execute(&db_pool) - .await.unwrap(); - - let mut headers = HeaderMap::new(); - // headers.insert(HX_TRIGGER, "close".parse().unwrap()); - headers.insert(HX_REDIRECT, "/user/settings".to_string().parse().unwrap()); - // headers.insert(StatusCode::CREATED) - - - [ - (HX_REDIRECT, "/user/settings".to_string()), - ].into_response() + .execute(&db_pool) + .await.unwrap(); + + + Ok([ + (HX_REDIRECT, "/user/settings".to_string()), + ].into_response()) + } + Err(e) => { + let mut fruits: HashMap = HashMap::new(); + fruits.insert("user_name".to_string(), "NO".to_string()); + + Ok(ProfileSettingsEditTemplate { + user_name: input.user_name, + + user_avatar: input.user_avatar, + // error_message: "Username has to be at least 5 characters long.".to_string(), + errors: fruits, + }.render().unwrap().into_response()) + } + } } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/tailwind.config.js b/tailwind.config.js index bd9d9fc..d1699d9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -30,7 +30,7 @@ const backfaceVisibility = plugin(function ({addUtilities}) { /** @type {import('tailwindcss').Config} */ module.exports = { - mode: 'jit', + // mode: 'jit', important: true, // mode: 'jit', content: ["./templates/**/*.html"], diff --git a/templates/article/create.html b/templates/article/create.html index a5a183a..7acdb62 100644 --- a/templates/article/create.html +++ b/templates/article/create.html @@ -138,6 +138,11 @@ - diff --git a/templates/meta/about.html b/templates/meta/about.html index 6595259..ec74706 100644 --- a/templates/meta/about.html +++ b/templates/meta/about.html @@ -6,7 +6,7 @@ app logo
-

Support

+

Support

@@ -62,7 +62,7 @@

Describe your bug

Wiki
-

Legal

+

Legal

diff --git a/templates/user/partial/settings_edit.html b/templates/user/partial/settings_edit.html new file mode 100644 index 0000000..0cf94b6 --- /dev/null +++ b/templates/user/partial/settings_edit.html @@ -0,0 +1,26 @@ + + {{errors["user_name"]}} + {% endif %} + + + + + diff --git a/templates/user/settings.html b/templates/user/settings.html index b098478..234c242 100644 --- a/templates/user/settings.html +++ b/templates/user/settings.html @@ -91,26 +91,7 @@

Edit profile

- - - - - + {% include "user/partial/settings_edit.html" %}
diff --git a/templates/user/settings_wrong_input.html b/templates/user/settings_wrong_input.html deleted file mode 100644 index 188d83c..0000000 --- a/templates/user/settings_wrong_input.html +++ /dev/null @@ -1,35 +0,0 @@ - - -
-
- -
-
- - - \ No newline at end of file