Compare commits
32 Commits
c111d2f668
...
335a84838f
Author | SHA1 | Date | |
---|---|---|---|
335a84838f | |||
0d6627d86a | |||
c31776e46d | |||
76090d4266 | |||
daf472fd3e | |||
1317863cec | |||
08bdbbfded | |||
a330b6ddd2 | |||
3daaaca521 | |||
f634ac4891 | |||
86d4b2c6de | |||
7b3014b44d | |||
9ee4a35cab | |||
243b971539 | |||
bd73c2e9ea | |||
3fcb854ff9 | |||
0e541c2f52 | |||
8fe911c9dd | |||
b984caef76 | |||
0989a48065 | |||
f314c4d63d | |||
b3a56558f2 | |||
99a7f1c362 | |||
2a9d2f812d | |||
a00602192a | |||
e8d63c3b84 | |||
8d9855d249 | |||
42bf3c58e3 | |||
07e0d95f12 | |||
9e30d854e8 | |||
5a155c0cd7 | |||
7a9f26c18f |
904
Cargo.lock
generated
904
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,7 @@ mod m20220101_000001_create_table;
|
|||||||
mod m20230726_124452_images;
|
mod m20230726_124452_images;
|
||||||
mod m20230726_135630_parking_spaces;
|
mod m20230726_135630_parking_spaces;
|
||||||
mod m20230805_000001_add_email;
|
mod m20230805_000001_add_email;
|
||||||
|
mod m20230809_135630_add_spot;
|
||||||
|
|
||||||
pub struct Migrator;
|
pub struct Migrator;
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ impl MigratorTrait for Migrator {
|
|||||||
Box::new(m20230726_124452_images::Migration),
|
Box::new(m20230726_124452_images::Migration),
|
||||||
Box::new(m20230726_135630_parking_spaces::Migration),
|
Box::new(m20230726_135630_parking_spaces::Migration),
|
||||||
Box::new(m20230805_000001_add_email::Migration),
|
Box::new(m20230805_000001_add_email::Migration),
|
||||||
|
Box::new(m20230809_135630_add_spot::Migration),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ pub enum ParkingSpace {
|
|||||||
Id,
|
Id,
|
||||||
State,
|
State,
|
||||||
Location,
|
Location,
|
||||||
|
Spot,
|
||||||
AccountId,
|
AccountId,
|
||||||
CreatedAt,
|
CreatedAt,
|
||||||
UpdatedAt,
|
UpdatedAt,
|
||||||
|
35
crates/migration/src/m20230809_135630_add_spot.rs
Normal file
35
crates/migration/src/m20230809_135630_add_spot.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
|
use crate::m20230726_135630_parking_spaces::ParkingSpace;
|
||||||
|
|
||||||
|
#[derive(DeriveMigrationName)]
|
||||||
|
pub struct Migration;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl MigrationTrait for Migration {
|
||||||
|
async fn up(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
m.alter_table(
|
||||||
|
Table::alter()
|
||||||
|
.table(ParkingSpace::ParkingSpaces)
|
||||||
|
.add_column(
|
||||||
|
ColumnDef::new(ParkingSpace::Spot)
|
||||||
|
.integer())
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn down(&self, m: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
m.alter_table(
|
||||||
|
Table::alter()
|
||||||
|
.table(ParkingSpace::ParkingSpaces)
|
||||||
|
.drop_column(ParkingSpace::Spot)
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
use actix_web::get;
|
use actix_web::web::{scope, Data, Form, ServiceConfig};
|
||||||
use actix_web::web::{scope, Data, ServiceConfig};
|
use actix_web::{get, post, HttpResponse};
|
||||||
use askama_actix::Template;
|
use askama_actix::Template;
|
||||||
use oswilno_contract::accounts;
|
use oswilno_contract::accounts;
|
||||||
use oswilno_contract::parking_space_rents;
|
use oswilno_contract::parking_space_rents;
|
||||||
@ -100,3 +100,18 @@ async fn load_parking_spaces(db: Arc<DatabaseConnection>) -> AllParkingSpace {
|
|||||||
parking_space_by_id,
|
parking_space_by_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize)]
|
||||||
|
struct CreateParkingSpace {
|
||||||
|
location: String,
|
||||||
|
spot: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/parking-spaces")]
|
||||||
|
async fn create(
|
||||||
|
db: Data<sea_orm::DatabaseConnection>,
|
||||||
|
p: Form<CreateParkingSpace>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let p = p.into_inner();
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@ actix-http = "3.3.1"
|
|||||||
actix-jwt-authc = { version = "0.2.0", features = ["tracing", "session"] }
|
actix-jwt-authc = { version = "0.2.0", features = ["tracing", "session"] }
|
||||||
actix-web = "4.3.1"
|
actix-web = "4.3.1"
|
||||||
argon2 = "0.5.1"
|
argon2 = "0.5.1"
|
||||||
askama = "0.12.0"
|
askama = { version = "0.12.0", features = ["serde", "with-actix-web", "comrak", "mime"] }
|
||||||
askama_actix = { version = "0.14.0" }
|
askama_actix = { version = "0.14.0" }
|
||||||
autometrics = { version = "0.5.0", features = ["tracing", "tracing-subscriber", "thiserror"] }
|
autometrics = { version = "0.5.0", features = ["tracing", "tracing-subscriber", "thiserror"] }
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||||||
use actix_jwt_authc::*;
|
use actix_jwt_authc::*;
|
||||||
use actix_web::web::{Data, Form, ServiceConfig};
|
use actix_web::web::{Data, Form, ServiceConfig};
|
||||||
use actix_web::{get, post, HttpResponse};
|
use actix_web::{get, post, HttpResponse};
|
||||||
use askama_actix::Template;
|
use askama_actix::{Template, TemplateToResponse as _};
|
||||||
use autometrics::autometrics;
|
use autometrics::autometrics;
|
||||||
use futures::channel::{mpsc, mpsc::Sender};
|
use futures::channel::{mpsc, mpsc::Sender};
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
@ -206,12 +206,7 @@ async fn login(
|
|||||||
{
|
{
|
||||||
Ok(res) => Ok(HttpResponse::Ok().json(res)),
|
Ok(res) => Ok(HttpResponse::Ok().json(res)),
|
||||||
Err(form) => Ok(HttpResponse::Ok().body(
|
Err(form) => Ok(HttpResponse::Ok().body(
|
||||||
SignInPartialTemplate {
|
(SignInPartialTemplate { form, lang, t, errors })
|
||||||
form,
|
|
||||||
lang,
|
|
||||||
t,
|
|
||||||
errors,
|
|
||||||
}
|
|
||||||
.render()
|
.render()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)),
|
)),
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
<label for="login" class="block mb-2 text-sm text-gray-600">Login</label>
|
<label for="login" class="block mb-2 text-sm text-gray-600">Login</label>
|
||||||
<input id="login" name="login" value="{{ form.login }}" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500" />
|
<input id="login" name="login" value="{{ form.login }}" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-cyan-500" />
|
||||||
{% for error in errors.field("login") %}
|
{% for error in errors.field("login") %}
|
||||||
<oswilno-error>{{error|t(lang,t)}}</oswilno-error>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "oswilno"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
actix = { version = "*" }
|
|
||||||
actix-cors = { version = "*" }
|
|
||||||
actix-files = { version = "*" }
|
|
||||||
actix-http = { version = "3.2.1" }
|
|
||||||
actix-identity = { version = "0.4.0" }
|
|
||||||
actix-multipart = { version = "0.4.0" }
|
|
||||||
actix-rt = { version = "*" }
|
|
||||||
actix-utils = { version = "3.0.0" }
|
|
||||||
actix-web = { version = "*" }
|
|
||||||
argon2 = { version = "0.4.1" }
|
|
||||||
askama = { version = "*", features = ["serde-json"] }
|
|
||||||
base64 = { version = "0.13.0" }
|
|
||||||
byteorder = { version = "1.4.3" }
|
|
||||||
chrono = { version = "*", features = ["serde"] }
|
|
||||||
contract = { path = "../contract", features = ['db'] }
|
|
||||||
dotenv = { version = "0.15.0" }
|
|
||||||
futures = { version = "0.3.21", features = ["async-await", "std"] }
|
|
||||||
futures-util = { version = "0.3.21", features = [] }
|
|
||||||
gumdrop = { version = "*" }
|
|
||||||
password-hash = { version = "0.4.2" }
|
|
||||||
postgres = { version = "0.19.3" }
|
|
||||||
rand = { version = "0.8.5", features = [] }
|
|
||||||
serde = { version = "*", features = ["derive"] }
|
|
||||||
serde_json = { version = "*" }
|
|
||||||
sqlx = { version = "*", features = ["runtime-actix-rustls", "postgres", "uuid", "chrono", "migrate"] }
|
|
||||||
sqlx-core = { version = "0.6.0" }
|
|
||||||
tokio = { version = "1.27.0", features = ['full'] }
|
|
||||||
tracing = { version = "*" }
|
|
||||||
tracing-actix-web = { version = "*" }
|
|
||||||
tracing-subscriber = { version = "*" }
|
|
||||||
uuid = { version = "*", features = ["serde"] }
|
|
||||||
validator = { version = "0.14", features = ["derive"] }
|
|
@ -1,132 +0,0 @@
|
|||||||
use actix_http::StatusCode;
|
|
||||||
use actix_web::web::{Data, ServiceConfig};
|
|
||||||
use actix_web::{get, web, HttpRequest};
|
|
||||||
use askama::Template;
|
|
||||||
use contract::businesses::BusinessList;
|
|
||||||
use contract::{Account, Helper};
|
|
||||||
use serde::Serialize;
|
|
||||||
use sqlx::PgPool;
|
|
||||||
|
|
||||||
use crate::model::view;
|
|
||||||
use crate::model::view::{account_to_view, business_to_view, Page};
|
|
||||||
use crate::queries;
|
|
||||||
use crate::routes::unrestricted::IndexTemplate;
|
|
||||||
use crate::routes::{HttpResult, Identity};
|
|
||||||
|
|
||||||
#[get("")]
|
|
||||||
#[tracing::instrument]
|
|
||||||
pub async fn businesses_page(req: HttpRequest, db: Data<PgPool>, id: Identity) -> HttpResult {
|
|
||||||
let pool = db.into_inner();
|
|
||||||
let mut t = crate::ok_or_internal!(&req, pool.begin().await);
|
|
||||||
let account = match id.identity() {
|
|
||||||
Some(id) => queries::account_by_id(&mut t, id).await,
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
let (services, mut items, mut contacts) = {
|
|
||||||
use crate::model::db::{LocalBusiness, LocalBusinessItem};
|
|
||||||
let services: Vec<LocalBusiness> = queries::visible_businesses(&mut t)
|
|
||||||
.await
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let items: Vec<LocalBusinessItem> = queries::visible_business_items(&mut t)
|
|
||||||
.await
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let contacts = queries::all_contacts(&mut t).await.unwrap_or_default();
|
|
||||||
(services, items, contacts)
|
|
||||||
};
|
|
||||||
|
|
||||||
let services: Vec<_> = services
|
|
||||||
.into_iter()
|
|
||||||
.map(|service| business_to_view(service, &mut items, &mut contacts))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
t.commit().await.ok();
|
|
||||||
|
|
||||||
HttpResult::res(
|
|
||||||
&req,
|
|
||||||
StatusCode::OK,
|
|
||||||
IndexTemplate(BusinessList {
|
|
||||||
businesses: services,
|
|
||||||
account: account.map(account_to_view),
|
|
||||||
page: Page::LocalBusinesses,
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Template)]
|
|
||||||
#[template(path = "businesses/show.html")]
|
|
||||||
pub struct ShowTemplate {
|
|
||||||
business: view::LocalBusiness,
|
|
||||||
account: Option<Account>,
|
|
||||||
error: Option<String>,
|
|
||||||
page: Page,
|
|
||||||
h: Helper,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/{id}")]
|
|
||||||
#[tracing::instrument]
|
|
||||||
pub async fn show_business_page(
|
|
||||||
req: HttpRequest,
|
|
||||||
db: Data<PgPool>,
|
|
||||||
id: Identity,
|
|
||||||
path: web::Path<(i32,)>,
|
|
||||||
) -> HttpResult {
|
|
||||||
let business_id = path.into_inner().0;
|
|
||||||
let pool = db.into_inner();
|
|
||||||
let mut t = crate::ok_or_internal!(&req, pool.begin().await);
|
|
||||||
let account = match id.identity() {
|
|
||||||
Some(id) => queries::account_by_id(&mut t, id).await,
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
let (business, mut items, mut contacts) = {
|
|
||||||
use crate::model::db::{LocalBusiness, LocalBusinessItem};
|
|
||||||
let business: LocalBusiness = match queries::business_by_id(&mut t, business_id).await {
|
|
||||||
Ok(business) => business,
|
|
||||||
Err(e) => {
|
|
||||||
dbg!(e);
|
|
||||||
return HttpResult::res(
|
|
||||||
&req,
|
|
||||||
StatusCode::BAD_REQUEST,
|
|
||||||
ShowTemplate {
|
|
||||||
account: account.map(account_to_view),
|
|
||||||
page: Page::Business,
|
|
||||||
error: Some("Page not found".into()),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let items: Vec<LocalBusinessItem> = queries::visible_business_items(&mut t)
|
|
||||||
.await
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let contacts = queries::all_contacts(&mut t).await.unwrap_or_default();
|
|
||||||
(business, items, contacts)
|
|
||||||
};
|
|
||||||
|
|
||||||
let business = business_to_view(business, &mut items, &mut contacts);
|
|
||||||
|
|
||||||
t.commit().await.ok();
|
|
||||||
|
|
||||||
HttpResult::res(
|
|
||||||
&req,
|
|
||||||
StatusCode::OK,
|
|
||||||
ShowTemplate {
|
|
||||||
business,
|
|
||||||
account: account.map(account_to_view),
|
|
||||||
page: Page::LocalBusinesses,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn configure(config: &mut ServiceConfig) {
|
|
||||||
config.service(
|
|
||||||
web::scope("/local-businesses")
|
|
||||||
.service(show_business_page)
|
|
||||||
.service(businesses_page),
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user