feat: add /plants page
parent
18499631ea
commit
dce23599ef
|
@ -1,7 +1,7 @@
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::db::{schema::*, DbPool, DbResult};
|
use crate::db::{schema::*, DbPool, DbResult, Pagination};
|
||||||
|
|
||||||
#[derive(Serialize, Queryable, Selectable)]
|
#[derive(Serialize, Queryable, Selectable)]
|
||||||
#[diesel(table_name = plants)]
|
#[diesel(table_name = plants)]
|
||||||
|
@ -45,4 +45,12 @@ impl Plant {
|
||||||
.first(&mut pool.get()?)
|
.first(&mut pool.get()?)
|
||||||
.optional()?)
|
.optional()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn page(pool: &DbPool, page: Pagination) -> DbResult<Vec<Self>> {
|
||||||
|
Ok(plants::table
|
||||||
|
.select(Self::as_select())
|
||||||
|
.offset((page.page * page.per_page).into())
|
||||||
|
.limit(page.per_page.into())
|
||||||
|
.get_results(&mut pool.get()?)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, Query, State},
|
||||||
http::HeaderMap,
|
http::HeaderMap,
|
||||||
response::Html,
|
response::Html,
|
||||||
routing::{get, post},
|
routing::get,
|
||||||
Form, Router,
|
Form, Router,
|
||||||
};
|
};
|
||||||
use tera::Context;
|
use tera::Context;
|
||||||
|
|
||||||
use crate::db::{self, DbError, Event, Plant};
|
use crate::db::{self, DbError, Event, Pagination, Plant};
|
||||||
|
|
||||||
use super::error::AppError;
|
use super::error::AppError;
|
||||||
|
|
||||||
pub fn app() -> axum::Router<crate::Context> {
|
pub fn app() -> axum::Router<crate::Context> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/{id}", get(get_plant_page))
|
.route("/{id}", get(get_plant_page))
|
||||||
.route("/", post(post_plant))
|
.route("/", get(get_plants).post(post_plant))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_plant_page(
|
async fn get_plant_page(
|
||||||
|
@ -54,6 +54,26 @@ async fn get_plant_page(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_plants(
|
||||||
|
State(ctx): State<crate::Context>,
|
||||||
|
Query(page): Query<Pagination>,
|
||||||
|
headers: HeaderMap,
|
||||||
|
) -> super::Result<Html<String>> {
|
||||||
|
let plants = tokio::task::spawn_blocking(move || db::Plant::page(&ctx.pool, page))
|
||||||
|
.await
|
||||||
|
.unwrap()?;
|
||||||
|
|
||||||
|
let mut context = Context::new();
|
||||||
|
context.insert("plants", &plants);
|
||||||
|
|
||||||
|
Ok(Html(super::render_view(
|
||||||
|
&ctx.tera,
|
||||||
|
"views/plants.html",
|
||||||
|
&context,
|
||||||
|
&headers,
|
||||||
|
)?))
|
||||||
|
}
|
||||||
|
|
||||||
async fn post_plant(
|
async fn post_plant(
|
||||||
State(ctx): State<crate::Context>,
|
State(ctx): State<crate::Context>,
|
||||||
Form(plant): Form<db::NewPlant>,
|
Form(plant): Form<db::NewPlant>,
|
||||||
|
|
|
@ -8,9 +8,13 @@
|
||||||
</div>
|
</div>
|
||||||
{% endmacro info %}
|
{% endmacro info %}
|
||||||
|
|
||||||
|
{% macro name(plant) %}
|
||||||
|
<a hx-get="/plants/{{ plant.id }}" hx-target="#content" hx-push-url="true">{{ plant.name }} (<em>{{ plant.species }}</em>)</a>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro li(plant) %}
|
{% macro li(plant) %}
|
||||||
<li>
|
<li>
|
||||||
<a hx-get="/plants/{{ plant.id }}" hx-target="#content" hx-push-url="true">{{ plant.name }}</a> ({{ plant.species }})
|
{{ self::name(plant=plant) }}
|
||||||
</li>
|
</li>
|
||||||
{% endmacro li %}
|
{% endmacro li %}
|
||||||
|
|
||||||
|
@ -26,16 +30,9 @@
|
||||||
|
|
||||||
{% macro form(target="#plants > ul") %}
|
{% macro form(target="#plants > ul") %}
|
||||||
<form hx-post="/plants" hx-target="{{ target }}" hx-swap="beforeend">
|
<form hx-post="/plants" hx-target="{{ target }}" hx-swap="beforeend">
|
||||||
<label for="name">Name:</label>
|
<input type="text" id="name" name="name" placeholder="My super cool plant"></br>
|
||||||
<input type="text" id="name" name="name"></br>
|
<input type="text" id="species" name="species" placeholder="Philodendron Candens"></br>
|
||||||
<label for="species">Species:</label>
|
<textarea id="description" name="description" rows=2 placeholder="An additional description"></textarea></br>
|
||||||
<input type="text" id="species" name="species"></br>
|
<input type="submit" value="Add plant">
|
||||||
<label for="description">Description:</label>
|
|
||||||
<textarea id="description" name="description" rows=4></textarea></br>
|
|
||||||
<input type="submit">
|
|
||||||
</form>
|
</form>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro name(plant) %}
|
|
||||||
<a hx-get="/plants/{{ plant.id }}" hx-target="#content" hx-push-url="true">{{ plant.name }} (<em>{{ plant.species }}</em>)</a>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
{% import "components/plant.html" as comp_plant %}
|
||||||
|
|
||||||
|
<h1>Plants</h1>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for plant in plants %}
|
||||||
|
{{ comp_plant::li(plant=plant) }}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
Loading…
Reference in New Issue