Skip to content

Commit

Permalink
Implemented HTMX (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
JijoBose authored Jan 21, 2024
1 parent 0aaa232 commit ed045e5
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 10 deletions.
94 changes: 94 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

<img src="https://foundation.rust-lang.org/img/rust-logo-blk.svg" height="100px" />
<img src="https://raw.githubusercontent.com/bigskysoftware/htmx/master/www/static/img/htmx_logo.1.png" height="100px"/>


## Development

Expand All @@ -11,7 +25,6 @@ Built with Axum and SeaORM
- ``cargo run``



## How to's

**Create new table**
Expand Down
2 changes: 2 additions & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
51 changes: 51 additions & 0 deletions api/src/handlers/base.rs
Original file line number Diff line number Diff line change
@@ -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<Arc<AppState>>) -> 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<Arc<AppState>>,
Form(form): Form<HouseModel>,
) -> 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<HouseModel>,
}

#[derive(Template)]
#[template(path = "house.html")]
struct HouseNewTemplate {
house: HouseModel,
}
1 change: 1 addition & 0 deletions api/src/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod base;
pub mod house;
pub mod room;
23 changes: 15 additions & 8 deletions api/src/routes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -21,13 +25,16 @@ use crate::handlers::room::{
pub fn create_routes(app_state: Arc<AppState>) -> 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)
}
14 changes: 14 additions & 0 deletions api/templates/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/[email protected]" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/styles.css"/>
<title>{% block title %}{{ title }} - My Site{% endblock %}</title>
{% block head %}{% endblock %}
</head>
<body>
<div id="content">
{% block content %}<p>Placeholder content</p>{% endblock %}
</div>
</body>
</html>
8 changes: 8 additions & 0 deletions api/templates/house.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<tr id="shuttle-house-{{ house.id }}">
<td> {{ house.id }} </td>
<td id="shuttle-house-desc-{{house.id}}"> {{ house.title }} </td>
<td id="shuttel-house-body={{house.id}}"> {{ house.body }}</td>
<td>
<button hx-delete="/houses/{{house.id}}" hx-trigger="click" hx-target="#shuttle-todo-{{house.id}}" hx-swap="delete">Delete</button>
</td>
</tr>
17 changes: 17 additions & 0 deletions api/templates/houses.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div id="houses">
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th>Delete</th>
</tr>
</thead>
<tbody id="houses-content">
{% for house in houses %}
{% include "house.html" %}
{% endfor %}
</tbody>
</table>
</div>
15 changes: 15 additions & 0 deletions api/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block content %}
<h1>Inventory App</h1>
<form id="add-form">
<input placeholder="Your House name" required type=text name="title">
<input placeholder="Description" required type=text name="body">
<button hx-post="/houses" hx-trigger="click" hx-target="#houses-content" hx-swap="beforeend">Add</button>
</form>
<div id="list" hx-get="/houses" hx-target="this" hx-trigger="load" hx-swap="outerHTML">
Loading...
</div>
{% endblock %}
11 changes: 11 additions & 0 deletions api/templates/styles.css
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit ed045e5

Please sign in to comment.