Show business item image

This commit is contained in:
eraden 2022-07-11 07:58:13 +02:00
parent d7f3f1c7f9
commit 563917d924
10 changed files with 115 additions and 47 deletions

View File

@ -25,6 +25,7 @@
<article> <article>
<ow-nav> <ow-nav>
<ow-path path="/" selected="{{ page.select_index() }}">Lokalne Usługi</ow-path> <ow-path path="/" selected="{{ page.select_index() }}">Lokalne Usługi</ow-path>
<ow-path path="/" selected="{{ page.select_marketplace() }}">Targ</ow-path>
<ow-path path="/news" selected="{{ page.select_news() }}">Aktualności</ow-path> <ow-path path="/news" selected="{{ page.select_news() }}">Aktualności</ow-path>
<ow-path path="/account" selected="{{ page.select_account() }}">Konto</ow-path> <ow-path path="/account" selected="{{ page.select_account() }}">Konto</ow-path>
{% match account.as_ref() %} {% match account.as_ref() %}

View File

@ -13,7 +13,12 @@
{% endfor %} {% endfor %}
{% for item in service.items %} {% for item in service.items %}
<local-business-item slot="item" name="{{item.name}}" price="{{item.price}}"> <local-business-item
slot="item"
name="{{item.name}}"
price="{{item.price}}"
picture-url="{{item.picture_url}}"
>
</local-business-item> </local-business-item>
{% endfor %} {% endfor %}

59
client/dist/app.js vendored
View File

