diff --git a/Cargo.lock b/Cargo.lock index 5c01561..e7905ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,6 +137,61 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "askama" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +dependencies = [ + "askama_derive", + "askama_escape", + "humansize", + "num-traits", + "percent-encoding", +] + +[[package]] +name = "askama_axum" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41603f7cdbf5ac4af60760f17253eb6adf6ec5b6f14a7ed830cf687d375f163" +dependencies = [ + "askama", + "axum-core", + "http", +] + +[[package]] +name = "askama_derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +dependencies = [ + "askama_parser", + "basic-toml", + "mime", + "mime_guess", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_parser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +dependencies = [ + "nom", +] + [[package]] name = "async-attributes" version = "1.1.2" @@ -452,6 +507,15 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "basic-toml" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" +dependencies = [ + "serde", +] + [[package]] name = "bigdecimal" version = "0.3.1" @@ -1254,6 +1318,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + [[package]] name = "humantime" version = "2.1.0" @@ -1365,6 +1438,8 @@ name = "inventory-api" version = "0.1.0" dependencies = [ "anyhow", + "askama", + "askama_axum", "async-std", "axum", "chrono", @@ -1538,6 +1613,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -3135,6 +3220,15 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.14" diff --git a/README.md b/README.md index 2c7703b..b3d2fad 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,19 @@ ### Home Inventory API -Built with Axum and SeaORM +App to manage your inventories + +#### Tech Stack + +**Backend** +- Rust 🦀 +- Axum +- SeaORM + +**Frontend** +- HTMX + + + + ## Development @@ -11,7 +25,6 @@ Built with Axum and SeaORM - ``cargo run`` - ## How to's **Create new table** diff --git a/api/Cargo.toml b/api/Cargo.toml index 4b3d05a..723a1be 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -8,6 +8,8 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +askama = { version = "0.12.1", features = ["with-axum"] } +askama_axum = "0.4.0" axum = { version = "0.7.4", features = ["macros"] } async-std = { version = "1.12.0", features = ["attributes", "tokio1"] } anyhow = "1.0.79" diff --git a/api/src/handlers/base.rs b/api/src/handlers/base.rs new file mode 100644 index 0000000..5ab82d0 --- /dev/null +++ b/api/src/handlers/base.rs @@ -0,0 +1,51 @@ +use askama::Template; +use axum::{extract::State, response::IntoResponse, Form}; +use sea_orm::Set; +use std::sync::Arc; +use uuid::Uuid; + +use crate::AppState; +use entity::house::ActiveModel as HouseActiveModel; +use entity::house::Entity as HouseEntity; +use entity::house::Model as HouseModel; +use sea_orm::{ActiveModelTrait, EntityTrait}; + +pub async fn root_path() -> impl IntoResponse { + HelloTemplate +} + +pub async fn get_houses_web(State(database): State>) -> impl IntoResponse { + let list_houses = HouseEntity::find().all(&database.db).await.unwrap(); + + Records { houses: list_houses } +} + +pub async fn create_house_web( + State(database): State>, + Form(form): Form, +) -> impl IntoResponse { + let new_house = HouseActiveModel { + id: Set(Uuid::new_v4().to_string()), + title: Set(form.title), + body: Set(form.body), + ..Default::default() + }; + let insert_response = new_house.insert(&database.db).await.unwrap(); + HouseNewTemplate { house: insert_response }; +} + +#[derive(Template)] +#[template(path = "index.html")] +struct HelloTemplate; + +#[derive(Template)] +#[template(path = "houses.html")] +struct Records { + houses: Vec, +} + +#[derive(Template)] +#[template(path = "house.html")] +struct HouseNewTemplate { + house: HouseModel, +} diff --git a/api/src/handlers/mod.rs b/api/src/handlers/mod.rs index 97fc67c..fa1bffc 100644 --- a/api/src/handlers/mod.rs +++ b/api/src/handlers/mod.rs @@ -1,2 +1,3 @@ +pub mod base; pub mod house; pub mod room; diff --git a/api/src/routes/mod.rs b/api/src/routes/mod.rs index 99845d5..34d556b 100644 --- a/api/src/routes/mod.rs +++ b/api/src/routes/mod.rs @@ -6,6 +6,10 @@ use axum::{ }; use crate::AppState; +use crate::handlers::base::{ + root_path, + get_houses_web +}; use crate::handlers::house::{ all_houses, create_house, @@ -21,13 +25,16 @@ use crate::handlers::room::{ pub fn create_routes(app_state: Arc) -> Router { Router::new() - .route("/houses", get(all_houses)) - .route("/houses", post(create_house)) - .route("/houses/:id", get(find_house)) - .route("/houses/:id", patch(update_house)) - .route("/houses/:id", delete(delete_house)) - // Rooms - .route("/rooms/:house_id", get(list_rooms)) - .route("/rooms", post(create_rooms)) + .route("/", get(root_path)) + .route("/houses", get(get_houses_web)) + // .route("/houses", post(create_house_web)) // Todo + // API Endpoints + .route("/api/houses", get(all_houses)) + .route("/api/houses", post(create_house)) + .route("/api/houses/:id", get(find_house)) + .route("/api/houses/:id", patch(update_house)) + .route("/api/houses/:id", delete(delete_house)) + .route("/api/rooms/:house_id", get(list_rooms)) + .route("/api/rooms", post(create_rooms)) .with_state(app_state) } diff --git a/api/templates/base.html b/api/templates/base.html new file mode 100644 index 0000000..1eb0b88 --- /dev/null +++ b/api/templates/base.html @@ -0,0 +1,14 @@ + + + + + + {% block title %}{{ title }} - My Site{% endblock %} + {% block head %}{% endblock %} + + +
+ {% block content %}

Placeholder content

{% endblock %} +
+ + diff --git a/api/templates/house.html b/api/templates/house.html new file mode 100644 index 0000000..d86a86a --- /dev/null +++ b/api/templates/house.html @@ -0,0 +1,8 @@ + + {{ house.id }} + {{ house.title }} + {{ house.body }} + + + + diff --git a/api/templates/houses.html b/api/templates/houses.html new file mode 100644 index 0000000..8a86533 --- /dev/null +++ b/api/templates/houses.html @@ -0,0 +1,17 @@ +
+ + + + + + + + + + + {% for house in houses %} + {% include "house.html" %} + {% endfor %} + +
IDTitleBodyDelete
+
diff --git a/api/templates/index.html b/api/templates/index.html new file mode 100644 index 0000000..f044830 --- /dev/null +++ b/api/templates/index.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% block title %}Index{% endblock %} + +{% block content %} +

Inventory App

+
+ + + +
+
+ Loading... +
+{% endblock %} diff --git a/api/templates/styles.css b/api/templates/styles.css new file mode 100644 index 0000000..aeed300 --- /dev/null +++ b/api/templates/styles.css @@ -0,0 +1,11 @@ +#content { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; +} + +table, th, td { + border: 1px solid black; + padding: 0.25rem; +}