feat: separate navigation bars for logged and unauthenticated users

SUMMARY
    Authenticated and unauthenticated users have different requirements.
    Links to profile and settings are irrelevant for unauthenticated
    users. So separate navigation bars.

USAGE
    crate::pages::auth_ctx
	Authenticated user context should be supplied on every
	authenticated route template render. Authenticated navigation
	bar depends on "loggedin_user" to render profile link.

    AUTH_NAV("auth_nav")
	Should only be used in authenticated routes. Depends on
	"loggedin_user" authenticated user context, which can't be
	supplied in unauthenticated routes.

NOTES
    Currently, there's (template)code
    duplication, when inheritance for "include" templates are
    implemented in Tera crate, navigation bars implementations should be
    refactored to avoid duplication.
master
Aravinth Manivannan 2022-02-23 12:17:48 +05:30
parent 3d040ede86
commit 28b501810e
Signed by: realaravinth
GPG Key ID: AD9F0F08E855ED88
4 changed files with 62 additions and 5 deletions

View File

@ -57,12 +57,13 @@ pub const PAYLOAD_KEY: &str = "payload";
pub const BASE: TemplateFile = TemplateFile::new("base", "components/base.html");
pub const FOOTER: TemplateFile = TemplateFile::new("footer", "components/footer.html");
pub const PUB_NAV: TemplateFile = TemplateFile::new("pub_nav", "components/pub-nav.html");
pub const PUB_NAV: TemplateFile = TemplateFile::new("pub_nav", "components/nav/pub.html");
pub const AUTH_NAV: TemplateFile = TemplateFile::new("auth_nav", "components/nav/auth.html");
lazy_static! {
pub static ref TEMPLATES: Tera = {
let mut tera = Tera::default();
for t in [BASE, FOOTER, PUB_NAV].iter() {
for t in [BASE, FOOTER, PUB_NAV, AUTH_NAV].iter() {
t.register(&mut tera).unwrap();
}
errors::register_templates(&mut tera);
@ -94,6 +95,16 @@ pub fn context(s: &Settings) -> Context {
ctx
}
pub fn auth_ctx(user: &str, s: &Settings) -> Context {
let mut ctx = Context::new();
let footer = Footer::new(s);
ctx.insert("footer", &footer);
ctx.insert("page", &PAGES);
ctx.insert("assets", &*ASSETS);
ctx.insert("loggedin_user", user);
ctx
}
#[derive(Serialize)]
pub struct Footer<'a> {
version: &'a str,
@ -125,17 +136,19 @@ pub async fn home() -> impl Responder {
#[cfg(test)]
mod tests {
use super::{auth, errors, BASE, FOOTER, PUB_NAV};
use tera::Tera;
#[test]
fn templates_work() {
fn templates_work_basic() {
use super::*;
use tera::Tera;
let mut tera = Tera::default();
let mut tera2 = Tera::default();
for t in [
BASE,
FOOTER,
PUB_NAV,
AUTH_NAV,
auth::AUTH_BASE,
auth::login::LOGIN,
auth::register::REGISTER,

View File

@ -0,0 +1,26 @@
<nav class="nav__container">
<input type="checkbox" class="nav__toggle" id="nav__toggle" />
<div class="nav__header">
<a class="nav__logo-container" href="/">
<p class="nav__home-btn">GitPad</p>
</a>
<label class="nav__hamburger-menu" for="nav__toggle">
<span class="nav__hamburger-inner"></span>
</label>
</div>
<div class="nav__spacer"></div>
<div class="nav__link-group">
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="{{ page.gist.new }}">New Paste</a>
</div>
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="{{ loggedin_user }}">Profile</a>
</div>
<div class="nav__link-container">
<a class="nav__link" rel="noreferrer" href="{{ page.auth.logout }}">Log out</a>
</div>
</div>
</nav>

View File

@ -0,0 +1,18 @@
<nav class="nav__container">
<input type="checkbox" class="nav__toggle" id="nav__toggle" />
<div class="nav__header">
<a class="nav__logo-container" href="/">
<p class="nav__home-btn">GitPad</p>
</a>
<label class="nav__hamburger-menu" for="nav__toggle">
<span class="nav__hamburger-inner"></span>
</label>
</div>
<div class="nav__spacer"></div>
<div class="nav__link-group">
{% block nav_links %} {% endblock %}
</div>
</nav>