More info
This commit is contained in:
parent
ee91354de8
commit
62d4e0c46a
@ -132,6 +132,7 @@ local-businesses local-business p {
|
||||
margin: 8px auto auto;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#home {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ if (!document.querySelector('#facebook-jssdk')) {
|
||||
xfbml: true,
|
||||
version: 'v14.0'
|
||||
});
|
||||
// FB.AppEvents.logPageView();
|
||||
FB.AppEvents.logPageView();
|
||||
fireFbReady();
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, FORM_STYLE } from "../shared";
|
||||
import { Component, FORM_STYLE, TIP } from "../shared";
|
||||
|
||||
customElements.define('offer-form', class extends Component {
|
||||
static get observedAttributes() {
|
||||
@ -9,11 +9,6 @@ customElements.define('offer-form', class extends Component {
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
.tip {
|
||||
font-size: 10px;
|
||||
font-style: italic;
|
||||
color: var(--border-slim-color)
|
||||
}
|
||||
#description {
|
||||
height: 200px;
|
||||
}
|
||||
@ -34,7 +29,7 @@ customElements.define('offer-form', class extends Component {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
${ FORM_STYLE }
|
||||
${ FORM_STYLE }${ TIP }
|
||||
</style>
|
||||
<section>
|
||||
<form action="/offers/create" method="post">
|
||||
@ -45,8 +40,11 @@ customElements.define('offer-form', class extends Component {
|
||||
</div>
|
||||
<div id="descriptionSection">
|
||||
<label for="description">Opis</label>
|
||||
<textarea name="description" id="description">
|
||||
</textarea>
|
||||
<textarea
|
||||
name="description"
|
||||
id="description"
|
||||
placeholder="Opisz przedmiot, który chcesz sprzedać"
|
||||
></textarea>
|
||||
</div>
|
||||
<div id="priceSection">
|
||||
<div>
|
||||
|
@ -2,7 +2,7 @@ import { Component, FORM_STYLE } from "../shared";
|
||||
|
||||
customElements.define('account-view', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['facebook-id', 'id', 'name', 'email']
|
||||
return ['facebook-id', 'id', 'name', 'email', 'register-success']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@ -21,6 +21,10 @@ customElements.define('account-view', class extends Component {
|
||||
display: flex;
|
||||
padding: .375rem .75rem;
|
||||
}
|
||||
#register-success { display: none; text-align: center; color: darkgreen; }
|
||||
:host([register-success]) #register-success {
|
||||
display: block;
|
||||
}
|
||||
#fb-button {
|
||||
display: none;
|
||||
}
|
||||
@ -29,6 +33,7 @@ customElements.define('account-view', class extends Component {
|
||||
}
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<h3 id="register-success">Konto utworzone!</h3>
|
||||
<div>
|
||||
<input id="id" name="id" readonly type="hidden" />
|
||||
</div>
|
||||
@ -61,6 +66,11 @@ customElements.define('account-view', class extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.register_success = (location.search || '').includes('success');
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.getAttribute('name') || '';
|
||||
}
|
||||
@ -87,4 +97,15 @@ customElements.define('account-view', class extends Component {
|
||||
this.setAttribute('facebook-id', v);
|
||||
this.shadowRoot.querySelector('#facebook_id').value = v;
|
||||
}
|
||||
|
||||
get register_success() {
|
||||
return this.getAttribute('register-success') === 'true'
|
||||
}
|
||||
|
||||
set register_success(v) {
|
||||
if (v === true || v === 'true')
|
||||
this.setAttribute('register-success', 'true');
|
||||
else
|
||||
this.removeAttribute('register-success');
|
||||
}
|
||||
});
|
||||
|
@ -22,6 +22,7 @@ customElements.define('register-basic-form', class extends PseudoForm {
|
||||
<label>Hasło</label>
|
||||
<input name="pass" placeholder="Hasło" type="password" required />
|
||||
</div>
|
||||
<input type="submit" style="display: none">
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`);
|
||||
@ -30,9 +31,10 @@ customElements.define('register-basic-form', class extends PseudoForm {
|
||||
form.addEventListener('submit', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.shadowRoot.querySelector('form-navigation').next();
|
||||
});
|
||||
this.shadowRoot.querySelector('form-navigation').addEventListener('form:next', ev => {
|
||||
|
||||
console.log(ev);
|
||||
if (form.reportValidity())
|
||||
this.shadowRoot.querySelector('form-navigation').next();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { FORM_STYLE, PseudoForm } from "../shared";
|
||||
import { FORM_STYLE, TIP, PseudoForm } from "../shared";
|
||||
|
||||
customElements.define('register-business-form', class extends PseudoForm {
|
||||
constructor() {
|
||||
@ -6,15 +6,18 @@ customElements.define('register-business-form', class extends PseudoForm {
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${ FORM_STYLE }
|
||||
textarea { min-height: 200px; }
|
||||
${ FORM_STYLE }${ TIP }
|
||||
</style>
|
||||
<form id="step-2">
|
||||
<div>
|
||||
<label>Nazwa usługodawcy</label>
|
||||
<input name="name" placeholder="Nazwa usługi" type="text" required autofocus />
|
||||
</div>
|
||||
<div>
|
||||
<label>description</label>
|
||||
<label>Opis usługodawcy</label>
|
||||
<textarea name="description" required></textarea>
|
||||
<div class="tip">Produkty dodawane są w nastepnym kroku</div>
|
||||
</div>
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
@ -26,4 +29,8 @@ customElements.define('register-business-form', class extends PseudoForm {
|
||||
this.shadowRoot.querySelector('form-navigation').next();
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
}
|
||||
})
|
||||
|
@ -30,6 +30,7 @@ customElements.define('register-items-form', class extends PseudoForm {
|
||||
<div>
|
||||
<input type="button" id="add-item" value="Dodaj usługę/produkt" />
|
||||
</div>
|
||||
<input type="submit" style="display: none" />
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`);
|
||||
@ -39,6 +40,7 @@ customElements.define('register-items-form', class extends PseudoForm {
|
||||
updateItems(this)
|
||||
});
|
||||
this.addEventListener('form:next', ev => {
|
||||
updateItems(this);
|
||||
for (const el of this.querySelectorAll('item-form-row')) {
|
||||
if (!el.reportValidity()) {
|
||||
ev.stopPropagation();
|
||||
@ -55,7 +57,7 @@ customElements.define('register-items-form', class extends PseudoForm {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.appendChild(document.createElement('register-item-form-row'));
|
||||
updateItems(this)
|
||||
updateItems(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ customElements.define('register-submit-form', class extends PseudoForm {
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${ FORM_STYLE }
|
||||
img[src=''] { display: none; }
|
||||
@media only screen and (min-device-width: 1200px) {
|
||||
.item-view {
|
||||
display: flex;
|
||||
@ -72,7 +73,10 @@ customElements.define('register-submit-form', class extends PseudoForm {
|
||||
const [name, price, img] = row;
|
||||
|
||||
el.innerHTML = `
|
||||
<img src="${img.value}" />
|
||||
${ img.value !== ''
|
||||
? `<img src="${img.value}" alt="" />`
|
||||
: `<span>Brak zdjęcia</span>`
|
||||
}
|
||||
<input type="text" name="${ name.name }" value="${ name.value }" readonly />
|
||||
<input type="hidden" name="${ price.name }" value="${ price.value }" readonly />
|
||||
<input type="hidden" name="${ img.name }" value="${ img.value }" readonly />
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, BUTTON_STYLE } from "../shared";
|
||||
import { Component, BUTTON_STYLE, TIP } from "../shared";
|
||||
|
||||
customElements.define('register-user-type', class extends Component {
|
||||
constructor() {
|
||||
@ -52,7 +52,7 @@ customElements.define('register-user-type', class extends Component {
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
${ BUTTON_STYLE }
|
||||
${ BUTTON_STYLE }${ TIP }
|
||||
</style>
|
||||
<article>
|
||||
<button id="accept-terms">
|
||||
@ -84,6 +84,7 @@ customElements.define('register-user-type', class extends Component {
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.5.875a3.625 3.625 0 0 0-1.006 7.109c-1.194.145-2.218.567-2.99 1.328-.982.967-1.479 2.408-1.479 4.288a.475.475 0 1 0 .95 0c0-1.72.453-2.88 1.196-3.612.744-.733 1.856-1.113 3.329-1.113s2.585.38 3.33 1.113c.742.733 1.195 1.892 1.195 3.612a.475.475 0 1 0 .95 0c0-1.88-.497-3.32-1.48-4.288-.77-.76-1.795-1.183-2.989-1.328A3.627 3.627 0 0 0 7.5.875ZM4.825 4.5a2.675 2.675 0 1 1 5.35 0 2.675 2.675 0 0 1-5.35 0Z" fill="currentColor"/>
|
||||
</svg>
|
||||
<div>Użytkownik</div>
|
||||
<div class="tip">Zwykły użytkownik z opcją wystawiania niepotrzebnych prywatnych rzeczy na sprzedaż</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
@ -93,6 +94,7 @@ customElements.define('register-user-type', class extends Component {
|
||||
<path d="M489.4 171.05c0-2.1-.5-4.1-1.6-5.9l-72.8-128c-2.1-3.7-6.1-6.1-10.4-6.1H84.7c-4.3 0-8.3 2.3-10.4 6.1l-72.7 128c-1 1.8-1.6 3.8-1.6 5.9 0 28.7 17.3 53.3 42 64.2v211.1c0 6.6 5.4 12 12 12h381.3c6.6 0 12-5.4 12-12v-209.6c0-.5 0-.9-.1-1.3 24.8-10.9 42.2-35.6 42.2-64.4zM91.7 55.15h305.9l56.9 100.1H34.9l56.8-100.1zm256.6 124c-3.8 21.6-22.7 38-45.4 38s-41.6-16.4-45.4-38h90.8zm-116.3 0c-3.8 21.6-22.7 38-45.4 38s-41.6-16.4-45.5-38H232zm-207.2 0h90.9c-3.8 21.6-22.8 38-45.5 38-22.7.1-41.6-16.4-45.4-38zm176.8 255.2h-69v-129.5c0-9.4 7.6-17.1 17.1-17.1h34.9c9.4 0 17.1 7.6 17.1 17.1v129.5h-.1zm221.7 0H225.6v-129.5c0-22.6-18.4-41.1-41.1-41.1h-34.9c-22.6 0-41.1 18.4-41.1 41.1v129.6H66v-193.3c1.4.1 2.8.1 4.2.1 24.2 0 45.6-12.3 58.2-31 12.6 18.7 34 31 58.2 31s45.5-12.3 58.2-31c12.6 18.7 34 31 58.1 31 24.2 0 45.5-12.3 58.1-31 12.6 18.7 34 31 58.2 31 1.4 0 2.7-.1 4.1-.1v193.2zm-4.1-217.1c-22.7 0-41.6-16.4-45.4-38h90.9c-3.9 21.5-22.8 38-45.5 38z"/>
|
||||
</svg>
|
||||
<div>Usługodawca</div>
|
||||
<div class="tip">Usługodawca posiadający stałe usłuugi lub produkty w ofercie</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -115,6 +115,7 @@ label {
|
||||
${ INPUT_STYLE }
|
||||
${ BUTTON_STYLE }
|
||||
`;
|
||||
export const TIP = `.tip { text-align: center; font-style: italic; font-size: 10px; color: var(--border-slim-color); }`;
|
||||
|
||||
export class Component extends HTMLElement {
|
||||
#shadow;
|
||||
|
@ -18,6 +18,12 @@ customElements.define('image-input', class extends Component {
|
||||
#hidden { overflow: hidden; width: 1px; height: 1px; position: relative; }
|
||||
input[type=file] { position: absolute; top: -10px; left: -10px; display: none; }
|
||||
#view { width: 200px; height: 200px; cursor: pointer; }
|
||||
#view > span {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-top: 8px;
|
||||
color: var(--border-slim-color)
|
||||
}
|
||||
div > input[type=button] {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
@ -40,8 +46,9 @@ customElements.define('image-input', class extends Component {
|
||||
<input id="file" type="file" accept="image/*" />
|
||||
</section>
|
||||
<div id="view">
|
||||
Kliknij żeby przesłać zdjęcie (opcjonalne)
|
||||
</div>
|
||||
<div>
|
||||
<div style="display: none;">
|
||||
<input id="save" type="button" value="Wyślij" />
|
||||
</div>
|
||||
</article>
|
||||
@ -56,10 +63,13 @@ customElements.define('image-input', class extends Component {
|
||||
const input = this.shadowRoot.querySelector('#file');
|
||||
const view = this.shadowRoot.querySelector('#view');
|
||||
|
||||
const toFile = (canvas) =>
|
||||
canvas.toBlob((blob) => {
|
||||
this.#file = new File([blob], `${ crypto.randomUUID() }.webp`, { type: blob.type });
|
||||
}, 'image/webp');
|
||||
const toFile = (canvas) => new Promise((resolve) => {
|
||||
canvas.toBlob(async (blob) => {
|
||||
this.#file = new File([blob], `${ crypto.randomUUID() }.webp`, { type: blob.type });
|
||||
resolve();
|
||||
await this.#sendFile(this.#file); // TODO: Send on form submit
|
||||
}, 'image/webp');
|
||||
})
|
||||
|
||||
input.addEventListener('change', ev => {
|
||||
ev.stopPropagation();
|
||||
@ -69,7 +79,7 @@ customElements.define('image-input', class extends Component {
|
||||
let maxWidth = this.width;
|
||||
let maxHeight = this.height;
|
||||
|
||||
image.onload = () => {
|
||||
image.onload = async () => {
|
||||
if (this.send_original) {
|
||||
maxWidth = maxWidth < image.naturalWidth ? maxWidth : image.naturalWidth;
|
||||
maxHeight = maxHeight < image.naturalHeight ? maxHeight : image.naturalHeight;
|
||||
@ -84,19 +94,17 @@ customElements.define('image-input', class extends Component {
|
||||
|
||||
canvas.width = image.width = width;
|
||||
canvas.height = image.height = height;
|
||||
if (this.send_original) {
|
||||
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
|
||||
} else {
|
||||
canvas.getContext('2d').drawImage(image, 0, 0);
|
||||
}
|
||||
toFile(canvas);
|
||||
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
|
||||
|
||||
await toFile(canvas);
|
||||
|
||||
image.width = width > image ? 200 : (width * 200) / height;
|
||||
image.height = width > image ? (width * 200) / height : 200;
|
||||
view.appendChild(image);
|
||||
};
|
||||
|
||||
image.src = URL.createObjectURL(input.files[0]);
|
||||
view.innerHTML = '';
|
||||
view.appendChild(image);
|
||||
});
|
||||
|
||||
view.addEventListener('click', ev => {
|
||||
@ -149,7 +157,11 @@ customElements.define('image-input', class extends Component {
|
||||
if (!(v || '').startsWith("/")) v = '';
|
||||
this.setAttribute('url', v);
|
||||
const view = this.shadowRoot.querySelector('#view');
|
||||
view.innerHTML = `<img src="${ v }" alt=""/>`;
|
||||
if (v === '') {
|
||||
view.innerHTML = '<span>Kliknij żeby przesłać zdjęcie (opcjonalne)</span>';
|
||||
} else {
|
||||
view.innerHTML = `<img src="${ v }" alt=""/>`;
|
||||
}
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
{% extends "../base.html" %}
|
||||
{% block content %}
|
||||
<h2 style="text-align: center">Lokalne usługi</h2>
|
||||
<local-business-list>
|
||||
{% for business in businesses %}
|
||||
<local-business
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "../base.html" %}
|
||||
{% block content %}
|
||||
<marketplace-offers>
|
||||
<h1>Rzeczy wystawione na sprzedaż</h1>
|
||||
<h2 style="text-align: center">Rzeczy wystawione na sprzedaż</h2>
|
||||
|
||||
{% for offer in offers %}
|
||||
<marketplace-offer
|
||||
|
@ -48,7 +48,9 @@
|
||||
</svg>
|
||||
<div>Moje usługi</div>
|
||||
</ow-path>
|
||||
{%- endif %}
|
||||
|
||||
{% if account.is_some() -%}
|
||||
<ow-path path="/account/offers" selected="{{ page.select_account_offers() }}" title="Moje sprzedaże">
|
||||
<svg viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "../base.html" %}
|
||||
{% block content %}
|
||||
<marketplace-offers>
|
||||
<h1>Sprzedaż niepotrzebnych rzeczy</h1>
|
||||
<h2>Sprzedaż niepotrzebnych rzeczy</h2>
|
||||
|
||||
<offer-form></offer-form>
|
||||
{% for offer in offers %}
|
||||
|
@ -204,7 +204,7 @@ RETURNING id, local_business_id, name, price, item_order, picture_url
|
||||
t.commit().await.unwrap();
|
||||
|
||||
Ok(HttpResponse::SeeOther()
|
||||
.append_header(("Location", "/"))
|
||||
.append_header(("Location", "/account?success"))
|
||||
.body(
|
||||
AccountTemplate {
|
||||
account: Some(account),
|
||||
|
@ -1,64 +1 @@
|
||||
use stdweb::web::HtmlElement;
|
||||
use stdweb::*;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
pub trait Component {
|
||||
fn tag_name() -> String;
|
||||
|
||||
fn create(el: HtmlElement) -> Self;
|
||||
|
||||
fn created(&mut self) {}
|
||||
|
||||
fn connected_callback(&self) {}
|
||||
|
||||
fn disconnected_callback(&mut self) {}
|
||||
|
||||
fn attribute_changed(
|
||||
&mut self,
|
||||
_name: String,
|
||||
_old_value: Option<String>,
|
||||
_new_value: Option<String>,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FooElement {
|
||||
el: HtmlElement,
|
||||
}
|
||||
|
||||
impl Component for FooElement {
|
||||
fn tag_name() -> String {
|
||||
"foo-element".into()
|
||||
}
|
||||
|
||||
fn create(el: HtmlElement) -> Self {
|
||||
Self { el }
|
||||
}
|
||||
|
||||
fn connected_callback(&self) {}
|
||||
}
|
||||
|
||||
pub struct BarElement {
|
||||
el: HtmlElement,
|
||||
}
|
||||
|
||||
impl Component for BarElement {
|
||||
fn tag_name() -> String {
|
||||
"bar-element".into()
|
||||
}
|
||||
|
||||
fn create(el: HtmlElement) -> Self {
|
||||
Self { el }
|
||||
}
|
||||
|
||||
fn connected_callback(&self) {}
|
||||
}
|
||||
|
||||
pub fn define() {
|
||||
let tag_name = BarElement::tag_name();
|
||||
js! {
|
||||
customerElemenets.define(@{tag_name}, class extends HTMLElement {});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user