diff --git a/src/base/component/poweredby.rs b/src/base/component/poweredby.rs index afa8db7..5a37464 100644 --- a/src/base/component/poweredby.rs +++ b/src/base/component/poweredby.rs @@ -1,13 +1,10 @@ use crate::prelude::*; -// Enlace a la página oficial de PageTop. -const LINK: &str = "PageTop"; - -/// Componente que renderiza la sección 'Powered by' (*Funciona con*) típica del pie de página. +/// Muestra un texto con información de copyright, típica en un pie de página. /// -/// Por defecto, usando [`default()`](Self::default) sólo se muestra un reconocimiento a PageTop. -/// Sin embargo, se puede usar [`new()`](Self::new) para crear una instancia con un texto de -/// copyright predeterminado. +/// Por defecto, usando [`default()`](Self::default) sólo se muestra un +/// reconocimiento a PageTop. Sin embargo, se puede usar [`new()`](Self::new) +/// para crear una instancia con un texto de copyright predeterminado. #[derive(AutoDefault)] pub struct PoweredBy { copyright: Option, @@ -16,8 +13,8 @@ pub struct PoweredBy { impl Component for PoweredBy { /// Crea una nueva instancia de `PoweredBy`. /// - /// El copyright se genera automáticamente con el año actual y el nombre de la aplicación - /// configurada en [`global::SETTINGS`]. + /// El copyright se genera automáticamente con el año actual y el nombre de + /// la aplicación configurada en [`global::SETTINGS`]. fn new() -> Self { let year = Utc::now().format("%Y").to_string(); let c = join!(year, " © ", global::SETTINGS.app.name); @@ -25,14 +22,19 @@ impl Component for PoweredBy { } fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { + let poweredby_pagetop = L10n::l("poweredby_pagetop") + .with_arg( + "pagetop_link", + "PageTop", + ) + .to_markup(cx); + PrepareMarkup::With(html! { div id=[self.id()] class="poweredby" { @if let Some(c) = self.copyright() { span class="poweredby__copyright" { (c) "." } " " } - span class="poweredby__pagetop" { - (L10n::l("poweredby_pagetop").with_arg("pagetop_link", LINK).to_markup(cx)) - } + span class="poweredby__pagetop" { (poweredby_pagetop) } } }) } diff --git a/src/base/extension/welcome.rs b/src/base/extension/welcome.rs index f768210..5f413d3 100644 --- a/src/base/extension/welcome.rs +++ b/src/base/extension/welcome.rs @@ -29,19 +29,19 @@ async fn homepage(request: HttpRequest) -> ResultPage { .with_theme("Basic") .with_assets(AssetsOp::AddStyleSheet(StyleSheet::from("/css/welcome.css"))) .with_body_classes(ClassesOp::Add, "welcome") - .with_component_in("header", Html::with(move |cx| html! { - div class="welcome-header" { - header class="welcome-header__body" { + .with_component(Html::with(move |cx| html! { + div id="main-header" { + header { h1 - class="welcome-header__title" + id="header-title" aria-label=(L10n::l("welcome_aria").with_arg("app", app).to_markup(cx)) { span { (L10n::l("welcome_title").to_markup(cx)) } (L10n::l("welcome_intro").with_arg("app", app).to_markup(cx)) } } - aside class="welcome-header__image" aria-hidden="true" { - div class="welcome-header__monster" { + aside id="header-image" aria-hidden="true" { + div id="monster" { picture { source type="image/avif" @@ -61,27 +61,25 @@ async fn homepage(request: HttpRequest) -> ResultPage { } })) .with_component(Html::with(move |cx| html! { - main class="welcome-content" { - section class="welcome-content__body" { - div class="welcome-poweredby" { + main id="main-content" { + section class="content-body" { + div id="poweredby-button" { a - class="welcome-poweredby__link" + id="poweredby-link" href="https://pagetop.cillero.es" target="_blank" rel="noreferrer" { span {} span {} span {} - div class="welcome-poweredby__text" { - (L10n::l("welcome_powered").to_markup(cx)) - } + div id="poweredby-text" { (L10n::l("welcome_powered").to_markup(cx)) } } } - div class="welcome-text" { + div class="content-text" { p { (L10n::l("welcome_text1").to_markup(cx)) } p { (L10n::l("welcome_text2").to_markup(cx)) } - div class="welcome-text__block" { - h2 { span { (L10n::l("welcome_about").to_markup(cx)) } } + div class="subcontent" { + h1 { span { (L10n::l("welcome_about").to_markup(cx)) } } p { (L10n::l("welcome_pagetop").to_markup(cx)) } p { (L10n::l("welcome_issues1").to_markup(cx)) } p { (L10n::l("welcome_issues2").with_arg("app", app).to_markup(cx)) } diff --git a/static/css/welcome.css b/static/css/welcome.css index 4ce8046..906c05d 100644 --- a/static/css/welcome.css +++ b/static/css/welcome.css @@ -58,17 +58,12 @@ a:hover:visited { align-items: center; } -/* - * Region header - */ - -.welcome-header { +#main-header { display: flex; flex-direction: column-reverse; - width: 100%; - max-width: 80rem; - margin: 0 auto; padding-bottom: 9rem; + max-width: 80rem; + width: 100%; background-image: var(--bg-img-sm); background-image: var(--bg-img-sm-set); background-position: top center; @@ -76,11 +71,11 @@ a:hover:visited { background-size: contain; background-repeat: no-repeat; } -.welcome-header__body { +#main-header header { padding: 0; background: none; } -.welcome-header__title { +#header-title { margin: 0 0 0 1.5rem; text-align: left; display: flex; @@ -94,7 +89,7 @@ a:hover:visited { line-height: 110%; text-shadow: 0 0.125rem 0.1875rem rgba(0, 0, 0, 0.3); } -.welcome-header__title > span { +#header-title > span { background: linear-gradient(180deg, #ddff95 30%, #ffb84b 100%); background-clip: text; -webkit-background-clip: text; @@ -105,44 +100,40 @@ a:hover:visited { line-height: 110%; text-shadow: none; } -.welcome-header__image { +#header-image { + width: 100%; + text-align: right; display: flex; justify-content: flex-start; - text-align: right; - width: 100%; } -.welcome-header__monster { +#header-image #monster { margin-right: 12rem; margin-top: 1rem; flex-shrink: 1; } @media (min-width: 64rem) { - .welcome-header { + #main-header { background-image: var(--bg-img); background-image: var(--bg-img-set); } - .welcome-header__title { + #header-title { padding: 1.2rem 2rem 2.6rem 2rem; } - .welcome-header__image { + #header-image { justify-content: flex-end; } } -/* - * Region content - */ - -.welcome-content { +#main-content { height: auto; margin-top: 1.6rem; } -.welcome-content__body { +.content-body { box-sizing: border-box; max-width: 80rem; } -.welcome-content__body:before, -.welcome-content__body:after { +.content-body:before, +.content-body:after { content: ''; position: absolute; left: 0; @@ -152,38 +143,38 @@ a:hover:visited { filter: blur(2.75rem); opacity: 0.8; inset: 11.75rem; - /*z-index: 0;*/ + z-index: 0; } -.welcome-content__body:before { +.content-body:before { top: -1rem; } -.welcome-content__body:after { +.content-body:after { bottom: -1rem; } @media (max-width: 48rem) { - .welcome-content__body { + .content-body { margin-top: -9.8rem; } - .welcome-content__body:before, - .welcome-content__body:after { + .content-body:before, + .content-body:after { inset: unset; } } @media (min-width: 64rem) { - .welcome-content { + #main-content { margin-top: 0; } - .welcome-content__body { + .content-body { margin-top: -5.7rem; } } -.welcome-poweredby { +#poweredby-button { width: 100%; margin: 0 auto 3rem; z-index: 10; } -.welcome-poweredby__link { +#poweredby-link { background: #7f1d1d; background-image: linear-gradient(to bottom, rgba(255,0,0,0.8), rgba(255,255,255,0)); background-position: top left, center; @@ -196,7 +187,7 @@ a:hover:visited { font-size: 1.5rem; line-height: 1.3; text-decoration: none; - /*text-shadow: var(--shadow);*/ + text-shadow: var(--shadow); transition: transform 0.3s ease-in-out; position: relative; overflow: hidden; @@ -204,7 +195,7 @@ a:hover:visited { min-height: 7.6875rem; outline: none; } -.welcome-poweredby__link::before { +#poweredby-link::before { content: ''; position: absolute; top: -13.125rem; @@ -216,7 +207,7 @@ a:hover:visited { transition: transform 0.3s ease-in-out; z-index: 5; } -.welcome-poweredby__text { +#poweredby-text { display: flex; flex-direction: column; flex: 1; @@ -226,25 +217,25 @@ a:hover:visited { padding: 1rem 1.5rem; text-align: left; color: white; - /*text-shadow: 0 0.101125rem 0.2021875rem rgba(0, 0, 0, 0.25);*/ + text-shadow: 0 0.101125rem 0.2021875rem rgba(0, 0, 0, 0.25); font-size: 1.65rem; font-style: normal; font-weight: 600; line-height: 130.023%; letter-spacing: 0.0075rem; } -.welcome-poweredby__text strong { +#poweredby-text strong { font-size: 2.625rem; font-weight: 600; line-height: 130.023%; letter-spacing: 0.013125rem; } -.welcome-poweredby__link span { +#poweredby-link span { position: absolute; display: block; pointer-events: none; } -.welcome-poweredby__link span:nth-child(1) { +#poweredby-link span:nth-child(1) { height: 8px; width: 100%; top: 0; @@ -264,7 +255,7 @@ a:hover:visited { transform: translateX(100%); } } -.welcome-poweredby__link span:nth-child(2) { +#poweredby-link span:nth-child(2) { width: 8px; height: 100%; top: 0; @@ -284,7 +275,7 @@ a:hover:visited { transform: translateY(100%); } } -.welcome-poweredby__link span:nth-child(3) { +#poweredby-link span:nth-child(3) { height: 8px; width: 100%; bottom: 0; @@ -304,22 +295,22 @@ a:hover:visited { transform: translateX(-100%); } } -.welcome-poweredby__link:hover span { +#poweredby-link:hover span { animation-play-state: paused; } @media (max-width: 48rem) { - .welcome-poweredby__link { + #poweredby-link { height: 6.25rem; min-width: auto; border-radius: 0; } - .welcome-poweredby__text { + #poweredby-text { display: inline; padding-top: .5rem; } } @media (min-width: 48rem) { - .welcome-poweredby { + #poweredby-button { position: absolute; top: 0; left: 50%; @@ -327,14 +318,14 @@ a:hover:visited { max-width: 29.375rem; margin-bottom: 0; } - .welcome-poweredby__link:hover { + #poweredby-link:hover { transition: all .5s; transform: rotate(-3deg) scale(1.1); - /*box-shadow: 0px 3px 5px rgba(0,0,0,.4);*/ + box-shadow: 0px 3px 5px rgba(0,0,0,.4); } } -.welcome-text { +.content-text { z-index: 1; width: 100%; display: flex; @@ -352,7 +343,7 @@ a:hover:visited { padding: 6rem 1.063rem 0.75rem; overflow: hidden; } -.welcome-text p { +.content-text p { width: 100%; line-height: 150%; font-weight: 400; @@ -360,14 +351,14 @@ a:hover:visited { margin: 0 0 1.5rem; } @media (min-width: 48rem) { - .welcome-text { + .content-text { font-size: 1.375rem; line-height: 2rem; padding-top: 7rem; } } @media (min-width: 64rem) { - .welcome-text { + .content-text { border-radius: 0.75rem; box-shadow: var(--shadow); max-width: 60rem; @@ -377,13 +368,13 @@ a:hover:visited { } } -.welcome-text__block { +.subcontent { position: relative; } -.welcome-text__block h2 { +.subcontent h1 { margin: 1em 0 .8em; } -.welcome-text__block h2 span { +.subcontent h1 span { display: inline-block; padding: 10px 30px 14px; margin: 0 0 0 20px; @@ -394,7 +385,7 @@ a:hover:visited { border-color: orangered; transform: rotate(-3deg) translateY(-25%); } -.welcome-text__block h2:before { +.subcontent h1:before { content: ""; height: 5px; position: absolute; @@ -407,7 +398,7 @@ a:hover:visited { transform: rotate(2deg) translateY(-50%); transform-origin: top left; } -.welcome-text__block h2:after { +.subcontent h1:after { content: ""; height: 70rem; position: absolute; diff --git a/tests/component_html.rs b/tests/component_html.rs index b9b8e5e..978248f 100644 --- a/tests/component_html.rs +++ b/tests/component_html.rs @@ -35,7 +35,7 @@ async fn component_html_renders_using_context_param() { async fn component_html_allows_replacing_render_function() { let mut component = Html::with(|_| html! { div { "Original" } }); - component.alter_fn(|_| html! { div { "Modified" } }); + component.alter_html(|_| html! { div { "Modified" } }); let markup = component .prepare_component(&mut Context::new(None))