Finished website design, and navbar smooth scrolling

This commit is contained in:
Franklin 2023-04-29 22:08:12 -04:00
parent 3d86536a9c
commit 5c4088a5b2
14 changed files with 223 additions and 126 deletions

View File

@ -1,5 +1,6 @@
.about-us-container {
scroll-margin-top: 75px;
margin-top: clamp(50px, 20vw, 150px);
display: flex;

View File

@ -1,16 +1,22 @@
* {
scroll-behavior: smooth;
}
body {
margin: 0; /* Remove body margins */
background-color: rgb(250, 248, 248);
}
a {
text-decoration: none;
}
.page-container {
scroll-behavior: smooth;
display: flex;
flex-direction: column;
justify-content: center;
align-items: stretch;
padding-left: clamp(35px, 10%, 10vw);
padding-right: clamp(35px, 5%, 10vw);
padding-top: clamp(85px, 10vw, 160px)
padding-top: clamp(85px, 10vw, 160px);
}
@media only screen and (min-width: 1000px) {
.page-container {
@ -20,7 +26,7 @@ body {
align-items: stretch;
padding-left: clamp(35px, 25%, 10vw);
padding-right: clamp(35px, 25%, 10vw);
padding-top: clamp(85px, 10vw, 160px)
padding-top: clamp(85px, 10vw, 160px);
}
}
/*

View File

@ -1,13 +1,13 @@
.contact-container {
margin-top: 30px;
scroll-margin-top: 100px;
margin-top: clamp(50px, 20vw, 150px);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
margin-left: calc(-1 * clamp(35px, 10%, 10vw));
margin-right: calc(-1 * clamp(35px, 10%, 10vw));
margin-left: calc(-1 * clamp(35px, 15%, 10vw));
background-color: #4C40F7;
@ -16,7 +16,7 @@
}
.contact-title {
font-family: Poppins;
font-size: 14px;
font-size: 16px;
font-weight: 400;
text-align: center;
@ -28,7 +28,7 @@
font-family: Poppins;
font-size: 28px;
font-weight: 600;
font-weight: 800;
text-align: center;
letter-spacing: 1px;
@ -44,11 +44,19 @@
align-items: center;
gap: 20px;
width: 500px;
width: 70vw;
}
.contact-form-button {
.contact-form-button-container {
margin-top: 25px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
width: 70vw;
}
.contact-form-button {
display: flex;
justify-content: center;
align-items: center;
@ -56,12 +64,16 @@
color: white;
font-size: 14px;
font-family: Poppins;
font-weight: 600;
text-align: end;
letter-spacing: 1px;
width: 150px;
height: 50px;
border-radius: 4px;
}
.contact-form-button {
.contact-form-button:hover {
cursor: pointer;
user-select: none;
}
@ -70,4 +82,10 @@
margin-left: calc(-1 * clamp(35px, 25%, 10vw));
margin-right: calc(-1 * clamp(35px, 25%, 10vw))
}
.contact-textfield-container {
width: 700px;
}
.contact-form-button-container {
width: 700px;
}
}

View File

@ -24,7 +24,7 @@
font-size: 14px;
line-height: 32px;
color: #ABAFC7;
color: #323232;
}
.textarea {
-moz-box-sizing: border-box;
@ -44,7 +44,7 @@
font-size: 13px;
line-height: 20px;
color: #ABAFC7;
color: #323232;
}
::placeholder {

View File

@ -12,6 +12,7 @@
width: clamp(300px, 50vw, 350px);
height: 420px;
}
.service-card-container:nth-child(1) .service-card-icon {
background-color: #4ADB61;
filter: drop-shadow(0px 15px 30px #4ADB61);
@ -69,31 +70,27 @@
display: flex;
justify-content: center;
align-items: center;
}
}
.service-card-container:hover {
.service-card-container-clicked {
transform: rotateY(-180deg);
transition: transform 150ms ease;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
padding: 10px;
background-color: #4C40F7;
transition-duration: 0.5s;
cursor: pointer;
border-radius: 20px;
box-shadow: -10px 30px 70px rgba(219, 222, 225, 0.4);
width: clamp(300px, 50vw, 350px);
height: 420px;
}
.service-card-container:hover .service-card-icon {
background-color: white;
filter: none;
box-shadow: none;
color: #4C40F7;
transition-duration: 1s;
}
.service-card-container:hover .service-card-title {
color: white;
transition-duration: 1s;
}
.service-card-container:hover .service-card-description {
color: white;
transition-duration: 1s;
}
.service-card-container:hover .service-card-button {
transition-duration: 1s;
background-color: #F3F4F6;
.service-card-container-clicked > * {
transform: rotateY(-180deg);
}
@ -133,5 +130,33 @@
width: clamp(270px, 24vw, 380px);
height: clamp(360px, 33vw, 450px);
}
.service-card-container-clicked {
width: clamp(270px, 24vw, 380px);
height: clamp(360px, 33vw, 450px);
}
.service-card-container:hover {
background-color: #4C40F7;
transition-duration: 0.5s;
cursor: pointer;
}
.service-card-container:hover .service-card-icon {
background-color: white;
filter: none;
box-shadow: none;
color: #4C40F7;
transition-duration: 1s;
}
.service-card-container:hover .service-card-title {
color: white;
transition-duration: 1s;
}
.service-card-container:hover .service-card-description {
color: white;
transition-duration: 1s;
}
.service-card-container:hover .service-card-button {
transition-duration: 1s;
background-color: #F3F4F6;
}
}

View File

@ -1,4 +1,6 @@
.services-section-container {
scroll-margin-top: 100px;
display: flex;
flex-direction: column;
justify-content: center;

View File

@ -10,18 +10,28 @@ services-section:
first:
title: Web Development
description: We develop amazing websites to be more professional, functional, and help you sell more.
opened-title: A
opened-description: B
second:
title: SEO
description: We optimize website content and structure to improve search engine rankings.
opened-title: A
opened-description: B
third:
title: Backend Logic
description: We efficientize your business critical operations and speed up your services & processes.
opened-title: A
opened-description: B
fourth:
title: Social Media Management
description: We plan and execute effective social media strategies to increase visibility and engagement.
opened-title: A
opened-description: B
fifth:
title: Digital Marketing
description: We also help you market your products through an online marketplace.
opened-title: A
opened-description: B
start:
left-column:
title-first-line: Make your business
@ -60,6 +70,6 @@ contact:
title: Contact Us
subtitle: Leave us a message
form-name-label: Name
form-email-label: Email
form-email-label: Phone number or Email
form-message-label: Start typing...
form-button-label: Send

View File

@ -1,7 +1,6 @@
use rust_i18n::t;
use stdweb::web::{event::ResizeEvent, IEventTarget};
use yew::prelude::*;
use yew_router::prelude::{use_navigator, use_route};
use crate::routes::main_router::Route;
@ -15,14 +14,7 @@ pub struct NavigationBarProps {
#[function_component(NavigationBar)]
pub fn navigation_bar(props: &NavigationBarProps) -> Html {
let language = &props.language;
let current_route: Option<Route> = use_route();
let navigator = use_navigator().unwrap();
let cloned_navigator_1 = navigator.clone();
let cloned_navigator_2 = navigator.clone();
let cloned_navigator_3 = navigator.clone();
let cloned_navigator_4 = navigator.clone();
let cloned_navigator_5 = navigator.clone();
let cloned_navigator_6 = navigator.clone();
let current_route = use_state_eq(|| Route::Start);
let navbar_toggle = use_state(|| true);
let on_click_hamburger = {
@ -46,38 +38,62 @@ pub fn navigation_bar(props: &NavigationBarProps) -> Html {
}
});
html! {
<div class={"navbar-background"}>
<div class={"navbar-container"}>
<div class={"navbar-brand-container"} onclick={move |_| cloned_navigator_6.push(&Route::MainPage)}>
<a href={"#"} class={"navbar-brand-container"} onclick={
let current_route = current_route.clone();
Callback::from(move |_| current_route.set(Route::Start))}>
<img class={"navbar-image"} src={ if (*window_device_handle) == WindowDevice::Mobile {"images/blanco-lorenzo-logo-white-transparent.png"} else {"images/blanco-lorenzo-logo-gray-transparent.png"}} alt=""/>
</div>
</a>
<div class={if *navbar_toggle {"navbar-closed"} else {"navbar-open"}}>
<div onclick={move |_| cloned_navigator_1.push(&Route::MainPage)} class={
if current_route.is_some() && matches!(current_route.clone().unwrap(), Route::MainPage) {"navbar-item-selected"} else {"navbar-item"}
}>
{t!("navbar.item.home", locale = language.locale())}
</div>
<a href={"#"} onclick={
let navbar_toggle = navbar_toggle.clone();
let current_route = current_route.clone();
Callback::from(move |_| {
current_route.set(Route::Start);
navbar_toggle.set(true);
})} class={
if matches!((*current_route).clone(), Route::Start) {"navbar-item-selected"} else {"navbar-item"}}>
{t!("navbar.item.home", locale = language.locale())}
</a>
<div onclick={move |_| cloned_navigator_2.push(&Route::Services)} class={
if current_route.is_some() && matches!(current_route.clone().unwrap(), Route::Services) {"navbar-item-selected"} else {"navbar-item"}
}>
<a href={"#services-page"} onclick={
let navbar_toggle = navbar_toggle.clone();
let current_route = current_route.clone();
Callback::from(move |_| {
current_route.set(Route::Services);
navbar_toggle.set(true);
})} class={
if matches!((*current_route).clone(), Route::Services) {"navbar-item-selected"} else {"navbar-item"}}>
{t!("navbar.item.services", locale = language.locale())}
</div>
</a>
<div onclick={move |_| cloned_navigator_3.push(&Route::About)} class={
if current_route.is_some() && matches!(current_route.unwrap(), Route::About) {"navbar-item-selected"} else {"navbar-item"}
}>
<a href={"#about-page"} onclick={
let navbar_toggle = navbar_toggle.clone();
let current_route = current_route.clone();
Callback::from(move |_| {
current_route.set(Route::About);
navbar_toggle.set(true);
})} class={
if matches!((*current_route).clone(), Route::About) {"navbar-item-selected"} else {"navbar-item"}}>
{t!("navbar.item.about-us", locale = language.locale())}
</div>
</a>
{
if (*window_device_handle) == WindowDevice::Mobile {
html! {
<div onclick={move |_| cloned_navigator_4.push(&Route::Contact)} class={"navbar-item"}>
<a class={"navbar-item"} onclick={
let navbar_toggle = navbar_toggle.clone();
let current_route = current_route.clone();
Callback::from(move |_| {
current_route.set(Route::Contact);
navbar_toggle.set(true);
})} href={"#call-to-action-page"}>
{t!("navbar.item.contact-us", locale = language.locale())}
</div>
</a>
}
} else { html! {} }
}
@ -109,9 +125,15 @@ pub fn navigation_bar(props: &NavigationBarProps) -> Html {
}
} else {
html! {
<div onclick={move |_| cloned_navigator_5.push(&Route::Contact)} class={"navbar-item-contact-us"}>
<a class={"navbar-item-contact-us"} href={"#call-to-action-page"} onclick={
let navbar_toggle = navbar_toggle.clone();
let current_route = current_route.clone();
Callback::from(move |_| {
current_route.set(Route::Contact);
navbar_toggle.set(true);
})}>
{t!("navbar.item.contact-us", locale = language.locale())}
</div>
</a>
}
}
}
@ -120,7 +142,7 @@ pub fn navigation_bar(props: &NavigationBarProps) -> Html {
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
enum WindowDevice {
Desktop,
Mobile,

View File

@ -2,55 +2,66 @@ use yew::prelude::*;
#[derive(PartialEq, Properties)]
pub struct ServiceCardProps {
#[prop_or_default]
pub selected: bool,
pub hexcolor: String,
pub iconclass: String,
pub title: String,
pub description: String,
pub opened_title: String,
pub opened_description: String,
}
#[function_component(ServiceCard)]
pub fn service_card(props: &ServiceCardProps) -> Html {
if props.selected {
html! {
<div class={"service-card-container-selected"}>
<div class={"service-card-icon-selected"}>
//Icon
<i class={props.iconclass.clone()}></i>
</div>
<div class={"service-card-title-selected"}>
//title
{props.title.clone()}
</div>
<div class={"service-card-description-selected"}>
//description
{props.description.clone()}
</div>
<div class={"service-card-button-selected"}>
<i class="fa-solid fa-arrow-right"></i>
</div>
</div>
}
} else {
html! {
<div class={"service-card-container"}>
<div class={"service-card-icon"}>
//Icon
<i class={props.iconclass.clone()}></i>
</div>
<div class={"service-card-title"}>
//title
{props.title.clone()}
</div>
<div class={"service-card-description"}>
//description
{props.description.clone()}
</div>
<div class={"service-card-button"}>
<i class="fa-solid fa-arrow-right"></i>
</div>
</div>
}
let clicked = use_state_eq(|| false);
let onclick = {
let clicked = clicked.clone();
Callback::from(move |_: MouseEvent| {
clicked.set(!(*clicked).clone());
})
};
html! {
<div class={
if (*clicked).clone() {
"service-card-container-clicked"
} else {
"service-card-container"
}} onclick={onclick}>
{
if (*clicked).clone() {
html! {
<>
<div class={"service-card-title-selected"}>
{props.opened_title.clone()}
</div>
<div class={"service-card-description-selected"}>
{props.opened_description.clone()}
</div>
</>
}
} else {
html! {
<>
<div class={"service-card-icon"}>
//Icon
<i class={props.iconclass.clone()}></i>
</div>
<div class={"service-card-title"}>
//title
{props.title.clone()}
</div>
<div class={"service-card-description"}>
//description
{props.description.clone()}
</div>
<div class={"service-card-button"}>
<i class="fa-solid fa-arrow-right"></i>
</div>
</>
}
}
}
</div>
}
}

View File

@ -11,7 +11,7 @@ pub struct AboutPageProps {
pub fn about_page(props: &AboutPageProps) -> Html {
let language = props.language.clone();
html! {
<div class={"about-us-container"}>
<div class={"about-us-container"} id={"about-page"}>
<div class={"about-us-title"}>
{t!("about-us.title", locale = language.locale())}
</div>

View File

@ -15,7 +15,7 @@ pub fn call_to_action_page(props: &CallToActionPageProps) -> Html {
let email_handle = use_state(|| String::new());
let message_handle = use_state(|| String::new());
html! {
<div class={"contact-container"}>
<div class={"contact-container"} id={"call-to-action-page"}>
<div class={"contact-title"}>
{t!("contact.title", locale = language.locale())}
</div>
@ -27,9 +27,12 @@ pub fn call_to_action_page(props: &CallToActionPageProps) -> Html {
<TextField label={t!("contact.form-email-label", locale = language.locale())} value={email_handle} />
<TextField label={t!("contact.form-message-label", locale = language.locale())} value={message_handle} fieldtype={TextFieldType::TextArea} />
</div>
<div class={"contact-form-button"}>
{t!("contact.form-button-label", locale = language.locale())}
<div class={"contact-form-button-container"}>
<div class={"contact-form-button"}>
{t!("contact.form-button-label", locale = language.locale())}
</div>
</div>
</div>
}
}

View File

@ -31,12 +31,12 @@ pub fn main_page() -> Html {
html! {
<>
<NavigationBar language={(*language).clone()}/>
<LanguagePicker language={language.clone()}/>
<LanguagePicker language={language.clone()} />
<div class={"page-container"}>
<StartPage language={(*language).clone()}/>
<ServicesPage language={(*language).clone()}/>
<AboutPage language={(*language).clone()}/>
<CallToActionPage language={(*language).clone()}/>
<StartPage language={(*language).clone()} />
<ServicesPage language={(*language).clone()} />
<AboutPage language={(*language).clone()} />
<CallToActionPage language={(*language).clone()} />
</div>
<PageFooter language={(*language).clone()}/>
</>

View File

@ -11,15 +11,14 @@ pub struct ServicesPageProps {
pub fn services_page(props: &ServicesPageProps) -> Html {
let language = &props.language;
html! {
<div class={"services-section-container"}>
<div class={"services-section-container"} id={"services-page"}>
<div class={"services-section-title"}>{t!("services-section.title", locale = language.locale())}</div>
<div class={"services-section-services-container"}>
<ServiceCard hexcolor={String::from("#4ADB61")} iconclass={String::from("fa-solid fa-desktop")} title={t!("services-section.cards.first.title", locale = language.locale())} description={t!("services-section.cards.first.description", locale = language.locale())} />
<ServiceCard hexcolor={String::from("#FF2D59")} iconclass={String::from("fa-solid fa-magnifying-glass")} title={t!("services-section.cards.second.title", locale = language.locale())} description={t!("services-section.cards.second.description", locale = language.locale())} />
<ServiceCard hexcolor={String::from("#2776EA")} iconclass={String::from("fa-solid fa-code")} title={t!("services-section.cards.third.title", locale = language.locale())} description={t!("services-section.cards.third.description", locale = language.locale())} />
<ServiceCard hexcolor={String::from("#FFCC00")} iconclass={String::from("fa-solid fa-users")} title={t!("services-section.cards.fourth.title", locale = language.locale())} description={t!("services-section.cards.fourth.description", locale = language.locale())} />
<ServiceCard hexcolor={String::from("#FF6800")} iconclass={String::from("fa-solid fa-chart-simple")} title={t!("services-section.cards.fifth.title", locale = language.locale())} description={t!("services-section.cards.fifth.description", locale = language.locale())} />
//<ServiceCard hexcolor={String::from("#FF6800")} iconclass={String::from("")} title={t!("services-section.cards.sixth.title", locale = language.locale())} description={t!("services-section.cards.sixth.description", locale = language.locale())} />
<ServiceCard hexcolor={String::from("#4ADB61")} iconclass={String::from("fa-solid fa-desktop")} title={t!("services-section.cards.first.title", locale = language.locale())} description={t!("services-section.cards.first.description", locale = language.locale())} opened_title={t!("services-section.cards.first.opened-title")} opened_description={t!("services-section.cards.first.opened-description")} />
<ServiceCard hexcolor={String::from("#FF2D59")} iconclass={String::from("fa-solid fa-magnifying-glass")} title={t!("services-section.cards.second.title", locale = language.locale())} description={t!("services-section.cards.second.description", locale = language.locale())} opened_title={t!("services-section.cards.second.opened-title")} opened_description={t!("services-section.cards.second.opened-description")}/>
<ServiceCard hexcolor={String::from("#2776EA")} iconclass={String::from("fa-solid fa-code")} title={t!("services-section.cards.third.title", locale = language.locale())} description={t!("services-section.cards.third.description", locale = language.locale())} opened_title={t!("services-section.cards.third.opened-title")} opened_description={t!("services-section.cards.third.opened-description")} />
<ServiceCard hexcolor={String::from("#FFCC00")} iconclass={String::from("fa-solid fa-users")} title={t!("services-section.cards.fourth.title", locale = language.locale())} description={t!("services-section.cards.fourth.description", locale = language.locale())} opened_title={t!("services-section.cards.fourth.opened-title")} opened_description={t!("services-section.cards.fourth.opened-description")} />
<ServiceCard hexcolor={String::from("#FF6800")} iconclass={String::from("fa-solid fa-chart-simple")} title={t!("services-section.cards.fifth.title", locale = language.locale())} description={t!("services-section.cards.fifth.description", locale = language.locale())} opened_title={t!("services-section.cards.fifth.opened-title")} opened_description={t!("services-section.cards.fifth.opened-description")} />
</div>
</div>

View File

@ -12,7 +12,7 @@ pub struct StartPageProps {
pub fn start_page(props: &StartPageProps) -> Html {
let language = &props.language;
html! {
<div class={"start-section-container"}>
<div class={"start-section-container"} id={"start-page"}>
<div class={"start-section-left-column"}>
<div class={"start-section-left-column-title-nocolor"}>
{t!("start.left-column.title-first-line", locale = language.locale())}
@ -26,9 +26,9 @@ pub fn start_page(props: &StartPageProps) -> Html {
<div class={"start-section-left-column-description"}>
{t!("start.left-column-description", locale = language.locale())}
</div>
<div class={"start-section-left-column-button"}>
<a href={"#call-to-action-page"} class={"start-section-left-column-button"}>
{t!("start.left-column-button-text", locale = language.locale())}
</div>
</a>
</div>
<div class={"start-section-right-column"}>