Navbar copy of the other frontend

This commit is contained in:
Franklin 2023-03-15 09:20:17 -04:00
commit f764bd08c0
26 changed files with 2427 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
/dist
.env

1829
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

29
Cargo.toml Normal file
View File

@ -0,0 +1,29 @@
[package]
name = "jl-frontend"
version = "0.1.0"
edition = "2021"
authors = [
"Franklin Blanco <me@franklinblanco.dev>"
]
license = "MIT OR Apache-2.0"
[dependencies]
# yew and core stuff
yew = { version = "0.20.0", features = ["csr"] }
yew-router = "0.17"
stylist = "0.12.0"
# Wasm/js stuff
wasm-logger = "0.2"
wasm-bindgen = "0.2.84"
wasm-bindgen-futures = "0.4.34"
js-sys = "0.3"
# other libs
reqwest = { version = "0.11.11", features = ["rustls-tls", "json", "blocking"], default-features = false }
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics", "serde", "js"] }
log = "0.4"
serde_json = "1.0.88"
# Core
jl-types = { path = "../jl-types" }

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
css/.DS_Store vendored Normal file

Binary file not shown.

12
css/body.css Normal file
View File

@ -0,0 +1,12 @@
body {
margin: 0; /* Remove body margins */
}
.page-container {
padding-top: 75.5px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: stretch;
}

0
css/landing.css Normal file
View File

160
css/navbar.css Normal file
View File

@ -0,0 +1,160 @@
/* Mobile View */
.navbar-background {
position: fixed;
width: 100%;
display: flex;
flex-direction: row;
justify-content: end;
align-items: center;
align-items: stretch;
background-color: #252631;
min-height: 74px;
}
.navbar-container {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
flex-grow: 1;
padding: 15px;
}
.navbar-hamburger {
font-size: 20pt;
color: white;
display: flex;
justify-content: center;
align-items: center;
margin-top: 5px;
max-height: 35px;
min-width: 30px;
padding: 15px;
}
.navbar-hamburger:hover {
background-color: #ffffff14;
font-size: 22pt;
font-weight: bold;
border-radius: 3px;
transition-duration: 0.3s;
cursor: pointer;
}
.navbar-closed{
display: flex;
flex-direction: column;
justify-content: flex-start;
margin-top: 10px;
display: none;
}
.navbar-open {
display: flex;
flex-direction: column;
justify-content: flex-start;
margin-top: 10px;
}
.navbar-item {
color: white;
font-size: 12pt;
padding-top: 10px;
padding-left: 5px;
padding-bottom: 10px;
font-family: Source Sans Pro;
}
.navbar-item:hover {
background-color: #ffffff14;
font-size: 13pt;
font-weight: bold;
border-radius: 3px;
transition-duration: 0.3s;
cursor: pointer;
}
.navbar-brand-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
max-width: 250px;
}
.navbar-brand-container:hover {
cursor: pointer;
}
.navbar-title {
color: white;
font-size: 23pt;
font-family: Sacramento;
}
.navbar-image {
max-width: 50px;
max-height: 50px;
}
/* Desktop view */
@media only screen and (min-width: 850px) {
.navbar-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
}
.navbar {
display: flex;
flex-direction: row;
justify-content: flex-end;
flex-grow: 1;
}
.navbar-closed {
display: flex;
flex-direction: row;
justify-content: flex-end;
flex-grow: 1;
margin-top: 0px;
}
.navbar-open {
display: flex;
flex-direction: row;
justify-content: flex-end;
flex-grow: 1;
margin-top: 0px;
}
.navbar-item {
color: white;
font-size: 12pt;
padding-left: 20px;
padding-right: 20px;
padding-top: 10px;
padding-bottom: 10px;
font-family: Source Sans Pro;
}
.navbar-item:hover {
background-color: #ffffff14;
font-size: 13pt;
font-weight: bold;
border-radius: 3px;
transition-duration: 0.3s;
cursor: pointer;
}
.navbar-title {
color: white;
font-size: 23pt;
font-family: Sacramento;
}
.navbar-hamburger {
display: none;
}
}

96
css/search.css Normal file
View File

@ -0,0 +1,96 @@
.property-search-container {
display: flex;
flex-direction: column;
justify-content: stretch;
align-items: center;
padding: 10px 50px;
flex-grow: 1;
}
.property-search-bar-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
min-width: 300px;
max-width: 600px;
width: 100%;
padding: 0px 20px;
min-height: 50px;
border: 0.5px solid rgba(0, 0, 0, 0.08);
border-radius: 30px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 10px;
background-color: white;
flex-grow: 1;
margin-bottom: 15px;
color: #252631;
}
.property-search-bar {
border: 0px;
padding: 10px;
outline: none;
font-family: Source Sans Pro;
font-size: 15px;
flex-grow: 1;
}
.search-bar-erase-button {
display: none;
}
.search-bar-erase-button:hover {
cursor: pointer;
}
.search-bar-filter-button {
display: flex;
justify-content: center;
align-items: center;
border-radius: 25px;
border: 1px solid rgba(0, 0, 0, 0.14);
padding: 4px;
width: 20px;
height: 20px;
font-size: 14px;
}
.search-bar-filter-button:hover {
cursor: pointer;
}
.property-search-filters-container {
display: flex;
flex-direction: row;
justify-content: space-evenly;
flex-wrap: wrap;
align-items: center;
width: 100%;
}
.property-search-filter-item {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
min-width: 75px;
color: black;
padding: 5px 10px;
border: 1px solid rgba(0, 0, 0, 0.5);
border-radius: 5px;
font-family: Open Sans;
font-weight: bold;
font-size: 15px;
}
.property-search-results-container {
color: purple;
}
.property-search-result-card {
color: orange
}