@ -111,7 +111,13 @@ class Component extends HTMLElement {
mode: "open" mode: "open"
}), this.#a.innerHTML = a; }), this.#a.innerHTML = a;
} }
connectedCallback() {} connectedCallback() {
let a = this.constructor.observedAttributes;
if (Array.isArray(a)) for (let b of a){
let c = this.constructor.attr2Field(b);
c && (this[c] = this[c]);
}
}
attributeChangedCallback(a, b, c) { attributeChangedCallback(a, b, c) {
if (b === c) return; if (b === c) return;
let d = this.constructor.observedAttributes; let d = this.constructor.observedAttributes;
@ -208,7 +214,8 @@ customElements.define("local-business-item", class extends Component {
static get observedAttributes() { static get observedAttributes() {
return [ return [
"name", "name",
"price" "price",
"picture-url"
]; ];
} }
constructor(){ constructor(){
@ -226,15 +233,20 @@ customElements.define("local-business-item", class extends Component {
#price { #price {
font-weight: bold; font-weight: bold;
} }
img {
width: 200px;
max-width: 200px;
}
</style> </style>
<section id="item"> <section id="item">
<img alt="" src="" />
<h3 id="name"></h3> <h3 id="name"></h3>
<price-view id="price"></price-view> <price-view id="price"></price-view>
</section> </section>
`); `);
} }
connectedCallback() { connectedCallback() {
this.name = this.name, this.price = this.price; super.connectedCallback();
} }
attributeChangedCallback(a, b, c) { attributeChangedCallback(a, b, c) {
super.attributeChangedCallback(a, b, c); super.attributeChangedCallback(a, b, c);
@ -252,6 +264,12 @@ customElements.define("local-business-item", class extends Component {
set name(a) { set name(a) {
this.setAttribute("name", a), this.shadowRoot.querySelector("#name").textContent = a; this.setAttribute("name", a), this.shadowRoot.querySelector("#name").textContent = a;
} }
get picture_url() {
return this.getAttribute("picture-url");
}
set picture_url(a) {
this.setAttribute("picture-url", a), a && (this.shadowRoot.querySelector("img").src = a);
}
}); });
customElements.define("local-business", class extends Component { customElements.define("local-business", class extends Component {
static get observedAttributes() { static get observedAttributes() {
@ -278,7 +296,7 @@ customElements.define("local-business", class extends Component {
`); `);
} }
connectedCallback() { connectedCallback() {
this.name = this.name; super.connectedCallback();
} }
attributeChangedCallback(a, b, c) { attributeChangedCallback(a, b, c) {
super.attributeChangedCallback(a, b, c); super.attributeChangedCallback(a, b, c);
@ -1445,7 +1463,7 @@ customElements.define("image-input", class extends Component {
<canvas width="200" height="200"></canvas> <canvas width="200" height="200"></canvas>
</div> </div>
<div> <div>
<input id="save" type="button" value="Zapisz" /> <input id="save" type="button" value="Wyślij" />
</div> </div>
</article> </article>
`), this.shadowRoot.querySelector("#save").addEventListener("click", (a)=>{ `), this.shadowRoot.querySelector("#save").addEventListener("click", (a)=>{
@ -1528,23 +1546,28 @@ customElements.define("business-item", class extends Component {
super(` super(`
<style> <style>
:host { display: block; } :host { display: block; }
section { display: flex; justify-content: space-between; } section > form { display: flex; justify-content: space-between; }
#form { input[type=submit] {
display: none; max-width: 25%;
} }
${FORM_STYLE}
</style> </style>
<section> <section>
<image-input></image-input>
<div id="name"></div>
<price-input></price-input>
</section>
<section id="form">
<form action="/business-item/update" method="post"> <form action="/business-item/update" method="post">
<input name="id" id="id" /> <image-input></image-input>
<div>
<label>Nazwa</label>
<input name="name" id="name" /> <input name="name" id="name" />
<input name="price" id="price" /> </div>
<input name="item_order" id="item_order" /> <div>
<input name="picture_url" id="picture_url" /> <label>Cena</label>
<price-input></price-input>
</div>
<input type="hidden" name="id" id="id" />
<input type="hidden" name="price" id="price" />
<input type="hidden" name="item_order" id="item_order" />
<input type="hidden" name="picture_url" id="picture_url" />
<input type="submit" value="Zapisz" />
</form> </form>
</section> </section>
`); `);
@ -1582,7 +1605,7 @@ customElements.define("business-item", class extends Component {
return this.getAttribute("name"); return this.getAttribute("name");
} }
set name(a) { set name(a) {
this.setAttribute("name", a), this.shadowRoot.querySelector("#name").textContent = a; this.setAttribute("name", a), this.shadowRoot.querySelector("#name").value = a;
} }
get price() { get price() {
return this.shadowRoot.querySelector("price-input").value; return this.shadowRoot.querySelector("price-input").value;

View File

@ -1,5 +1,5 @@
import "../shared/image-input"; import "../shared/image-input";
import { Component } from "../shared"; import { Component, FORM_STYLE } from "../shared";
customElements.define('business-item', class extends Component { customElements.define('business-item', class extends Component {
static get observedAttributes() { static get observedAttributes() {
@ -10,23 +10,28 @@ customElements.define('business-item', class extends Component {
super(` super(`
<style> <style>
:host { display: block; } :host { display: block; }
section { display: flex; justify-content: space-between; } section > form { display: flex; justify-content: space-between; }
#form { input[type=submit] {
display: none; max-width: 25%;
} }
${ FORM_STYLE }
</style> </style>
<section> <section>
<image-input></image-input>
<div id="name"></div>
<price-input></price-input>
</section>
<section id="form">
<form action="/business-item/update" method="post"> <form action="/business-item/update" method="post">
<input name="id" id="id" /> <image-input></image-input>
<div>
<label>Nazwa</label>
<input name="name" id="name" /> <input name="name" id="name" />
<input name="price" id="price" /> </div>
<input name="item_order" id="item_order" /> <div>
<input name="picture_url" id="picture_url" /> <label>Cena</label>
<price-input></price-input>
</div>
<input type="hidden" name="id" id="id" />
<input type="hidden" name="price" id="price" />
<input type="hidden" name="item_order" id="item_order" />
<input type="hidden" name="picture_url" id="picture_url" />
<input type="submit" value="Zapisz" />
</form> </form>
</section> </section>
`); `);
@ -61,7 +66,8 @@ customElements.define('business-item', class extends Component {
if (oldV === newV) return; if (oldV === newV) return;
switch (name) { switch (name) {
case 'price': return this.price = newV / 100.0; case 'price':
return this.price = newV / 100.0;
} }
} }
@ -91,7 +97,7 @@ customElements.define('business-item', class extends Component {
set name(v) { set name(v) {
this.setAttribute('name', v); this.setAttribute('name', v);
this.shadowRoot.querySelector('#name').textContent = v; this.shadowRoot.querySelector('#name').value = v;
} }
get price() { get price() {

View File

@ -2,7 +2,7 @@ import { Component } from "../shared";
customElements.define('local-business-item', class extends Component { customElements.define('local-business-item', class extends Component {
static get observedAttributes() { static get observedAttributes() {
return ['name', 'price'] return ['name', 'price', 'picture-url']
} }
constructor() { constructor() {
@ -20,8 +20,13 @@ customElements.define('local-business-item', class extends Component {
#price { #price {
font-weight: bold; font-weight: bold;
} }
img {
width: 200px;
max-width: 200px;
}
</style> </style>
<section id="item"> <section id="item">
<img alt="" src="" />
<h3 id="name"></h3> <h3 id="name"></h3>
<price-view id="price"></price-view> <price-view id="price"></price-view>
</section> </section>
@ -29,8 +34,7 @@ customElements.define('local-business-item', class extends Component {
} }
connectedCallback() { connectedCallback() {
this.name = this.name; super.connectedCallback();
this.price = this.price;
} }
attributeChangedCallback(name, oldV, newV) { attributeChangedCallback(name, oldV, newV) {
@ -55,4 +59,13 @@ customElements.define('local-business-item', class extends Component {
this.setAttribute('name', v); this.setAttribute('name', v);
this.shadowRoot.querySelector('#name').textContent = v; this.shadowRoot.querySelector('#name').textContent = v;
} }
get picture_url() {
return this.getAttribute('picture-url')
}
set picture_url(v) {
this.setAttribute('picture-url', v);
if (v) this.shadowRoot.querySelector('img').src = v;
}
}); });

View File

@ -23,7 +23,7 @@ customElements.define('local-business', class extends Component {
} }
connectedCallback() { connectedCallback() {
this.name = this.name; super.connectedCallback();
} }
attributeChangedCallback(name, oldV, newV) { attributeChangedCallback(name, oldV, newV) {

View File

@ -119,6 +119,14 @@ export class Component extends HTMLElement {
} }
connectedCallback() { connectedCallback() {
const observed = this.constructor.observedAttributes;
if (!Array.isArray(observed))
return;
for (const name of observed) {
const field = this.constructor.attr2Field(name);
if (!field) continue;
this[field] = this[field];
}
} }
attributeChangedCallback(name, oldV, newV) { attributeChangedCallback(name, oldV, newV) {

View File

@ -36,7 +36,7 @@ customElements.define('image-input', class extends Component {
<canvas width="200" height="200"></canvas> <canvas width="200" height="200"></canvas>
</div> </div>
<div> <div>
<input id="save" type="button" value="Zapisz" /> <input id="save" type="button" value="Wyślij" />
</div> </div>
</article> </article>
`); `);

View File

@ -10,6 +10,7 @@ pub enum Page {
Register, Register,
Login, Login,
BusinessItems, BusinessItems,
Marketplace,
} }
impl Page { impl Page {
@ -44,6 +45,14 @@ impl Page {
"" ""
} }
} }
pub fn select_marketplace(&self) -> &str {
if matches!(self, Page::Marketplace) {
"selected"
} else {
""
}
}
} }
#[derive(Debug, Default, PartialEq, Serialize, Deserialize)] #[derive(Debug, Default, PartialEq, Serialize, Deserialize)]

View File

@ -44,13 +44,16 @@ async fn handle_business_items_page(pool: Arc<PgPool>, id: Identity) -> Result<H
let items: Vec<db::LocalBusinessItem> = sqlx::query_as( let items: Vec<db::LocalBusinessItem> = sqlx::query_as(
r#" r#"
SELECT SELECT
id, local_business_items.id,
local_business_id, local_business_items.local_business_id,
name, local_business_items.name,
price, local_business_items.price,
item_order, local_business_items.item_order,
picture_url local_business_items.picture_url
FROM local_business_items FROM local_business_items
INNER JOIN local_businesses
ON local_businesses.id = local_business_items.local_business_id
WHERE local_businesses.owner_id = $1
ORDER BY item_order DESC ORDER BY item_order DESC
"#, "#,
) )