what does loco offers
This commit is contained in:
@@ -51,6 +51,8 @@ impl Hooks for App {
|
||||
|
||||
fn routes(_ctx: &AppContext) -> AppRoutes {
|
||||
AppRoutes::with_default_routes() // controller routes below
|
||||
.add_route(controllers::home::routes())
|
||||
.add_route(controllers::court::routes())
|
||||
.add_route(controllers::auth::routes())
|
||||
}
|
||||
async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {
|
||||
@@ -71,4 +73,4 @@ impl Hooks for App {
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
117
ht_booking/src/controllers/court.rs
Normal file
117
ht_booking/src/controllers/court.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
#![allow(clippy::unnecessary_struct_initialization)]
|
||||
#![allow(clippy::unused_async)]
|
||||
use loco_rs::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use axum::response::Redirect;
|
||||
use axum_extra::extract::Form;
|
||||
use sea_orm::{sea_query::Order, QueryOrder};
|
||||
|
||||
use crate::{
|
||||
models::_entities::courts::{ActiveModel, Column, Entity, Model},
|
||||
views,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Params {
|
||||
pub name: Option<String>,
|
||||
pub surface: Option<String>,
|
||||
pub indoor: Option<bool>,
|
||||
}
|
||||
|
||||
impl Params {
|
||||
fn update(&self, item: &mut ActiveModel) {
|
||||
item.name = Set(self.name.clone());
|
||||
item.surface = Set(self.surface.clone());
|
||||
item.indoor = Set(self.indoor);
|
||||
}
|
||||
}
|
||||
|
||||
async fn load_item(ctx: &AppContext, id: i32) -> Result<Model> {
|
||||
let item = Entity::find_by_id(id).one(&ctx.db).await?;
|
||||
item.ok_or_else(|| Error::NotFound)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn list(
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
let item = Entity::find()
|
||||
.order_by(Column::Id, Order::Desc)
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
views::court::list(&v, &item)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn new(
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(_ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
views::court::create(&v)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn update(
|
||||
Path(id): Path<i32>,
|
||||
State(ctx): State<AppContext>,
|
||||
Form(params): Form<Params>,
|
||||
) -> Result<Redirect> {
|
||||
let item = load_item(&ctx, id).await?;
|
||||
let mut item = item.into_active_model();
|
||||
params.update(&mut item);
|
||||
item.update(&ctx.db).await?;
|
||||
Ok(Redirect::to("../courts"))
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn edit(
|
||||
Path(id): Path<i32>,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
let item = load_item(&ctx, id).await?;
|
||||
views::court::edit(&v, &item)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn show(
|
||||
Path(id): Path<i32>,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
let item = load_item(&ctx, id).await?;
|
||||
views::court::show(&v, &item)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn add(
|
||||
State(ctx): State<AppContext>,
|
||||
Form(params): Form<Params>,
|
||||
) -> Result<Redirect> {
|
||||
let mut item = ActiveModel {
|
||||
..Default::default()
|
||||
};
|
||||
params.update(&mut item);
|
||||
item.insert(&ctx.db).await?;
|
||||
Ok(Redirect::to("courts"))
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn remove(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {
|
||||
load_item(&ctx, id).await?.delete(&ctx.db).await?;
|
||||
format::empty()
|
||||
}
|
||||
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new()
|
||||
.prefix("courts/")
|
||||
.add("/", get(list))
|
||||
.add("/", post(add))
|
||||
.add("new", get(new))
|
||||
.add("{id}", get(show))
|
||||
.add("{id}/edit", get(edit))
|
||||
.add("{id}", delete(remove))
|
||||
.add("{id}", post(update))
|
||||
}
|
||||
16
ht_booking/src/controllers/home.rs
Normal file
16
ht_booking/src/controllers/home.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
#![allow(clippy::unnecessary_struct_initialization)]
|
||||
#![allow(clippy::unused_async)]
|
||||
use loco_rs::prelude::*;
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn home(
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(_ctx): State<AppContext>
|
||||
) -> Result<Response> {
|
||||
format::render().view(&v, "home/home.html", data!({}))
|
||||
}
|
||||
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new().add("/", get(home))
|
||||
}
|
||||
@@ -1 +1,4 @@
|
||||
pub mod auth;
|
||||
|
||||
pub mod court;
|
||||
pub mod home;
|
||||
19
ht_booking/src/models/_entities/courts.rs
Normal file
19
ht_booking/src/models/_entities/courts.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.20
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "courts")]
|
||||
pub struct Model {
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i32,
|
||||
pub name: Option<String>,
|
||||
pub surface: Option<String>,
|
||||
pub indoor: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
@@ -1,4 +1,6 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.20
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod courts;
|
||||
pub mod users;
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.20
|
||||
|
||||
pub use super::courts::Entity as Courts;
|
||||
pub use super::users::Entity as Users;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.20
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
28
ht_booking/src/models/courts.rs
Normal file
28
ht_booking/src/models/courts.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
pub use super::_entities::courts::{ActiveModel, Model, Entity};
|
||||
pub type Courts = Entity;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
async fn before_save<C>(self, _db: &C, insert: bool) -> std::result::Result<Self, DbErr>
|
||||
where
|
||||
C: ConnectionTrait,
|
||||
{
|
||||
if !insert && self.updated_at.is_unchanged() {
|
||||
let mut this = self;
|
||||
this.updated_at = sea_orm::ActiveValue::Set(chrono::Utc::now().into());
|
||||
Ok(this)
|
||||
} else {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// implement your read-oriented logic here
|
||||
impl Model {}
|
||||
|
||||
// implement your write-oriented logic here
|
||||
impl ActiveModel {}
|
||||
|
||||
// implement your custom finders, selectors oriented logic here
|
||||
impl Entity {}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod _entities;
|
||||
pub mod users;
|
||||
pub mod courts;
|
||||
|
||||
39
ht_booking/src/views/court.rs
Normal file
39
ht_booking/src/views/court.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use loco_rs::prelude::*;
|
||||
|
||||
use crate::models::_entities::courts;
|
||||
|
||||
/// Render a list view of `courts`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// When there is an issue with rendering the view.
|
||||
pub fn list(v: &impl ViewRenderer, items: &Vec<courts::Model>) -> Result<Response> {
|
||||
format::render().view(v, "court/list.html", data!({"items": items}))
|
||||
}
|
||||
|
||||
/// Render a single `court` view.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// When there is an issue with rendering the view.
|
||||
pub fn show(v: &impl ViewRenderer, item: &courts::Model) -> Result<Response> {
|
||||
format::render().view(v, "court/show.html", data!({"item": item}))
|
||||
}
|
||||
|
||||
/// Render a `court` create form.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// When there is an issue with rendering the view.
|
||||
pub fn create(v: &impl ViewRenderer) -> Result<Response> {
|
||||
format::render().view(v, "court/create.html", data!({}))
|
||||
}
|
||||
|
||||
/// Render a `court` edit form.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// When there is an issue with rendering the view.
|
||||
pub fn edit(v: &impl ViewRenderer, item: &courts::Model) -> Result<Response> {
|
||||
format::render().view(v, "court/edit.html", data!({"item": item}))
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
pub mod auth;
|
||||
|
||||
pub mod court;
|
||||
Reference in New Issue
Block a user