18
index.html Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JL</title>
<link data-trunk type="text/css" href="css/body.css" rel="css" />
<link data-trunk type="text/css" href="css/navbar.css" rel="css" />
<link data-trunk type="text/css" href="css/landing.css" rel="css" />
<link data-trunk type="text/css" href="css/search.css" rel="css" />
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Sacramento" rel="stylesheet">
<script src="https://kit.fontawesome.com/fcdfdfe1ad.js" crossorigin="anonymous"></script>
<base data-trunk-public-url />
<link data-trunk rel="copy-dir" href="assets/images/"/>
</head>
</html>

0
src/api/backend/mod.rs Normal file
View File

0
src/api/base.rs Normal file
View File

2
src/api/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod base;
pub mod backend;

2
src/components/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod nav_bar;
pub mod search_filter;

57
src/components/nav_bar.rs Normal file
View File

@ -0,0 +1,57 @@
use yew::prelude::*;
use yew_router::prelude::use_navigator;
use crate::{routes::main_router::{Route}, constants::{NAVBAR_TITLE, NAVBAR_COL_LANDING, NAVBAR_COL_PROYECTOS_ACABADOS, NAVBAR_COL_CONTACTO, NAVBAR_COL_PROYECTOS_EN_CONSTRUCCION}, pages::search::PropertyState};
//use yew_router::prelude::use_navigator;
#[function_component(NavigationBar)]
pub fn navigation_bar() -> Html {
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 navbar_toggle = use_state(|| true);
let on_click_hamburger = {
let navbar_toggle = navbar_toggle.clone();
Callback::from(move |_| navbar_toggle.set(!*navbar_toggle))
};
html! {
<div class={"navbar-background"}>
<div class={"navbar-container"}>
<div class={"navbar-brand-container"} onclick={move |_| cloned_navigator_5.push(&Route::LandingPage)}>
<img class={"navbar-image"} src="images/remax-logo.png" alt=""/>
<div class={"navbar-title"}>
{NAVBAR_TITLE}
</div>
</div>
<div class={if *navbar_toggle {"navbar-closed"} else {"navbar-open"}}>
<div onclick={move |_| cloned_navigator_1.push(&Route::LandingPage)} class={"navbar-item"}>
{NAVBAR_COL_LANDING}
</div>
<div onclick={move |_| cloned_navigator_2.push(&Route::Search { property_state: PropertyState::Finished })} class={"navbar-item"}>
{NAVBAR_COL_PROYECTOS_ACABADOS}
</div>
<div onclick={move |_| cloned_navigator_3.push(&Route::Search { property_state: PropertyState::InConstruction })} class={"navbar-item"}>
{NAVBAR_COL_PROYECTOS_EN_CONSTRUCCION}
</div>
<div onclick={move |_| cloned_navigator_4.push(&Route::Contact)} class={"navbar-item"}>
{NAVBAR_COL_CONTACTO}
</div>
</div>
</div>
<div class={"navbar-hamburger"} onclick={on_click_hamburger}>
<i class="fa-solid fa-bars" ></i>
</div>
</div>
}
}

View File

5
src/constants/mod.rs Normal file
View File

@ -0,0 +1,5 @@
pub const NAVBAR_TITLE: &str = "Jorge Ledesma";
pub const NAVBAR_COL_LANDING: &str = "Inicio";
pub const NAVBAR_COL_PROYECTOS_ACABADOS: &str = "Listos para entrega";
pub const NAVBAR_COL_PROYECTOS_EN_CONSTRUCCION: &str = "En construcción";
pub const NAVBAR_COL_CONTACTO: &str = "Contacto";

22
src/main.rs Normal file
View File

@ -0,0 +1,22 @@
pub mod api;
pub mod components;
pub mod routes;
pub mod pages;
pub mod constants;
use yew::prelude::*;
use yew_router::{BrowserRouter, Switch};
use crate::routes::main_router::{Route, switch};
#[function_component]
fn App() -> Html {
html! {
<BrowserRouter>
<Switch<Route> render={switch} /> // <- must be child of <BrowserRouter>
</BrowserRouter>
}
}
fn main() {
yew::Renderer::<App>::new().render();
}

16
src/pages/contact.rs Normal file
View File

