Improve layout, fix navbar
This commit is contained in:
parent
749ce35ab9
commit
c9fd7128f3
@ -1,5 +1,5 @@
|
||||
use actix_web::web::{scope, Data, Form, ServiceConfig};
|
||||
use actix_web::{get, post, HttpResponse};
|
||||
use actix_web::{get, post, HttpRequest, HttpResponse};
|
||||
use askama_actix::Template;
|
||||
use oswilno_contract::accounts;
|
||||
use oswilno_contract::parking_space_rents;
|
||||
@ -10,7 +10,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use oswilno_session::{Authenticated, Claims};
|
||||
use oswilno_view::{Layout, LayoutOptions};
|
||||
use oswilno_view::{is_partial, Layout, LayoutOptions, Main};
|
||||
|
||||
pub fn mount(config: &mut ServiceConfig) {
|
||||
config.service(
|
||||
@ -31,15 +31,27 @@ struct AllPartialParkingSpace {
|
||||
|
||||
#[get("/all")]
|
||||
async fn all_parking_spaces(
|
||||
req: HttpRequest,
|
||||
db: Data<sea_orm::DatabaseConnection>,
|
||||
) -> Layout<AllPartialParkingSpace> {
|
||||
) -> HttpResponse {
|
||||
let db = db.into_inner();
|
||||
|
||||
let main = load_parking_spaces(db).await;
|
||||
oswilno_view::Layout {
|
||||
main,
|
||||
opts: LayoutOptions::default(),
|
||||
}
|
||||
let parking_spaces = load_parking_spaces(db).await;
|
||||
|
||||
HttpResponse::Ok().body(
|
||||
if is_partial(&req) {
|
||||
parking_spaces.render()
|
||||
} else {
|
||||
Layout {
|
||||
main: Main {
|
||||
body: parking_spaces,
|
||||
opts: LayoutOptions::default(),
|
||||
},
|
||||
}
|
||||
.render()
|
||||
}
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/all-partial")]
|
||||
|
@ -9,7 +9,7 @@ use askama_actix::Template;
|
||||
use autometrics::autometrics;
|
||||
use garde::Validate;
|
||||
use jsonwebtoken::*;
|
||||
use oswilno_view::{Errors, Lang, Layout, LayoutOptions, TranslationStorage};
|
||||
use oswilno_view::{Errors, Lang, Layout, LayoutOptions, Main, TranslationStorage};
|
||||
use ring::rand::SystemRandom;
|
||||
use ring::signature::{Ed25519KeyPair, KeyPair};
|
||||
use sea_orm::DatabaseConnection;
|
||||
@ -157,22 +157,34 @@ pub struct SignInPayload {
|
||||
async fn login_view(req: HttpRequest, t: Data<TranslationStorage>) -> HttpResponse {
|
||||
HttpResponse::Ok().body(
|
||||
if oswilno_view::is_partial(&req) {
|
||||
SignInPartialTemplate {
|
||||
form: SignInPayload::default(),
|
||||
lang: Lang::Pl,
|
||||
t: t.into_inner(),
|
||||
errors: Errors::default(),
|
||||
}
|
||||
.render()
|
||||
} else {
|
||||
oswilno_view::Layout {
|
||||
main: SignInPartialTemplate {
|
||||
Main {
|
||||
body: SignInPartialTemplate {
|
||||
form: SignInPayload::default(),
|
||||
lang: Lang::Pl,
|
||||
t: t.into_inner(),
|
||||
errors: Errors::default(),
|
||||
},
|
||||
opts: LayoutOptions { show: true, ..Default::default() },
|
||||
opts: LayoutOptions {
|
||||
show: true,
|
||||
search: None,
|
||||
session: None,
|
||||
},
|
||||
}
|
||||
.render()
|
||||
} else {
|
||||
Layout {
|
||||
main: Main {
|
||||
body: SignInPartialTemplate {
|
||||
form: SignInPayload::default(),
|
||||
lang: Lang::Pl,
|
||||
t: t.into_inner(),
|
||||
errors: Errors::default(),
|
||||
},
|
||||
opts: LayoutOptions {
|
||||
show: true,
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
.render()
|
||||
}
|
||||
@ -313,22 +325,31 @@ struct AccountInfo {
|
||||
async fn register_view(req: HttpRequest, t: Data<TranslationStorage>) -> HttpResponse {
|
||||
HttpResponse::Ok().body(
|
||||
if oswilno_view::is_partial(&req) {
|
||||
RegisterPartialTemplate {
|
||||
form: AccountInfo::default(),
|
||||
t: t.into_inner(),
|
||||
lang: Lang::Pl,
|
||||
errors: oswilno_view::Errors::default(),
|
||||
}
|
||||
.render()
|
||||
} else {
|
||||
Layout {
|
||||
main: RegisterPartialTemplate {
|
||||
Main {
|
||||
body: RegisterPartialTemplate {
|
||||
form: AccountInfo::default(),
|
||||
t: t.into_inner(),
|
||||
lang: Lang::Pl,
|
||||
errors: oswilno_view::Errors::default(),
|
||||
},
|
||||
opts: LayoutOptions::default(),
|
||||
opts: LayoutOptions {
|
||||
show: true,
|
||||
search: None,
|
||||
session: None,
|
||||
},
|
||||
}
|
||||
.render()
|
||||
} else {
|
||||
Layout {
|
||||
main: Main {
|
||||
body: RegisterPartialTemplate {
|
||||
form: AccountInfo::default(),
|
||||
t: t.into_inner(),
|
||||
lang: Lang::Pl,
|
||||
errors: oswilno_view::Errors::default(),
|
||||
},
|
||||
opts: LayoutOptions::default(),
|
||||
},
|
||||
}
|
||||
.render()
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<a href="/login" hx-get="/login" hx-replace-url="true" hx-target="#main-view" hx-headers='{"Accept":"text/html-partial"}'>{{"Sign in"|t(lang,t)}}</a>
|
||||
<a href="/login" hx-get="/login" hx-replace-url="true" hx-target="main" hx-headers='{"Accept":"text/html-partial"}'>{{"Sign in"|t(lang,t)}}</a>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<a href="/register" hx-get="/register" hx-replace-url="true" hx-target="#main-view" hx-headers='{"Accept":"text/html-partial"}'>{{"Register"|t(lang,t)}}</a>
|
||||
<a href="/register" hx-get="/register" hx-replace-url="true" hx-target="main" hx-headers='{"Accept":"text/html-partial"}'>{{"Register"|t(lang,t)}}</a>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -33,11 +33,17 @@ pub struct LayoutOptions {
|
||||
pub session: Option<SessionOpts>,
|
||||
}
|
||||
|
||||
#[derive(Debug, askama_actix::Template)]
|
||||
#[template(path = "../templates/main.html")]
|
||||
pub struct Main<BodyTemplate: askama::Template> {
|
||||
pub body: BodyTemplate,
|
||||
pub opts: LayoutOptions,
|
||||
}
|
||||
|
||||
#[derive(Debug, askama_actix::Template)]
|
||||
#[template(path = "../templates/base.html")]
|
||||
pub struct Layout<BodyTemplate: askama::Template> {
|
||||
pub main: BodyTemplate,
|
||||
pub opts: LayoutOptions,
|
||||
pub main: Main<BodyTemplate>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
@ -11,9 +11,6 @@
|
||||
</head>
|
||||
<body>
|
||||
<base url="/" />
|
||||
{% include "navbar.html" %}
|
||||
<main>
|
||||
{{ main|safe }}
|
||||
</main>
|
||||
{{ main|safe }}
|
||||
</body>
|
||||
</html>
|
||||
|
4
crates/oswilno-view/templates/main.html
Normal file
4
crates/oswilno-view/templates/main.html
Normal file
@ -0,0 +1,4 @@
|
||||
<main>
|
||||
{% include "navbar.html" %}
|
||||
{{ body|safe }}
|
||||
</main>
|
14
crates/oswilno-view/templates/nav/account-options.html
Normal file
14
crates/oswilno-view/templates/nav/account-options.html
Normal file
@ -0,0 +1,14 @@
|
||||
<ul class="py-2" aria-labelledby="user-menu-button">
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Dashboard</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Settings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Earnings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Sign out</a>
|
||||
</li>
|
||||
</ul>
|
19
crates/oswilno-view/templates/nav/links-large.html
Normal file
19
crates/oswilno-view/templates/nav/links-large.html
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="navbar-user">
|
||||
<ul class="flex flex-col font-medium p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500" aria-current="page">Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">About</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Services</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Pricing</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
19
crates/oswilno-view/templates/nav/search.html
Normal file
19
crates/oswilno-view/templates/nav/search.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% match opts.search %}
|
||||
{% when Some with (search) %}
|
||||
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="main-search">
|
||||
<div class="relative mt-3 xs:hidden">
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<input
|
||||
type="search"
|
||||
id="search-navbar"
|
||||
class="block w-full min-w-[35rem] p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Search..."
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{% when None %}
|
||||
{% endmatch %}
|
44
crates/oswilno-view/templates/nav/session-menu.html
Normal file
44
crates/oswilno-view/templates/nav/session-menu.html
Normal file
@ -0,0 +1,44 @@
|
||||
{% match opts.session %}
|
||||
{% when Some with (session) %}
|
||||
<div class="flex items-center md:order-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex mr-3 text-sm bg-gray-800 rounded-full md:mr-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
|
||||
id="user-menu-button"
|
||||
aria-expanded="false"
|
||||
data-dropdown-toggle="user-dropdown"
|
||||
data-dropdown-placement="bottom"
|
||||
>
|
||||
<span class="sr-only">Open user menu</span>
|
||||
{% match session.profile_image_url %}
|
||||
{% when Some with (url) %}
|
||||
<img class="w-8 h-8 rounded-full" src="{{ url }}" alt="user photo">
|
||||
{% when None %}
|
||||
<span>{{ session.login }}</span>
|
||||
{% endmatch %}
|
||||
</button>
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600" id="user-dropdown">
|
||||
<div class="px-4 py-3">
|
||||
<span class="block text-sm text-gray-900 dark:text-white">session.login</span>
|
||||
<span class="block text-sm text-gray-500 truncate dark:text-gray-400">session.login</span>
|
||||
</div>
|
||||
{% include "nav/account-options.html" %}
|
||||
</div>
|
||||
|
||||
<button
|
||||
data-collapse-toggle="navbar-user"
|
||||
type="button"
|
||||
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
|
||||
aria-controls="navbar-user"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<span class="sr-only">Open main menu</span>
|
||||
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{% when None %}
|
||||
{% endmatch %}
|
@ -5,102 +5,10 @@
|
||||
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">Flowbite</span>
|
||||
</a>
|
||||
|
||||
<div class="flex items-center md:order-2">
|
||||
{% include "nav/session-menu.html" %}
|
||||
{% include "nav/search.html" %}
|
||||
{% include "nav/links-large.html" %}
|
||||
|
||||
{% match opts.session %}
|
||||
{% when Some with (session) %}
|
||||
<button type="button" class="flex mr-3 text-sm bg-gray-800 rounded-full md:mr-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600" id="user-menu-button" aria-expanded="false" data-dropdown-toggle="user-dropdown" data-dropdown-placement="bottom">
|
||||
<span class="sr-only">Open user menu</span>
|
||||
{% match session.profile_image_url %}
|
||||
{% when Some with (url) %}
|
||||
<img class="w-8 h-8 rounded-full" src="{{ url }}" alt="user photo">
|
||||
{% when None %}
|
||||
<span>{{ session.login }}</span>
|
||||
{% endmatch %}
|
||||
</button>
|
||||
{% when None %}
|
||||
{% endmatch %}
|
||||
|
||||
{% match opts.session %}
|
||||
{% when Some with (session) %}
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600" id="user-dropdown">
|
||||
<div class="px-4 py-3">
|
||||
<span class="block text-sm text-gray-900 dark:text-white">session.login</span>
|
||||
<span class="block text-sm text-gray-500 truncate dark:text-gray-400">session.login</span>
|
||||
</div>
|
||||
|
||||
<ul class="py-2" aria-labelledby="user-menu-button">
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Dashboard</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Settings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Earnings</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Sign out</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button
|
||||
data-collapse-toggle="navbar-user"
|
||||
type="button"
|
||||
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
|
||||
aria-controls="navbar-user" aria-expanded="false"
|
||||
>
|
||||
<span class="sr-only">Open main menu</span>
|
||||
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"/>
|
||||
</svg>
|
||||
</button>
|
||||
{% when None %}
|
||||
{% endmatch %}
|
||||
</div>
|
||||
|
||||
{% match opts.search %}
|
||||
{% when Some with (search) %}
|
||||
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="main-search">
|
||||
<div class="relative mt-3 xs:hidden">
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<input
|
||||
type="search"
|
||||
id="search-navbar"
|
||||
class="block w-full min-w-[35rem] p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Search..."
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{% when None %}
|
||||
{% endmatch %}
|
||||
|
||||
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="navbar-user">
|
||||
<ul class="flex flex-col font-medium p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500" aria-current="page">Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">About</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Services</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Pricing</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user