Display locations
This commit is contained in:
parent
5e806454f9
commit
4edccc7661
@ -76,6 +76,18 @@ impl MigrationTrait for Migration {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
m.create_index(
|
||||||
|
IndexCreateStatement::default()
|
||||||
|
.unique()
|
||||||
|
.name("uniq-location")
|
||||||
|
.table(ParkingSpaceLocation::ParkingSpaceLocations)
|
||||||
|
.col(ParkingSpaceLocation::Name)
|
||||||
|
.col(ParkingSpaceLocation::Number)
|
||||||
|
.col(ParkingSpaceLocation::Stage)
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
crates/oswilno-parking-space/assets/wilno.webp
Normal file
BIN
crates/oswilno-parking-space/assets/wilno.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 366 KiB |
@ -3,16 +3,23 @@ use actix_web::web::{scope, Data, Form, ServiceConfig};
|
|||||||
use actix_web::{get, post, HttpRequest, HttpResponse};
|
use actix_web::{get, post, HttpRequest, HttpResponse};
|
||||||
use askama_actix::Template;
|
use askama_actix::Template;
|
||||||
use autometrics::autometrics;
|
use autometrics::autometrics;
|
||||||
use oswilno_contract::accounts;
|
|
||||||
use oswilno_contract::parking_space_rents;
|
use oswilno_contract::parking_space_rents;
|
||||||
use oswilno_contract::parking_spaces;
|
use oswilno_contract::parking_spaces;
|
||||||
|
use oswilno_contract::{accounts, parking_space_locations};
|
||||||
use oswilno_session::{Authenticated, MaybeAuthenticated};
|
use oswilno_session::{Authenticated, MaybeAuthenticated};
|
||||||
use oswilno_view::{is_partial, Blank, Layout, Main, MainOpts, SearchOpts, SessionOpts};
|
use oswilno_view::{
|
||||||
|
filters, is_partial, Blank, Errors, Lang, Layout, Main, MainOpts, SearchOpts, SessionOpts,
|
||||||
|
TranslationStorage,
|
||||||
|
};
|
||||||
use sea_orm::prelude::*;
|
use sea_orm::prelude::*;
|
||||||
use sea_orm::ActiveValue::{NotSet, Set};
|
use sea_orm::ActiveValue::{NotSet, Set};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub async fn init(db: Arc<sea_orm::DatabaseConnection>) {
|
||||||
|
ensure_locations(db).await;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mount(config: &mut ServiceConfig) {
|
pub fn mount(config: &mut ServiceConfig) {
|
||||||
config.service(root).service(
|
config.service(root).service(
|
||||||
scope("/parking-spaces")
|
scope("/parking-spaces")
|
||||||
@ -36,6 +43,7 @@ struct AllPartialParkingSpace {
|
|||||||
parking_space_rents: Vec<parking_space_rents::Model>,
|
parking_space_rents: Vec<parking_space_rents::Model>,
|
||||||
parking_space_by_id: HashMap<i32, parking_spaces::Model>,
|
parking_space_by_id: HashMap<i32, parking_spaces::Model>,
|
||||||
account_by_id: HashMap<i32, accounts::Model>,
|
account_by_id: HashMap<i32, accounts::Model>,
|
||||||
|
locations: Vec<parking_space_locations::Model>,
|
||||||
session: Option<SessionOpts>,
|
session: Option<SessionOpts>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,19 +122,45 @@ async fn load_parking_spaces(db: Arc<DatabaseConnection>) -> AllPartialParkingSp
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let locations = load_locations(db).await;
|
||||||
|
|
||||||
AllPartialParkingSpace {
|
AllPartialParkingSpace {
|
||||||
account_by_id,
|
account_by_id,
|
||||||
parking_space_rents: rents,
|
parking_space_rents: rents,
|
||||||
parking_space_by_id,
|
parking_space_by_id,
|
||||||
|
locations,
|
||||||
session: None,
|
session: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn load_locations(db: Arc<DatabaseConnection>) -> Vec<parking_space_locations::Model> {
|
||||||
|
use oswilno_contract::parking_space_locations::*;
|
||||||
|
let mut v = Entity::find().all(&*db).await.unwrap();
|
||||||
|
v.sort_by(|l, r| {
|
||||||
|
l.name
|
||||||
|
.cmp(&r.name)
|
||||||
|
.cmp(&l.number.cmp(&r.number))
|
||||||
|
.cmp(&l.stage.cmp(&r.stage))
|
||||||
|
});
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/form")]
|
#[get("/form")]
|
||||||
async fn form_show(req: HttpRequest, session: Authenticated) -> HttpResponse {
|
async fn form_show(
|
||||||
|
req: HttpRequest,
|
||||||
|
session: Authenticated,
|
||||||
|
t: Data<TranslationStorage>,
|
||||||
|
lang: Lang,
|
||||||
|
db: Data<DatabaseConnection>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let db = db.into_inner();
|
||||||
let session = session.into();
|
let session = session.into();
|
||||||
let body = ParkingSpaceFormPartial {
|
let body = ParkingSpaceFormPartial {
|
||||||
..Default::default()
|
form: Default::default(),
|
||||||
|
locations: load_locations(db.clone()).await,
|
||||||
|
lang,
|
||||||
|
errors: Default::default(),
|
||||||
|
t: t.into_inner(),
|
||||||
};
|
};
|
||||||
let main = Main {
|
let main = Main {
|
||||||
body,
|
body,
|
||||||
@ -147,10 +181,14 @@ async fn form_show(req: HttpRequest, session: Authenticated) -> HttpResponse {
|
|||||||
.body(html.unwrap())
|
.body(html.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Template)]
|
#[derive(Debug, Template)]
|
||||||
#[template(path = "../templates/parking-spaces/form-partial.html")]
|
#[template(path = "../templates/parking-spaces/form-partial.html")]
|
||||||
struct ParkingSpaceFormPartial {
|
struct ParkingSpaceFormPartial {
|
||||||
form: CreateParkingSpace,
|
form: CreateParkingSpace,
|
||||||
|
lang: Lang,
|
||||||
|
errors: Errors,
|
||||||
|
t: Arc<TranslationStorage>,
|
||||||
|
locations: Vec<parking_space_locations::Model>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, serde::Deserialize)]
|
#[derive(Debug, Default, serde::Deserialize)]
|
||||||
@ -165,6 +203,8 @@ async fn create(
|
|||||||
db: Data<sea_orm::DatabaseConnection>,
|
db: Data<sea_orm::DatabaseConnection>,
|
||||||
p: Form<CreateParkingSpace>,
|
p: Form<CreateParkingSpace>,
|
||||||
session: Authenticated,
|
session: Authenticated,
|
||||||
|
t: Data<TranslationStorage>,
|
||||||
|
lang: Lang,
|
||||||
) -> HttpResponse {
|
) -> HttpResponse {
|
||||||
use oswilno_contract::parking_spaces::*;
|
use oswilno_contract::parking_spaces::*;
|
||||||
let CreateParkingSpace { location_id, spot } = p.into_inner();
|
let CreateParkingSpace { location_id, spot } = p.into_inner();
|
||||||
@ -181,6 +221,10 @@ async fn create(
|
|||||||
return HttpResponse::BadRequest().body(
|
return HttpResponse::BadRequest().body(
|
||||||
ParkingSpaceFormPartial {
|
ParkingSpaceFormPartial {
|
||||||
form: CreateParkingSpace { location_id, spot },
|
form: CreateParkingSpace { location_id, spot },
|
||||||
|
t: t.into_inner(),
|
||||||
|
lang,
|
||||||
|
errors: Default::default(),
|
||||||
|
locations: load_locations(db.clone()).await,
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -189,3 +233,39 @@ async fn create(
|
|||||||
|
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn ensure_locations(db: Arc<sea_orm::DatabaseConnection>) {
|
||||||
|
for (name, number, stage) in [
|
||||||
|
("Wilno", 1, "1a"),
|
||||||
|
("Wilno", 1, "1b"),
|
||||||
|
("Wilno", 1, "2AF1"),
|
||||||
|
("Wilno", 1, "2AF2"),
|
||||||
|
("Wilno", 1, "3"),
|
||||||
|
("Wilno", 1, "4"),
|
||||||
|
("Wilno", 2, "1"),
|
||||||
|
("Wilno", 2, "2"),
|
||||||
|
("Wilno", 2, "3"),
|
||||||
|
("Wilno", 3, "1"),
|
||||||
|
("Wilno", 3, "2"),
|
||||||
|
("Wilno", 3, "3"),
|
||||||
|
("Wilno", 3, "4"),
|
||||||
|
("Wilno", 3, "5"),
|
||||||
|
// 4
|
||||||
|
("Wilno", 4, "1"),
|
||||||
|
("Wilno", 4, "2"),
|
||||||
|
("Wilno", 4, "3"),
|
||||||
|
// 5
|
||||||
|
("Wilno", 5, "1"),
|
||||||
|
("Wilno", 5, "2"),
|
||||||
|
] {
|
||||||
|
let _model = oswilno_contract::parking_space_locations::ActiveModel {
|
||||||
|
name: Set(name.to_string()),
|
||||||
|
number: Set(number),
|
||||||
|
stage: Set(stage.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.save(&*db)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
<section id="main-view" class="min-h-screen flex items-center justify-center">
|
||||||
|
<section class="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
|
||||||
|
{% for error in errors.global() %}
|
||||||
|
<oswilno-error>{{error|t(lang,t)}}</oswilno-error>
|
||||||
|
{% endfor %}
|
||||||
|
<form hx-post="/login" hx-target="#main-view">
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="location_id" class="block mb-2 text-sm text-gray-600">location_id</label>
|
||||||
|
<select id="location_id" name="location_id" value="{{ form.location_id }}" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500">
|
||||||
|
{% for loc in locations %}
|
||||||
|
<option value="{{loc.id}}">
|
||||||
|
{{ loc.name }}
|
||||||
|
{{ loc.number }}
|
||||||
|
{{ loc.stage }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
{% for error in errors.field("login") %}
|
||||||
|
<oswilno-error>{{error|t(lang,t)}}</oswilno-error>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="mb-6">
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
value="{{"Submit"|t(lang,t)}}"
|
||||||
|
class="w-32 bg-cyan-600 text-white py-2 rounded-lg mx-auto block focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 mb-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</section>
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
@ -48,6 +49,8 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let session_config = oswilno_session::SessionConfigurator::new(redis.clone());
|
let session_config = oswilno_session::SessionConfigurator::new(redis.clone());
|
||||||
session_config.translations(&mut l10n);
|
session_config.translations(&mut l10n);
|
||||||
|
|
||||||
|
oswilno_parking_space::init(Arc::new(conn.clone())).await;
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
let session_config = session_config.clone();
|
let session_config = session_config.clone();
|
||||||
let session_factory = session_config.factory();
|
let session_factory = session_config.factory();
|
||||||
|
Loading…
Reference in New Issue
Block a user