@ -0,0 +1,16 @@
use yew::prelude::*;
use crate::components::nav_bar::NavigationBar;
#[function_component(ContactPage)]
pub fn contact_page() -> Html {
html!{
<>
<NavigationBar/>
<div class={"page-container"}>
{"Contact Page"}
</div>
</>
}
}

8
src/pages/details.rs Normal file
View File

@ -0,0 +1,8 @@
use yew::prelude::*;
#[function_component(DetailsPage)]
pub fn details_page() -> Html {
html!{
<div class={"page-container"}>{"Details Page"}</div>
}
}

16
src/pages/landing.rs Normal file
View File

@ -0,0 +1,16 @@
use yew::prelude::*;
use crate::components::nav_bar::NavigationBar;
#[function_component(LandingPage)]
pub fn landing_page() -> Html {
html!{
<>
<NavigationBar/>
<div class={"page-container"}>
{"Landing Page"}
</div>
</>
}
}

5
src/pages/mod.rs Normal file
View File

@ -0,0 +1,5 @@
pub mod landing;
pub mod search;
pub mod details;
pub mod not_found;
pub mod contact;

15
src/pages/not_found.rs Normal file
View File

@ -0,0 +1,15 @@
use yew::prelude::*;
use crate::components::nav_bar::NavigationBar;
#[function_component(NotFoundPage)]
pub fn not_found_page() -> Html {
html! {
<>
<NavigationBar/>
<div class={"page-container"}>
{"Not found page"}
</div>
</>
}
}

99
src/pages/search.rs Normal file
View File

@ -0,0 +1,99 @@
use std::{fmt::Display, str::FromStr};
use yew::prelude::*;
use crate::components::nav_bar::NavigationBar;
#[function_component(SearchPage)]
pub fn search_page(_props: &SearchPageProperties) -> Html {
let search_text = use_state(|| String::new());
let clear_search_input = {
let search_text = search_text.clone();
Callback::from(move |_| {
search_text.set(String::new())
})
};
html!{
<>
<NavigationBar/>
<div class={"page-container"}>
<div class={"property-search-container"}>
<div class={"property-search-bar-container"}> // Search bar
<i class={"fa-solid fa-magnifying-glass"}></i>
<input type={"text"} value={(*search_text).clone()} class={"property-search-bar"} placeholder={"Buscar propiedades..."}/>
<div class={"search-bar-erase-button"}>
<i class="fa-solid fa-circle-xmark" onclick={clear_search_input}></i>
</div>
<div class={"search-bar-filter-button"}>
<i class="fa-solid fa-sliders"></i>
</div>
</div>
<div class={"property-search-filters-container"}> // Filters
<div class={"property-search-filter-item"}>
<div>{"0"}</div>
<i class="fa-solid fa-bed"></i>
<div>{"+"}</div>
</div>
<div class={"property-search-filter-item"}>
<div>{"0"}</div>
<i class="fa-solid fa-ruler"></i>
<div>{"+"}</div>
</div>
<div class={"property-search-filter-item"}>
<div>{"0"}</div>
<i class="fa-solid fa-dollar-sign"></i>
<div>{"+"}</div>
</div>
<div class={"property-search-filter-item"}>
<div>{"0"}</div>
<i class="fa-solid fa-hand-holding-dollar"></i>
<div>{"+"}</div>
</div>
</div>
</div>
//TODO: Add a spacing
<div class={"property-search-results-container"}> // Search Results Content
<div class={"property-search-result-card"}></div>
</div>
</div>
</>
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Properties)]
pub struct SearchPageProperties {
pub property_state: PropertyState
}
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
pub enum PropertyState {
Finished,
#[default]
InConstruction,
}
impl Display for PropertyState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PropertyState::Finished => write!(f, "Finished"),
PropertyState::InConstruction => write!(f, "InConstruction"),
}
}
}
impl FromStr for PropertyState {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Finished" => Ok(Self::Finished),
"InConstruction" => Ok(Self::InConstruction),
_ => Err(())
}
}
}

32
src/routes/main_router.rs Normal file
View File

@ -0,0 +1,32 @@
use yew_router::prelude::*;
use yew::prelude::*;
use uuid::Uuid;
use crate::{pages::{landing::LandingPage, search::{SearchPage, PropertyState}, details::DetailsPage, not_found::NotFoundPage, contact::ContactPage}};
#[derive(Clone, Routable, PartialEq)]
pub enum Route {
#[at("/")]
LandingPage,
#[at("/search/:property_state")]
Search { property_state: PropertyState },
#[at("/details/:property_id")]
Details { property_id: Uuid },
#[at("/contact")]
Contact,
#[not_found]
#[at("/404")]
NotFound,
}
pub fn switch(routes: Route) -> Html {
match routes {
Route::LandingPage => html! { <LandingPage/> },
Route::Search { property_state } => html! { <SearchPage property_state={property_state}/> },
Route::Details { property_id: _ } => html! { <DetailsPage/> },
Route::NotFound => html! { <NotFoundPage/> },
Route::Contact => html! { <ContactPage/> }
}
}

1
src/routes/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod main_router;