feat: add /plants page
							parent
							
								
									18499631ea
								
							
						
					
					
						commit
						dce23599ef
					
				|  | @ -1,7 +1,7 @@ | |||
| use diesel::prelude::*; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| use crate::db::{schema::*, DbPool, DbResult}; | ||||
| use crate::db::{schema::*, DbPool, DbResult, Pagination}; | ||||
| 
 | ||||
| #[derive(Serialize, Queryable, Selectable)] | ||||
| #[diesel(table_name = plants)] | ||||
|  | @ -45,4 +45,12 @@ impl Plant { | |||
|             .first(&mut pool.get()?) | ||||
|             .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::{ | ||||
|     extract::{Path, State}, | ||||
|     extract::{Path, Query, State}, | ||||
|     http::HeaderMap, | ||||
|     response::Html, | ||||
|     routing::{get, post}, | ||||
|     routing::get, | ||||
|     Form, Router, | ||||
| }; | ||||
| use tera::Context; | ||||
| 
 | ||||
| use crate::db::{self, DbError, Event, Plant}; | ||||
| use crate::db::{self, DbError, Event, Pagination, Plant}; | ||||
| 
 | ||||
| use super::error::AppError; | ||||
| 
 | ||||
| pub fn app() -> axum::Router<crate::Context> { | ||||
|     Router::new() | ||||
|         .route("/{id}", get(get_plant_page)) | ||||
|         .route("/", post(post_plant)) | ||||
|         .route("/", get(get_plants).post(post_plant)) | ||||
| } | ||||
| 
 | ||||
| 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( | ||||
|     State(ctx): State<crate::Context>, | ||||
|     Form(plant): Form<db::NewPlant>, | ||||
|  |  | |||
|  | @ -8,9 +8,13 @@ | |||
| </div> | ||||
| {% 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) %} | ||||
| <li> | ||||
|     <a hx-get="/plants/{{ plant.id }}" hx-target="#content" hx-push-url="true">{{ plant.name }}</a> ({{ plant.species }}) | ||||
|     {{ self::name(plant=plant) }}  | ||||
| </li> | ||||
| {% endmacro li %} | ||||
| 
 | ||||
|  | @ -26,16 +30,9 @@ | |||
| 
 | ||||
| {% macro form(target="#plants > ul") %} | ||||
| <form hx-post="/plants" hx-target="{{ target }}" hx-swap="beforeend"> | ||||
|     <label for="name">Name:</label> | ||||
|     <input type="text" id="name" name="name"></br> | ||||
|     <label for="species">Species:</label> | ||||
|     <input type="text" id="species" name="species"></br> | ||||
|     <label for="description">Description:</label> | ||||
|     <textarea id="description" name="description" rows=4></textarea></br> | ||||
|     <input type="submit"> | ||||
|     <input type="text" id="name" name="name" placeholder="My super cool plant"></br> | ||||
|     <input type="text" id="species" name="species" placeholder="Philodendron Candens"></br> | ||||
|     <textarea id="description" name="description" rows=2 placeholder="An additional description"></textarea></br> | ||||
|     <input type="submit" value="Add plant"> | ||||
| </form> | ||||
| {% 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