Fix rent offers
This commit is contained in:
parent
de03009257
commit
f14d27b93d
@ -783,6 +783,10 @@ select {
|
|||||||
z-index: 50;
|
z-index: 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.m-0 {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.m-1 {
|
.m-1 {
|
||||||
margin: 0.25rem;
|
margin: 0.25rem;
|
||||||
}
|
}
|
||||||
@ -1169,10 +1173,6 @@ select {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-2xl {
|
.text-2xl {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
@ -1621,6 +1621,14 @@ select {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1280px) {
|
@media (min-width: 1280px) {
|
||||||
|
.xl\:mt-6 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xl\:block {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.xl\:flex {
|
.xl\:flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@ -1629,9 +1637,25 @@ select {
|
|||||||
min-height: calc(100vh - 80px - 192px);
|
min-height: calc(100vh - 80px - 192px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xl\:w-\[30\%\] {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
.xl\:w-\[48\%\] {
|
.xl\:w-\[48\%\] {
|
||||||
width: 48%;
|
width: 48%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xl\:justify-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xl\:p-0 {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xl\:text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.\[\&\.active\]\:text-black\/90.active {
|
.\[\&\.active\]\:text-black\/90.active {
|
||||||
|
@ -5,15 +5,16 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use actix_web::http::header::ContentType;
|
use actix_web::http::header::ContentType;
|
||||||
use actix_web::web::{scope, Data, Form, Path, ServiceConfig};
|
use actix_web::web::{scope, Data, Form, Path, ServiceConfig};
|
||||||
use actix_web::{get, post, put, HttpRequest, HttpResponse};
|
use actix_web::{delete, get, post, put, HttpRequest, HttpResponse};
|
||||||
use askama_actix::Template;
|
use askama_actix::Template;
|
||||||
use autometrics::autometrics;
|
use autometrics::autometrics;
|
||||||
use oswilno_contract::parking_space_locations::Model as ParkingSpaceLocation;
|
use oswilno_contract::parking_space_locations::Model as ParkingSpaceLocation;
|
||||||
use oswilno_contract::parking_space_rents::Model as ParkingSpaceRent;
|
use oswilno_contract::parking_space_rents::Model as ParkingSpaceRent;
|
||||||
use oswilno_contract::parking_spaces::Model as ParkingSpace;
|
use oswilno_contract::parking_spaces::Model as ParkingSpace;
|
||||||
|
use oswilno_contract::prelude::*;
|
||||||
use oswilno_contract::sea_orm_active_enums::ParkingSpaceState;
|
use oswilno_contract::sea_orm_active_enums::ParkingSpaceState;
|
||||||
use oswilno_contract::{
|
use oswilno_contract::{
|
||||||
accounts, chrono, parking_space_locations, parking_space_rents, parking_spaces,
|
accounts, chrono, parking_space_locations, parking_space_rents, parking_spaces, rent_requests,
|
||||||
};
|
};
|
||||||
use oswilno_session::{Authenticated, MaybeAuthenticated};
|
use oswilno_session::{Authenticated, MaybeAuthenticated};
|
||||||
use oswilno_view::{
|
use oswilno_view::{
|
||||||
@ -40,7 +41,8 @@ pub fn mount(config: &mut ServiceConfig) {
|
|||||||
.service(all_parking_spaces)
|
.service(all_parking_spaces)
|
||||||
.service(create)
|
.service(create)
|
||||||
.service(edit_show)
|
.service(edit_show)
|
||||||
.service(update),
|
.service(update)
|
||||||
|
.service(delete_parking_space),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +134,34 @@ async fn search_parking_spaces() -> HttpResponse {
|
|||||||
HttpResponse::Ok().body("")
|
HttpResponse::Ok().body("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[delete("/delete/{parking_space_id}")]
|
||||||
|
async fn delete_parking_space(
|
||||||
|
_req: HttpRequest,
|
||||||
|
db: Data<sea_orm::DatabaseConnection>,
|
||||||
|
_session: Authenticated,
|
||||||
|
_hcx: HelperContext,
|
||||||
|
parking_space_id: Path<i32>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let parking_space_id = parking_space_id.into_inner();
|
||||||
|
let db = db.into_inner();
|
||||||
|
let Ok(res) = ParkingSpaces::delete_by_id(parking_space_id)
|
||||||
|
.exec(&*db)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| tracing::error!("Failed to delete parking space {parking_space_id}: {e}"))
|
||||||
|
else {
|
||||||
|
return HttpResponse::NotFound()
|
||||||
|
.body(format!("Parking space {parking_space_id} does not exists"));
|
||||||
|
};
|
||||||
|
if res.rows_affected == 1 {
|
||||||
|
HttpResponse::SeeOther()
|
||||||
|
.append_header(("HX-Redirect", "/parking-spaces/all"))
|
||||||
|
.append_header(("Location", "/parking-spaces/all"))
|
||||||
|
.body("")
|
||||||
|
} else {
|
||||||
|
HttpResponse::NotFound().body(format!("Parking space {parking_space_id} does not exists"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn load_parking_spaces(
|
async fn load_parking_spaces(
|
||||||
db: Arc<DatabaseConnection>,
|
db: Arc<DatabaseConnection>,
|
||||||
account_id: Option<i32>,
|
account_id: Option<i32>,
|
||||||
@ -792,3 +822,52 @@ fn render_rent_form(
|
|||||||
}
|
}
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/{parking_space_id}/parking-space-rents/{parking_space_rent_id}/request")]
|
||||||
|
pub async fn create_rent_request(
|
||||||
|
session: Authenticated,
|
||||||
|
db: Data<DatabaseConnection>,
|
||||||
|
parking_space_id: Path<i32>,
|
||||||
|
parking_space_rent_id: Path<i32>,
|
||||||
|
hcx: HelperContext,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let db = db.into_inner();
|
||||||
|
let parking_space_id = parking_space_id.into_inner();
|
||||||
|
let parking_space_rent_id = parking_space_rent_id.into_inner();
|
||||||
|
{
|
||||||
|
use rent_requests::Column::*;
|
||||||
|
|
||||||
|
let res = RentRequests::find()
|
||||||
|
.filter(ParkingSpaceId.eq(Some(parking_space_id)))
|
||||||
|
.filter(ParkingSpaceRentId.eq(Some(parking_space_rent_id)))
|
||||||
|
.filter(AccountId.eq(Some(session.account_id()))).one(&*db).await
|
||||||
|
.inspect_err(|e| tracing::error!("Failed to check rent request existence for space {parking_space_id} and rent {parking_space_rent_id}: {e}"));
|
||||||
|
match res {
|
||||||
|
Ok(Some(_)) => {
|
||||||
|
return HttpResponse::Conflict()
|
||||||
|
.body(filters::t("Already requested", &hcx).unwrap_or_default());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return HttpResponse::InternalServerError()
|
||||||
|
.body(filters::t("Internat server error", &hcx).unwrap_or_default());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let Ok(_rent_request) = rent_requests::ActiveModel {
|
||||||
|
parking_space_id: Set(Some(parking_space_id)),
|
||||||
|
parking_space_rent_id: Set(Some(parking_space_rent_id)),
|
||||||
|
account_id: Set(Some(session.account_id())),
|
||||||
|
..Default::default()
|
||||||
|
}.save(&*db).await
|
||||||
|
.inspect_err(|e| tracing::error!("Failed to create rent request for space {parking_space_id} and rent {parking_space_rent_id}: {e}")) else {
|
||||||
|
return HttpResponse::InternalServerError()
|
||||||
|
.body(filters::t("Internat server error", &hcx).unwrap_or_default());
|
||||||
|
};
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.append_header((
|
||||||
|
"HX-Retarget",
|
||||||
|
format!("#submit-request-rent-{parking_space_rent_id}").as_str(),
|
||||||
|
))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
<section class="container mx-auto px-4">
|
<section class="container mx-auto px-4">
|
||||||
<section class="flex space-x-4">
|
<section class="flex space-x-4 xl:justify-between justify-center">
|
||||||
<h1 class="text-white font-semibold text-5xl">
|
<h1 class="text-white font-semibold text-5xl hidden xl:block">
|
||||||
{{"Parking spaces"}}
|
{{"Parking spaces"}}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="">
|
<div class="hidden xl:block">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="hidden xl:block">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if let Some(session) = session %}
|
{% if let Some(session) = session %}
|
||||||
<div>
|
<div class="m-0">
|
||||||
<a
|
<a
|
||||||
href="/parking-spaces/form"
|
href="/parking-spaces/form"
|
||||||
x-get="/parking-spaces/form"
|
x-get="/parking-spaces/form"
|
||||||
@ -62,7 +63,7 @@
|
|||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<oswilno-parking-space-rents class="xl:flex justify-between">
|
<oswilno-parking-space-rents class="block xl:flex justify-between">
|
||||||
{% for parking_space_rent in parking_space_rents -%}
|
{% for parking_space_rent in parking_space_rents -%}
|
||||||
{% if let Some(parking_space) = parking_space_by_id.get(parking_space_rent.parking_space_id) %}
|
{% if let Some(parking_space) = parking_space_by_id.get(parking_space_rent.parking_space_id) %}
|
||||||
{% if parking_space.state == ParkingSpaceState::Verified || Some(parking_space.account_id.clone()) == account_id %}
|
{% if parking_space.state == ParkingSpaceState::Verified || Some(parking_space.account_id.clone()) == account_id %}
|
||||||
@ -72,53 +73,56 @@
|
|||||||
|
|
||||||
<oswilno-parking-space-rent
|
<oswilno-parking-space-rent
|
||||||
id="parking-space-rent-{{ parking_space_rent.id }}"
|
id="parking-space-rent-{{ parking_space_rent.id }}"
|
||||||
class="xl:w-[48%] p-4 bg-white border border-white-200 rounded-lg shadow sm:p-8 dark:bg-white-800 dark:border-white-700 mt-6"
|
class="block xl:w-[48%] p-4 bg-white border border-white-200 rounded-lg shadow sm:p-8 dark:bg-white-800 dark:border-white-700 mt-6"
|
||||||
>
|
>
|
||||||
<oswilno-parking-space
|
<oswilno-parking-space
|
||||||
id="parking-space-{{ parking_space.id }}"
|
id="parking-space-{{ parking_space.id }}"
|
||||||
{% if let Some(spot) = parking_space.spot %} spot="{{ spot }}" {% endif %}
|
{% if let Some(spot) = parking_space.spot %} spot="{{ spot }}" {% endif %}
|
||||||
class="flex justify-between"
|
class="flex justify-between flex-wrap"
|
||||||
>
|
>
|
||||||
<span class='spot text-4xl font-bold w-[30%] text-left'>
|
<div class='spot text-4xl font-bold w-[30%] text-left'>
|
||||||
{% if let Some(spot) = parking_space.spot %}
|
{% if let Some(spot) = parking_space.spot %}
|
||||||
{{ spot }}
|
{{ spot }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</div>
|
||||||
|
|
||||||
<oswilno-parking-space-location
|
<oswilno-parking-space-location
|
||||||
id="parking-space-location-{{ location.id }}"
|
id="parking-space-location-{{ location.id }}"
|
||||||
name="{{ location.name }}"
|
name="{{ location.name }}"
|
||||||
stage="{{ location.stage }}"
|
stage="{{ location.stage }}"
|
||||||
number="{{ location.number }}"
|
number="{{ location.number }}"
|
||||||
class="w-[30%] text-3xl"
|
class="xl:w-[30%] flex text-3xl"
|
||||||
>
|
>
|
||||||
<span class="name">{{ location.name }}</span>
|
<div>{{ location.name }}</div>
|
||||||
<span class="number">{{ location.number }}</span>
|
<div> </div>
|
||||||
<span class="stage-label text-sm mr-1 ml-1">
|
<div>{{ location.number }}</div>
|
||||||
{{"stage"|t(hcx)}}
|
<div> </div>
|
||||||
</span>
|
<div class="stage-label text-sm mr-1 ml-1">
|
||||||
<span class="stage">
|
{{"stage"|t(hcx)}}
|
||||||
{{ location.stage }}
|
</div>
|
||||||
</span>
|
<div> </div>
|
||||||
|
<div>{{ location.stage }}</div>
|
||||||
</oswilno-parking-space-location>
|
</oswilno-parking-space-location>
|
||||||
|
|
||||||
<oswilno-account
|
<oswilno-account
|
||||||
id="account-{{ account.id }}"
|
id="account-{{ account.id }}"
|
||||||
class="w-[30%] text-right font-bold uppercase text-red-800 dark:text-red-400"
|
login="{{ account.login }}"
|
||||||
|
class="w-full xl:w-[30%] text-center py-2 xl:p-0 xl:text-right font-bold uppercase text-red-800 dark:text-red-400"
|
||||||
>
|
>
|
||||||
<div>{{ account.login }}</div>
|
{{ account.login }}
|
||||||
</oswilno-account>
|
</oswilno-account>
|
||||||
</oswilno-parking-space>
|
</oswilno-parking-space>
|
||||||
|
|
||||||
<div class="xl:flex justify-between mt-6">
|
<div class="flex justify-between xl:mt-6">
|
||||||
<span>{{"Price:"|t(hcx)}}</span>
|
<span>{{"Price:"|t(hcx)}}</span>
|
||||||
<oswilno-price
|
<oswilno-price
|
||||||
id="parking-space-rent-{{ parking_space_rent.id }}-price"
|
id="parking-space-rent-{{ parking_space_rent.id }}-price"
|
||||||
multiplier="100"
|
multiplier="100"
|
||||||
currency="PLN"
|
currency="PLN"
|
||||||
price="{{ parking_space_rent.price }}"
|
price="{{ parking_space_rent.price }}"
|
||||||
|
class="flex justify-between"
|
||||||
>
|
>
|
||||||
<span class="price text-3xl">{{ parking_space_rent.price|display_price }}</span>
|
<span class="price text-3xl">{{ parking_space_rent.price|display_price }}</span>
|
||||||
<span class="currency text-base text-neutral-500 dark:text-neutral-300">PLN</span>
|
<span class="currency text-base text-neutral-500 dark:text-neutral-300">PLN</span>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
<a
|
<a
|
||||||
href="/parking-spaces/delete/{{parking_space.id}}"
|
href="/parking-spaces/delete/{{parking_space.id}}"
|
||||||
hx-target="main"
|
hx-target="main"
|
||||||
hx-delete="/parking-spaces/edit/{{parking_space.id}}"
|
hx-delete="/parking-spaces/delete/{{parking_space.id}}"
|
||||||
hx-headers='{"Accept":"text/html-partial"}'
|
hx-headers='{"Accept":"text/html-partial"}'
|
||||||
class="text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm p-2.5 text-center inline-flex items-center"
|
class="text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm p-2.5 text-center inline-flex items-center"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user