Display price
This commit is contained in:
parent
de9f1742d1
commit
fa38a41044
@ -8,6 +8,15 @@
|
|||||||
offer-id="{{offer.id}}"
|
offer-id="{{offer.id}}"
|
||||||
description="{{offer.description}}"
|
description="{{offer.description}}"
|
||||||
picture-url="{{offer.picture_url}}"
|
picture-url="{{offer.picture_url}}"
|
||||||
|
{% match offer.price_range %}
|
||||||
|
{% when PriceRange::Free %}
|
||||||
|
price-range="free"
|
||||||
|
{% when PriceRange::Fixed with { value } %}
|
||||||
|
price-range="{{value}}"
|
||||||
|
{% when PriceRange::Range with { min, max } %}
|
||||||
|
price-range-min="{{min}}"
|
||||||
|
price-range-max="{{max}}"
|
||||||
|
{% endmatch %}
|
||||||
></marketplace-offer>
|
></marketplace-offer>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</marketplace-offers>
|
</marketplace-offers>
|
||||||
|
@ -84,14 +84,18 @@ customElements.define('marketplace-offer', class extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set price_range(v) {
|
set price_range(v) {
|
||||||
|
if (v instanceof PriceRange) return;
|
||||||
v = v + '';
|
v = v + '';
|
||||||
if (!v.match(/free|(\d+([,.]\d{2})?)(,(\d+([,.]\d{2})?))?/i))
|
if (!v.match(/free|(\d+([,.]\d{2})?)(\|(\d+([,.]\d{2})?))?/i))
|
||||||
return;
|
return console.warn('malformed price range');
|
||||||
|
|
||||||
if (v === 'free') return this.#price_range = new PriceRange(v, 0);
|
if (v === 'free')
|
||||||
if (v.includes(',')) {
|
this.#price_range = new PriceRange(v, 0);
|
||||||
|
else if (v.includes(',')) {
|
||||||
const [min, max, ...r] = v.split(',');
|
const [min, max, ...r] = v.split(',');
|
||||||
this.#price_range = new PriceRange(parseInt(min), parseInt(max));
|
this.#price_range = new PriceRange(parseInt(min), parseInt(max));
|
||||||
|
} else {
|
||||||
|
this.#price_range.min = parseInt(v);
|
||||||
}
|
}
|
||||||
this.#displayPrice();
|
this.#displayPrice();
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,16 @@ export class PriceRange {
|
|||||||
set max(v) {
|
set max(v) {
|
||||||
this.#max = v;
|
this.#max = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Symbol.toStringTag]() {
|
||||||
|
return this.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
if (this.isFixed) return this.min.toString()
|
||||||
|
if (this.isFree) return 'free';
|
||||||
|
return `${this.min}|${this.max}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fireFbReady = () => {
|
export const fireFbReady = () => {
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::model::db;
|
use crate::model::db;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default, Serialize)]
|
||||||
pub enum Page {
|
pub enum Page {
|
||||||
#[default]
|
#[default]
|
||||||
LocalBusinesses,
|
LocalBusinesses,
|
||||||
|
@ -1,26 +1,28 @@
|
|||||||
use actix_web::web::{self, Data, ServiceConfig};
|
use actix_web::web::{self, Data, ServiceConfig};
|
||||||
use actix_web::{get, HttpResponse};
|
use actix_web::{get, HttpRequest, HttpResponse};
|
||||||
use askama::*;
|
use askama::*;
|
||||||
|
use serde::Serialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use crate::model::db;
|
use crate::model::db::{self, PriceRange};
|
||||||
use crate::model::view::Page;
|
use crate::model::view::Page;
|
||||||
use crate::queries;
|
use crate::queries;
|
||||||
use crate::routes::{Identity, Result};
|
use crate::routes::{Identity, Result};
|
||||||
use crate::view::Helper;
|
use crate::view::Helper;
|
||||||
|
|
||||||
#[derive(Default, Template)]
|
#[derive(Default, Serialize, Template)]
|
||||||
#[template(path = "./marketplace/index.html")]
|
#[template(path = "./marketplace/index.html")]
|
||||||
struct MarketplaceTemplate {
|
struct MarketplaceTemplate {
|
||||||
account: Option<db::Account>,
|
account: Option<db::Account>,
|
||||||
error: Option<String>,
|
error: Option<String>,
|
||||||
page: Page,
|
page: Page,
|
||||||
|
#[serde(skip)]
|
||||||
h: Helper,
|
h: Helper,
|
||||||
offers: Vec<db::Offer>,
|
offers: Vec<db::Offer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("")]
|
#[get("")]
|
||||||
async fn marketplace(db: Data<PgPool>, id: Identity) -> Result<HttpResponse> {
|
async fn marketplace(req: HttpRequest, db: Data<PgPool>, id: Identity) -> Result<HttpResponse> {
|
||||||
let pool = db.into_inner();
|
let pool = db.into_inner();
|
||||||
let mut t = crate::ok_or_internal!(pool.begin().await);
|
let mut t = crate::ok_or_internal!(pool.begin().await);
|
||||||
let account = match id.identity() {
|
let account = match id.identity() {
|
||||||
@ -32,16 +34,24 @@ async fn marketplace(db: Data<PgPool>, id: Identity) -> Result<HttpResponse> {
|
|||||||
|
|
||||||
t.commit().await.ok();
|
t.commit().await.ok();
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().body(
|
match req.headers().get("accept").and_then(|h| h.to_str().ok()) {
|
||||||
MarketplaceTemplate {
|
Some("application/json") => Ok(HttpResponse::Ok().json(MarketplaceTemplate {
|
||||||
page: Page::Marketplace,
|
page: Page::Marketplace,
|
||||||
account,
|
account,
|
||||||
offers,
|
offers,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})),
|
||||||
.render()
|
_ => Ok(HttpResponse::Ok().content_type("text/html").body(
|
||||||
.unwrap(),
|
MarketplaceTemplate {
|
||||||
))
|
page: Page::Marketplace,
|
||||||
|
account,
|
||||||
|
offers,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.render()
|
||||||
|
.unwrap(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure(config: &mut ServiceConfig) {
|
pub fn configure(config: &mut ServiceConfig) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::model::db::AccountType;
|
use crate::model::db::AccountType;
|
||||||
|
|
||||||
pub mod filters {
|
pub mod filters {
|
||||||
@ -9,7 +11,7 @@ pub mod filters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug, Serialize)]
|
||||||
pub struct Helper;
|
pub struct Helper;
|
||||||
|
|
||||||
impl Helper {
|
impl Helper {
|
||||||
|
Loading…
Reference in New Issue
Block a user