MOre web bs

This commit is contained in:
Gvidas Juknevičius 2026-01-15 22:08:40 +02:00
parent 1ecbdde2c0
commit 7d9d95fcd2
37 changed files with 684 additions and 31 deletions

View File

@ -0,0 +1,55 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::db::models::Client;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "clients/index.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
pub clients: Vec<Client>
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
use diesel::prelude::*;
use crate::db::schema::clients::dsl::*;
let results = clients
.order(id.asc())
.limit(50)
.load::<Client>(&mut pool.get()?)?;
let mut template = PageTemplate {
ctx: Default::default(),
clients: results
};
template.set_title("Clients");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,55 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::db::models::Client;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "clients/index.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
pub clients: Vec<Client>
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
use diesel::prelude::*;
use crate::db::schema::clients::dsl::*;
let results = clients
.order(id.asc())
.limit(50)
.load::<Client>(&mut pool.get()?)?;
let mut template = PageTemplate {
ctx: Default::default(),
clients: results
};
template.set_title("Clients");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -7,6 +7,11 @@ use crate::db::DbPool;
use crate::db::models::Client; use crate::db::models::Client;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx}; use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
pub mod add;
pub mod edit;
pub mod view;
pub mod remove;
#[derive(Template)] #[derive(Template)]
#[template(path = "clients/index.html")] #[template(path = "clients/index.html")]
pub struct PageTemplate { pub struct PageTemplate {
@ -32,7 +37,7 @@ pub async fn get_page(State(pool): State<DbPool>) -> Response {
let results = clients let results = clients
.order(id.asc()) .order(id.asc())
.limit(50) .limit(100)
.load::<Client>(&mut pool.get()?)?; .load::<Client>(&mut pool.get()?)?;
let mut template = PageTemplate { let mut template = PageTemplate {

View File

@ -0,0 +1,55 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::db::models::Client;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "clients/index.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
pub clients: Vec<Client>
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
use diesel::prelude::*;
use crate::db::schema::clients::dsl::*;
let results = clients
.order(id.asc())
.limit(50)
.load::<Client>(&mut pool.get()?)?;
let mut template = PageTemplate {
ctx: Default::default(),
clients: results
};
template.set_title("Clients");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,55 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::db::models::Client;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "clients/index.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
pub clients: Vec<Client>
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
use diesel::prelude::*;
use crate::db::schema::clients::dsl::*;
let results = clients
.order(id.asc())
.limit(50)
.load::<Client>(&mut pool.get()?)?;
let mut template = PageTemplate {
ctx: Default::default(),
clients: results
};
template.set_title("Clients");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -1,5 +1,5 @@
pub mod services;
pub mod clients; pub mod clients;
pub mod inventory; pub mod inventory;
pub mod tickets; pub mod tickets;

View File

@ -0,0 +1,44 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "services/add.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Assigning a service");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,44 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "services/catalog/add.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Adding a service to the catalog");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,44 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "services/catalog/edit.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Editing a service in the catalog");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,48 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
pub mod add;
pub mod edit;
pub mod view;
#[derive(Template)]
#[template(path = "services/catalog/index.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Clients");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,44 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "services/catalog/view.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Service from the catalog");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,49 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
pub mod catalog;
pub mod view;
pub mod add;
pub mod remove;
#[derive(Template)]
#[template(path = "services/index.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Services");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,44 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "services/remove.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Removing a service");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -0,0 +1,44 @@
use askama::Template;
use axum::extract::State;
use axum::response::{Html, IntoResponse, Response};
use axum::http::StatusCode;
use crate::db::DbPool;
use crate::web::pages::{BaseTemplate, BaseTemplateCtx};
#[derive(Template)]
#[template(path = "services/view.html")]
pub struct PageTemplate {
pub ctx: BaseTemplateCtx,
}
impl BaseTemplate for PageTemplate {
fn ctx(&self) -> &BaseTemplateCtx {
&self.ctx
}
fn ctx_mut(&mut self) -> &mut BaseTemplateCtx {
&mut self.ctx
}
}
#[axum::debug_handler]
pub async fn get_page(State(pool): State<DbPool>) -> Response {
async fn inner(_pool: &DbPool) -> anyhow::Result<(StatusCode, String)> {
let mut template = PageTemplate {
ctx: Default::default(),
};
template.set_title("Service");
Ok((StatusCode::OK, template.render()?))
}
match inner(&pool).await {
Ok((status, s)) => (status, Html(s)).into_response(),
Err(e) => {
let s = crate::web::pages::error::get_error_page(e.to_string()).await;
(StatusCode::INTERNAL_SERVER_ERROR, Html(s)).into_response()
}
}
}

View File

@ -5,14 +5,19 @@ body,html {
} }
.nav { .nav {
position: fixed;
display: flex; display: flex;
top: 0;
list-style: none; list-style: none;
gap: 10px; gap: 10px;
background: gray; background: gray;
padding: 8px; padding: 8px;
margin: 0px; margin: 0px;
width: 99.5%;
}
main {
padding-top: 50px
} }
.right { .right {
margin-left: auto; margin-left: auto;
} }
@ -40,8 +45,8 @@ body,html {
} }
footer { footer {
position: absolute; position: sticky;
bottom: 0px; bottom: 0;
width: 100%; width: 100%;
padding: 5px; padding: 5px;
padding-left: 10px; padding-left: 10px;

View File

@ -0,0 +1,41 @@
.table {
margin: 0 auto;
width: 80%;
font-size: 0.95rem;
border-radius: 8px;
overflow: hidden;
border-collapse: collapse;
border: 5px double black;
}
.table-header {
border: 5px double black;
}
.table-header-item {
padding-top: 1px;
padding-bottom: 1px;
padding-left: 5px;
padding-right: 1px;
border: 1px solid black;
border-left: 0.5px thin gray;
border-right: 0.5px thin gray;
}
.table-body {
border: 5px double black;
}
.table-cell {
padding-top: 1px;
padding-bottom: 1px;
padding-left: 5px;
padding-right: 1px;
border: 1px solid black;
border-left: 0.5px thin gray;
border-right: 0.5px thin gray;
}

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>{{ self.title() }}</title> <title>{{ self.title() }}</title>
<link rel="stylesheet" href="/static/base.css"> <link rel="stylesheet" href="/static/css/base.css">
{% block headers %}{% endblock %} {% block headers %}{% endblock %}
</head> </head>
<body> <body>

View File

View File

View File

@ -1,31 +1,38 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block headers %} {% block headers %}
<link rel="stylesheet" href="/static/css/clients/index.css">
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<table> <table class="table">
<tr> <thead class="table-header">
<td>First Name</td> <tr class="table-row">
<td>Last Name</td> <td class="table-header-item">First Name</td>
<td>Address</td> <td class="table-header-item">Last Name</td>
<td>Number</td> <td class="table-header-item">Address</td>
<td>Email</td> <td class="table-header-item">Number</td>
</tr> <td class="table-header-item">Email</td>
{% for client in clients %} </tr>
<tr> </thead>
<td>{{ client.first_name }}</td> <tbody class="table-body">
<td>{{ client.last_name }}</td> {% for client in clients %}
<td> <tr class="table-row">
{{ client.country}} <td class="table-cell">{{ client.first_name }}</td>
{{ client.city}} <td class="table-cell">{{ client.last_name }}</td>
{{ client.state}} <td class="table-cell">
{{ client.address_line}} {{ client.country}}
{{ client.house_number}} {{ client.city}}
{{ client.postal_code}} {{ client.state}}
</td> {{ client.address_line}}
<td>{{ client.phone_number }}</td> {{ client.house_number}}
<td>{{ client.email }}</td> {{ client.postal_code}}
</tr> </td>
{% endfor %} <td class="table-cell">{{ client.phone_number }}</td>
<td class="table-cell">{{ client.email }}</td>
</tr>
{% endfor %}
</tbody>
</table> </table>
{% endblock %} {% endblock %}

View File

View File

View File

View File

View File

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block headers %} {% block headers %}
<link rel="stylesheet" href="/static/login.css"> <link rel="stylesheet" href="/static/css/login.css">
{% endblock %} {% endblock %}
{% block content %} {% block content %}

View File

View File

View File

View File

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block headers %}
{% endblock %}
{% block content %}
Hewwo wowld!!!!
{% endblock %}

View File

View File

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block headers %}
{% endblock %}
{% block content %}
Hewwo wowld!!!!
{% endblock %}

View File

View File

View File