Better facebook button. Split account view.
This commit is contained in:
parent
ad20d85012
commit
d7f3f1c7f9
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ uploads
|
||||
client/dist
|
||||
client/dist/app.js.map
|
||||
client/dist/app.js
|
||||
!/client/dist/
|
||||
|
@ -10,6 +10,8 @@
|
||||
facebook-id="{{a.facebook_id.as_deref().unwrap_or_default()}}"
|
||||
></ow-account>
|
||||
{% when None %}
|
||||
<ow-account></ow-account>
|
||||
<ow-account
|
||||
mode="form"
|
||||
></ow-account>
|
||||
{% endmatch %}
|
||||
{% endblock %}
|
||||
|
813
client/dist/app.js
vendored
813
client/dist/app.js
vendored
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,13 @@
|
||||
import "./business-items/business-item";
|
||||
import { Component } from "./shared";
|
||||
|
||||
customElements.define('business-items', class extends HTMLElement {
|
||||
#form;
|
||||
|
||||
customElements.define('business-items', class extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
</style>
|
||||
<slot></slot>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
@ -1,18 +1,13 @@
|
||||
import "../shared/image-input";
|
||||
import { Component } from "../shared";
|
||||
|
||||
customElements.define('business-item', class extends HTMLElement {
|
||||
#form;
|
||||
|
||||
customElements.define('business-item', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['item-id', 'name', 'price', 'picture-url', 'item-order']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
section { display: flex; justify-content: space-between; }
|
||||
@ -34,9 +29,9 @@ customElements.define('business-item', class extends HTMLElement {
|
||||
<input name="picture_url" id="picture_url" />
|
||||
</form>
|
||||
</section>
|
||||
`;
|
||||
`);
|
||||
|
||||
const imageInput = shadow.querySelector('image-input');
|
||||
const imageInput = this.shadowRoot.querySelector('image-input');
|
||||
|
||||
this.addEventListener('image-input:uploaded', ev => {
|
||||
ev.preventDefault();
|
||||
@ -44,7 +39,7 @@ customElements.define('business-item', class extends HTMLElement {
|
||||
|
||||
this.picture_url = imageInput.url;
|
||||
|
||||
const form = shadow.querySelector('form');
|
||||
const form = this.shadowRoot.querySelector('form');
|
||||
form.querySelector('#id').value = this.item_id;
|
||||
form.querySelector('#name').value = this.name;
|
||||
form.querySelector('#price').value = this.price;
|
||||
@ -62,15 +57,18 @@ customElements.define('business-item', class extends HTMLElement {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'item-id': return this.item_id = newV;
|
||||
case 'name': return this.name = newV;
|
||||
case 'price': return this.price = newV / 100.0;
|
||||
case 'picture-url': return this.picture_url = newV;
|
||||
}
|
||||
}
|
||||
|
||||
static get attr2FieldBlacklist() {
|
||||
return ['price'];
|
||||
}
|
||||
|
||||
get item_id() {
|
||||
return this.getAttribute('item-id');
|
||||
}
|
||||
@ -93,16 +91,16 @@ customElements.define('business-item', class extends HTMLElement {
|
||||
|
||||
set name(v) {
|
||||
this.setAttribute('name', v);
|
||||
this.#form.querySelector('#name').textContent = v;
|
||||
this.shadowRoot.querySelector('#name').textContent = v;
|
||||
}
|
||||
|
||||
get price() {
|
||||
return this.#form.querySelector('price-input').value;
|
||||
return this.shadowRoot.querySelector('price-input').value;
|
||||
}
|
||||
|
||||
set price(v) {
|
||||
this.setAttribute('price', v);
|
||||
this.#form.querySelector('price-input').value = v;
|
||||
this.shadowRoot.querySelector('price-input').value = v;
|
||||
}
|
||||
|
||||
get picture_url() {
|
||||
@ -111,6 +109,6 @@ customElements.define('business-item', class extends HTMLElement {
|
||||
|
||||
set picture_url(v) {
|
||||
this.setAttribute('picture-url', v);
|
||||
this.#form.querySelector('image-input').url = v;
|
||||
this.shadowRoot.querySelector('image-input').url = v;
|
||||
}
|
||||
});
|
||||
|
@ -1,17 +1,12 @@
|
||||
import { FORM_STYLE } from "./shared";
|
||||
|
||||
customElements.define('form-navigation', class extends HTMLElement {
|
||||
#form;
|
||||
import { FORM_STYLE, Component } from "./shared";
|
||||
|
||||
customElements.define('form-navigation', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['next', 'prev']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -33,13 +28,14 @@ customElements.define('form-navigation', class extends HTMLElement {
|
||||
<input id="next" type="submit" value="Następny" />
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
shadow.querySelector('#prev').addEventListener('click', ev => {
|
||||
`);
|
||||
|
||||
this.shadowRoot.querySelector('#prev').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.prev();
|
||||
});
|
||||
shadow.querySelector('#next').addEventListener('click', ev => {
|
||||
this.shadowRoot.querySelector('#next').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.next();
|
||||
@ -50,11 +46,11 @@ customElements.define('form-navigation', class extends HTMLElement {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'next': {
|
||||
this.#form.querySelector('#next').className = newV === 'hidden' ? 'hidden' : '';
|
||||
this.shadowRoot.querySelector('#next').className = newV === 'hidden' ? 'hidden' : '';
|
||||
break;
|
||||
}
|
||||
case 'prev': {
|
||||
this.#form.querySelector('#prev').className = newV === 'hidden' ? 'hidden' : '';
|
||||
this.shadowRoot.querySelector('#prev').className = newV === 'hidden' ? 'hidden' : '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,18 @@
|
||||
import "./local-businesses/local-business-item";
|
||||
import "./local-businesses/local-business";
|
||||
import { Component } from "./shared";
|
||||
|
||||
customElements.define('local-businesses', class extends HTMLElement {
|
||||
#form;
|
||||
|
||||
customElements.define('local-businesses', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['filter']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
::slotted(local-service[local-services-visible="invisible"]) {
|
||||
::slotted(local-service[local-business-visible="invisible"]) {
|
||||
display: none;
|
||||
}
|
||||
input {
|
||||
@ -39,9 +36,9 @@ customElements.define('local-businesses', class extends HTMLElement {
|
||||
<section id="items">
|
||||
<slot name="services"></slot>
|
||||
</section>
|
||||
`;
|
||||
`);
|
||||
{
|
||||
const filter = shadow.querySelector('#filter');
|
||||
const filter = this.shadowRoot.querySelector('#filter');
|
||||
let t = null;
|
||||
filter.addEventListener('change', ev => {
|
||||
ev.stopPropagation();
|
||||
@ -65,11 +62,7 @@ customElements.define('local-businesses', class extends HTMLElement {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'filter':
|
||||
return this.filter = newV;
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
get filter() {
|
||||
@ -79,17 +72,17 @@ customElements.define('local-businesses', class extends HTMLElement {
|
||||
set filter(value) {
|
||||
if (!value || value === '') {
|
||||
this.removeAttribute('filter');
|
||||
for (const el of this.querySelectorAll('local-service')) {
|
||||
el.removeAttribute('local-services-visible');
|
||||
for (const el of this.querySelectorAll('local-business')) {
|
||||
el.removeAttribute('local-business-visible');
|
||||
}
|
||||
} else {
|
||||
this.setAttribute('filter', value);
|
||||
for (const el of this.querySelectorAll('local-service')) {
|
||||
for (const el of this.querySelectorAll('local-business')) {
|
||||
if (!el.name) continue;
|
||||
if (el.name.includes(value)) {
|
||||
el.setAttribute('local-services-visible', 'visible');
|
||||
el.setAttribute('local-business-visible', 'visible');
|
||||
} else {
|
||||
el.setAttribute('local-services-visible', 'invisible');
|
||||
el.setAttribute('local-business-visible', 'invisible');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,12 @@
|
||||
customElements.define('local-business-item', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component } from "../shared";
|
||||
|
||||
customElements.define('local-business-item', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['name', 'price']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -27,26 +25,34 @@ customElements.define('local-business-item', class extends HTMLElement {
|
||||
<h3 id="name"></h3>
|
||||
<price-view id="price"></price-view>
|
||||
</section>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.#form.querySelector('#name').textContent = this.getAttribute('name');
|
||||
this.#form.querySelector('#price').value = this.price();
|
||||
this.name = this.name;
|
||||
this.price = this.price;
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'name':
|
||||
return this.#form.querySelector('#name').textContent = newV;
|
||||
case 'price':
|
||||
return this.#form.querySelector('#price').value = newV;
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
price(s) {
|
||||
const n = parseInt(s || this.getAttribute('price'));
|
||||
get price() {
|
||||
const n = parseInt(this.getAttribute('price'));
|
||||
return isNaN(n) ? 0 : n;
|
||||
}
|
||||
|
||||
set price(v) {
|
||||
this.setAttribute('price', v);
|
||||
this.shadowRoot.querySelector('#price').value = v;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.getAttribute('name');
|
||||
}
|
||||
|
||||
set name(v) {
|
||||
this.setAttribute('name', v);
|
||||
this.shadowRoot.querySelector('#name').textContent = v;
|
||||
}
|
||||
});
|
||||
|
@ -1,16 +1,12 @@
|
||||
import { S } from "../shared";
|
||||
|
||||
customElements.define('local-business', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component, S } from "../shared";
|
||||
|
||||
customElements.define('local-business', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['name', 'service-id', 'state']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -23,22 +19,39 @@ customElements.define('local-business', class extends HTMLElement {
|
||||
<section id="items">
|
||||
<slot name="item"></slot>
|
||||
</section>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.#form.querySelector('#name').textContent = this.getAttribute('name');
|
||||
this.name = this.name;
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'name':
|
||||
return this.#form.querySelector('#name').textContent = newV;
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.getAttribute('name') || ''
|
||||
}
|
||||
|
||||
set name(v) {
|
||||
this.setAttribute('name', v);
|
||||
this.shadowRoot.querySelector('#name').textContent = v;
|
||||
}
|
||||
|
||||
get state() {
|
||||
return this.getAttribute('state');
|
||||
}
|
||||
|
||||
set state(v) {
|
||||
this.setAttribute('state', v);
|
||||
}
|
||||
|
||||
get service_id() {
|
||||
return this.getAttribute('service-id');
|
||||
}
|
||||
|
||||
set service_id(v) {
|
||||
this.setAttribute('service-id', v);
|
||||
}
|
||||
});
|
||||
|
@ -1,16 +1,8 @@
|
||||
import { FORM_STYLE, S } from "./shared";
|
||||
|
||||
customElements.define('login-form', class extends HTMLElement {
|
||||
#form;
|
||||
|
||||
static get observedAttributes() {
|
||||
return []
|
||||
}
|
||||
import { Component, FORM_STYLE } from "./shared";
|
||||
|
||||
customElements.define('login-form', class extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -29,15 +21,6 @@ customElements.define('login-form', class extends HTMLElement {
|
||||
<input type="button" value="Zaloguj" />
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
}
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
@ -1,10 +1,8 @@
|
||||
customElements.define('ow-nav', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component } from "../shared";
|
||||
|
||||
customElements.define('ow-nav', class extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -35,6 +33,6 @@ customElements.define('ow-nav', class extends HTMLElement {
|
||||
<section>
|
||||
<slot></slot>
|
||||
</section>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
@ -1,14 +1,12 @@
|
||||
customElements.define('ow-path', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component } from "../shared";
|
||||
|
||||
customElements.define('ow-path', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['selected', 'path'];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -30,7 +28,7 @@ customElements.define('ow-path', class extends HTMLElement {
|
||||
}
|
||||
</style>
|
||||
<a><slot></slot></a>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
@ -38,13 +36,7 @@ customElements.define('ow-path', class extends HTMLElement {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'selected':
|
||||
return this.selected = newV;
|
||||
case 'path':
|
||||
return this.path = newV;
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
get selected() {
|
||||
@ -66,6 +58,6 @@ customElements.define('ow-path', class extends HTMLElement {
|
||||
return;
|
||||
}
|
||||
this.setAttribute('path', value);
|
||||
this.#form.querySelector('a').setAttribute('href', value);
|
||||
this.shadowRoot.querySelector('a').setAttribute('href', value);
|
||||
}
|
||||
});
|
||||
|
@ -1,16 +1,14 @@
|
||||
import { FORM_STYLE } from "./shared";
|
||||
|
||||
customElements.define('ow-account', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component, FORM_STYLE } from "./shared";
|
||||
import './shared/facebook-button';
|
||||
import './ow-account/account-view';
|
||||
|
||||
customElements.define('ow-account', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['mode', "id", "name", 'email', "facebook-id"]
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -23,15 +21,15 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
:host([mode="register"]) #form > register-form, :host([mode="register"]) #switch-login {
|
||||
display: block !important;
|
||||
}
|
||||
#display {
|
||||
account-view {
|
||||
display: none;
|
||||
}
|
||||
:host([mode="display"]) #display { display: block; }
|
||||
:host([mode="display"]) account-view { display: block; }
|
||||
:host([mode="display"]) #form { display: none; }
|
||||
:host([mode="form"]) #form,
|
||||
:host([mode="login"]) #form { display: block; }
|
||||
|
||||
a{
|
||||
a {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -41,7 +39,7 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
${FORM_STYLE}
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<article id="form">
|
||||
<login-form></login-form>
|
||||
@ -53,65 +51,43 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
<a>Masz konta? Zaloguj się</a>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<article id="display">
|
||||
<div>
|
||||
<input id="id" name="id" readonly type="hidden" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Login</label>
|
||||
<input id="name" name="name" readonly />
|
||||
</div>
|
||||
<div>
|
||||
<label>E-Mail</label>
|
||||
<input id="email" name="email" readonly />
|
||||
</div>
|
||||
<div>
|
||||
<label>Powiązane konto Facebook</label>
|
||||
<input id="facebook_id" name="facebook_id" readonly />
|
||||
</div>
|
||||
</article>
|
||||
`;
|
||||
shadow.querySelector('#switch-login > a').addEventListener('click', ev => {
|
||||
<account-view></account-view>
|
||||
`);
|
||||
|
||||
this.shadowRoot.querySelector('#switch-login > a').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.mode = 'login';
|
||||
});
|
||||
shadow.querySelector('#switch-register > a').addEventListener('click', ev => {
|
||||
this.shadowRoot.querySelector('#switch-register > a').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.mode = 'register';
|
||||
});
|
||||
this.addEventListener('facebook:account', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.mode = 'facebook';
|
||||
|
||||
const { id, name, email } = ev.details;
|
||||
console.info({ id, name, email })
|
||||
// form.querySelector('#email').value = email;
|
||||
// form.querySelector('#login').value = name;
|
||||
// form.querySelector('#password').value = crypto.randomUUID();
|
||||
// form.querySelector('#facebook_id').value = id;
|
||||
// form.submit();
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.mode === '') this.mode = 'login';
|
||||
this.name = this.name;
|
||||
this.email = this.email;
|
||||
this.facebook_id = this.facebook_id;
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'mode': {
|
||||
this.mode = newV;
|
||||
break;
|
||||
}
|
||||
case 'id': {
|
||||
this.id = newV;
|
||||
break;
|
||||
}
|
||||
case 'name': {
|
||||
this.name = newV;
|
||||
break;
|
||||
}
|
||||
case 'email': {
|
||||
this.email = newV;
|
||||
break;
|
||||
}
|
||||
case 'facebook-id': {
|
||||
this.facebook_id = newV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
get mode() {
|
||||
@ -129,7 +105,7 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
|
||||
set name(v) {
|
||||
this.setAttribute('name', v);
|
||||
this.#form.querySelector('#display #name').value = v;
|
||||
this.shadowRoot.querySelector('account-view').name = v;
|
||||
}
|
||||
|
||||
get email() {
|
||||
@ -138,7 +114,7 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
|
||||
set email(v) {
|
||||
this.setAttribute('email', v);
|
||||
this.#form.querySelector('#display #email').value = v;
|
||||
this.shadowRoot.querySelector('account-view').email = v;
|
||||
}
|
||||
|
||||
get facebook_id() {
|
||||
@ -147,6 +123,6 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
|
||||
set facebook_id(v) {
|
||||
this.setAttribute('facebook-id', v);
|
||||
this.#form.querySelector('#display #facebook_id').value = v;
|
||||
this.shadowRoot.querySelector('account-view').facebook_id = v;
|
||||
}
|
||||
});
|
||||
|
85
client/src/ow-account/account-view.js
Normal file
85
client/src/ow-account/account-view.js
Normal file
@ -0,0 +1,85 @@
|
||||
import { Component, FORM_STYLE } from "../shared";
|
||||
|
||||
customElements.define('account-view', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['facebook-id', 'id', 'name', 'email']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super(`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
:host(:not([facebook-id = ""])) #fb-id {
|
||||
display: block;
|
||||
}
|
||||
:host([facebook-id = ""]) #fb-id {
|
||||
display: none;
|
||||
}
|
||||
:host([facebook-id = ""]) #fb-button {
|
||||
display: flex;
|
||||
padding: .375rem .75rem;
|
||||
}
|
||||
#fb-button {
|
||||
display: none;
|
||||
}
|
||||
facebook-button {
|
||||
margin-right: 16px;
|
||||
}
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<div>
|
||||
<input id="id" name="id" readonly type="hidden" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Login</label>
|
||||
<input id="name" name="name" readonly />
|
||||
</div>
|
||||
<div>
|
||||
<label>E-Mail</label>
|
||||
<input id="email" name="email" readonly />
|
||||
</div>
|
||||
<div id="fb-button">
|
||||
<facebook-button width="100">
|
||||
<p>Powiąż z kontem Facebook</p>
|
||||
</facebook-button>
|
||||
</div>
|
||||
<div id="fb-id">
|
||||
<label>Powiązane konto Facebook</label>
|
||||
<input id="facebook_id" name="facebook_id" readonly />
|
||||
</div>
|
||||
`);
|
||||
this.addEventListener('facebook:available', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.getAttribute('name') || '';
|
||||
}
|
||||
|
||||
set name(v) {
|
||||
this.setAttribute('name', v);
|
||||
this.shadowRoot.querySelector('#name').value = v;
|
||||
}
|
||||
|
||||
get email() {
|
||||
return this.getAttribute('email') || '';
|
||||
}
|
||||
|
||||
set email(v) {
|
||||
this.setAttribute('email', v);
|
||||
this.shadowRoot.querySelector('#email').value = v;
|
||||
}
|
||||
|
||||
get facebook_id() {
|
||||
return this.getAttribute('facebook-id');
|
||||
}
|
||||
|
||||
set facebook_id(v) {
|
||||
this.setAttribute('facebook-id', v);
|
||||
this.shadowRoot.querySelector('#facebook_id').value = v;
|
||||
}
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
import { S, FORM_STYLE } from "./shared";
|
||||
import { S, FORM_STYLE, Component } from "./shared";
|
||||
|
||||
import "./register-form/register-basic-form";
|
||||
import "./register-form/register-item-form-row.js";
|
||||
@ -8,15 +8,13 @@ import "./register-form/register-submit-form";
|
||||
import "./register-form/register-user-type";
|
||||
import "./register-form/register-user-form";
|
||||
|
||||
customElements.define('register-form', class extends HTMLElement {
|
||||
customElements.define('register-form', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['step']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this[S] = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -54,27 +52,26 @@ customElements.define('register-form', class extends HTMLElement {
|
||||
<register-submit-form id="step-4"></register-submit-form>
|
||||
<register-user-form id="step-40"></register-user-form>
|
||||
</article>
|
||||
`;
|
||||
|
||||
const finalForm = shadow.querySelector('#step-4');
|
||||
this[S].addEventListener('account:type:user', ev => {
|
||||
`);
|
||||
const finalForm = this.shadowRoot.querySelector('#step-4');
|
||||
this.shadowRoot.addEventListener('account:type:user', ev => {
|
||||
ev.stopPropagation();
|
||||
finalForm.accountType = 'User';
|
||||
this.step = 40;
|
||||
});
|
||||
this[S].addEventListener('account:type:local-service', ev => {
|
||||
this.shadowRoot.addEventListener('account:type:local-service', ev => {
|
||||
ev.stopPropagation();
|
||||
finalForm.accountType = 'Business';
|
||||
this.step = 1;
|
||||
});
|
||||
this[S].addEventListener('form:next', ev => {
|
||||
this.shadowRoot.addEventListener('form:next', ev => {
|
||||
ev.stopPropagation();
|
||||
const form = shadow.querySelector(`#step-${ this.step }`);
|
||||
const form = this.shadowRoot.querySelector(`#step-${ this.step }`);
|
||||
if (this.#copyForm(form, finalForm)) {
|
||||
this.step = this.step + 1;
|
||||
}
|
||||
});
|
||||
this[S].addEventListener('form:prev', ev => {
|
||||
this.shadowRoot.addEventListener('form:prev', ev => {
|
||||
ev.stopPropagation();
|
||||
this.step = this.step - 1;
|
||||
});
|
||||
@ -89,9 +86,7 @@ customElements.define('register-form', class extends HTMLElement {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
get step() {
|
||||
|
@ -1,14 +1,8 @@
|
||||
import { FORM_STYLE, PseudoForm } from "../shared";
|
||||
|
||||
customElements.define('register-basic-form', class extends PseudoForm {
|
||||
#form;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -30,13 +24,13 @@ customElements.define('register-basic-form', class extends PseudoForm {
|
||||
</div>
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`;
|
||||
`);
|
||||
|
||||
const form = shadow.querySelector('form');
|
||||
const form = this.shadowRoot.querySelector('form');
|
||||
form.addEventListener('submit', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
shadow.querySelector('form-navigation').next();
|
||||
this.shadowRoot.querySelector('form-navigation').next();
|
||||
})
|
||||
}
|
||||
});
|
||||
|
@ -1,18 +1,12 @@
|
||||
import { FORM_STYLE, PseudoForm } from "../shared";
|
||||
|
||||
customElements.define('register-business-form', class extends PseudoForm {
|
||||
#form;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({mode: "closed"});
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${FORM_STYLE}
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<form id="step-2">
|
||||
<div>
|
||||
@ -24,12 +18,12 @@ customElements.define('register-business-form', class extends PseudoForm {
|
||||
</div>
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`;
|
||||
`);
|
||||
|
||||
shadow.querySelector('form').addEventListener('submit', ev => {
|
||||
this.shadowRoot.querySelector('form').addEventListener('submit', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
shadow.querySelector('form-navigation').next();
|
||||
this.shadowRoot.querySelector('form-navigation').next();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -1,15 +1,56 @@
|
||||
import { FORM_STYLE, PseudoForm } from "../shared";
|
||||
|
||||
customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
#form;
|
||||
const htmlContent = (idx) => {
|
||||
return `
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
#fields > *:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
#fields > div > label {
|
||||
margin-right: 16px;
|
||||
}
|
||||
#fields {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<form class="inline">
|
||||
<div id="fields">
|
||||
<image-input></image-input>
|
||||
<input type="hidden" name="picture_url" id="picture_url" />
|
||||
<div id="name" class="field">
|
||||
<label>Nazwa</label>
|
||||
<input class="item-name" name="items[${ idx }][name]" type="text" required>
|
||||
</div>
|
||||
<div id="price" class="field">
|
||||
<label>Cena</label>
|
||||
<price-input class="item-price" name="items[${ idx }][price]" required>
|
||||
</price-input>
|
||||
</div>
|
||||
</div>
|
||||
<div><input class="remove" type="button" value="Usuń"></div>
|
||||
</form>
|
||||
`;
|
||||
}
|
||||
|
||||
customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
static get observedAttributes() {
|
||||
return ['idx', 'name']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#form = this.attachShadow({ mode: 'closed' });
|
||||
super(htmlContent());
|
||||
|
||||
this.addEventListener('item:removed', () => {
|
||||
this.setAttribute('removed', 'removed');
|
||||
@ -20,62 +61,20 @@ customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const idx = this.idx;
|
||||
|
||||
this.#form.innerHTML = `
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
#fields > *:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
#fields > div > label {
|
||||
margin-right: 16px;
|
||||
}
|
||||
#fields {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<form class="inline">
|
||||
<div id="fields">
|
||||
<image-input></image-input>
|
||||
<input type="hidden" name="picture_url" id="picture_url" />
|
||||
<div id="name" class="field">
|
||||
<label>Nazwa</label>
|
||||
<input class="item-name" name="items[${ idx }][name]" type="text" required>
|
||||
</div>
|
||||
<div id="price" class="field">
|
||||
<label>Cena</label>
|
||||
<price-input class="item-price" name="items[${ idx }][price]" required>
|
||||
</price-input>
|
||||
</div>
|
||||
</div>
|
||||
<div><input class="remove" type="button" value="Usuń"></div>
|
||||
</form>
|
||||
`;
|
||||
const imageInput = this.#form.querySelector('image-input');
|
||||
this.shadowRoot.innerHTML = htmlContent(this.idx);
|
||||
const imageInput = this.shadowRoot.querySelector('image-input');
|
||||
|
||||
this.addEventListener('image-input:uploaded', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.picture_url = imageInput.url;
|
||||
});
|
||||
this.#form.querySelector('form').addEventListener('submit', ev => {
|
||||
this.shadowRoot.querySelector('form').addEventListener('submit', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.reportValidity();
|
||||
});
|
||||
this.#form.querySelector('.remove').addEventListener('click', ev => {
|
||||
this.shadowRoot.querySelector('.remove').addEventListener('click', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.dispatchEvent(new CustomEvent('item:removed', { bubbles: true, composed: false }));
|
||||
@ -85,21 +84,23 @@ customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'idx':return this.updateNames();
|
||||
case 'picture-url': return this.picture_url = newV;
|
||||
case 'idx':
|
||||
return this.updateNames();
|
||||
case 'picture-url':
|
||||
return this.picture_url = newV;
|
||||
}
|
||||
}
|
||||
|
||||
get inputs() {
|
||||
return [
|
||||
extract(this.#form.querySelector('.item-name')),
|
||||
extract(this.#form.querySelector('.item-price')),
|
||||
extract(this.shadowRoot.querySelector('.item-name')),
|
||||
extract(this.shadowRoot.querySelector('.item-price')),
|
||||
];
|
||||
}
|
||||
|
||||
updateNames() {
|
||||
const idx = this.getAttribute('idx');
|
||||
for (const el of this.#form.querySelectorAll('.field')) {
|
||||
for (const el of this.shadowRoot.querySelectorAll('.field')) {
|
||||
const id = el.id;
|
||||
el.querySelector('input, price-input').setAttribute('name', `items[${ idx }][${ id }]`);
|
||||
}
|
||||
@ -119,12 +120,12 @@ customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
|
||||
set picture_url(v) {
|
||||
this.setAttribute('picture-url', v);
|
||||
this.#form.querySelector('image-input').url = v;
|
||||
this.#form.querySelector('#picture_url').value = v;
|
||||
this.shadowRoot.querySelector('image-input').url = v;
|
||||
this.shadowRoot.querySelector('#picture_url').value = v;
|
||||
}
|
||||
|
||||
reportValidity() {
|
||||
return super.reportValidity() && this.#form.querySelector('price-input').reportValidity();
|
||||
return super.reportValidity() && this.shadowRoot.querySelector('price-input').reportValidity();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -11,24 +11,17 @@ const updateItems = (form) => {
|
||||
}
|
||||
|
||||
customElements.define('register-items-form', class extends PseudoForm {
|
||||
#form;
|
||||
|
||||
static get observedAttributes() {
|
||||
return []
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const shadow = this.#form = this.attachShadow({ mode: 'closed' });
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${ FORM_STYLE }
|
||||
|
||||
::slotted(section) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<form>
|
||||
<article id="items">
|
||||
@ -39,7 +32,7 @@ customElements.define('register-items-form', class extends PseudoForm {
|
||||
</div>
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`;
|
||||
`);
|
||||
this.addEventListener('item:removed', ev => {
|
||||
ev.stopPropagation();
|
||||
updateItems(this)
|
||||
@ -52,7 +45,7 @@ customElements.define('register-items-form', class extends PseudoForm {
|
||||
}
|
||||
}
|
||||
});
|
||||
shadow.querySelector('#add-item').addEventListener('click', ev => {
|
||||
this.shadowRoot.querySelector('#add-item').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.appendChild(document.createElement('register-item-form-row'));
|
||||
|
@ -1,14 +1,8 @@
|
||||
import { FORM_STYLE, PseudoForm } from "../shared";
|
||||
|
||||
customElements.define('register-submit-form', class extends PseudoForm {
|
||||
#form;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
@ -59,16 +53,16 @@ customElements.define('register-submit-form', class extends PseudoForm {
|
||||
<input type="submit" value="Dodaj usługi/produkty" />
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
|
||||
updateField(name, value) {
|
||||
this.#form.querySelector(`[id="hidden-${ name }"]`).value = value;
|
||||
this.#form.querySelector(`[id="preview-${ name }"]`).value = value;
|
||||
this.shadowRoot.querySelector(`[id="hidden-${ name }"]`).value = value;
|
||||
this.shadowRoot.querySelector(`[id="preview-${ name }"]`).value = value;
|
||||
}
|
||||
|
||||
setItems(items) {
|
||||
const host = this.#form.querySelector('#items');
|
||||
const host = this.shadowRoot.querySelector('#items');
|
||||
host.innerHTML = ``;
|
||||
for (const row of items) {
|
||||
const el = host.appendChild(document.createElement('div'));
|
||||
@ -76,14 +70,14 @@ customElements.define('register-submit-form', class extends PseudoForm {
|
||||
const [name, price] = row;
|
||||
|
||||
el.innerHTML = `
|
||||
<input type="text" name="${name.name}" value="${name.value}" readonly />
|
||||
<input type="hidden" name="${price.name}" value="${price.value}" readonly />
|
||||
<price-view value="${price.value}"></price-view>
|
||||
<input type="text" name="${ name.name }" value="${ name.value }" readonly />
|
||||
<input type="hidden" name="${ price.name }" value="${ price.value }" readonly />
|
||||
<price-view value="${ price.value }"></price-view>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
set accountType(v) {
|
||||
this.#form.querySelector('#account_type').value = v;
|
||||
this.shadowRoot.querySelector('#account_type').value = v;
|
||||
}
|
||||
});
|
||||
|
@ -1,21 +1,15 @@
|
||||
import { FORM_STYLE } from "../shared";
|
||||
|
||||
customElements.define('register-user-form', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component, FORM_STYLE } from "../shared";
|
||||
import "../shared/facebook-button";
|
||||
|
||||
customElements.define('register-user-form', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['mode']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host { display: block; }
|
||||
svg { width: 200px; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
#icons {
|
||||
display: flex;
|
||||
@ -49,6 +43,7 @@ customElements.define('register-user-form', class extends HTMLElement {
|
||||
</svg>
|
||||
|
||||
<form id="form" method="post" action="/register">
|
||||
<input type="hidden" id="account_type" name="account_type">
|
||||
<input type="hidden" id="facebook_id" name="facebook_id">
|
||||
<div>
|
||||
<label>E-Mail</label>
|
||||
@ -68,34 +63,28 @@ customElements.define('register-user-form', class extends HTMLElement {
|
||||
</form>
|
||||
</div>
|
||||
<div class="option">
|
||||
<svg id="fb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" xml:space="preserve">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#3B5998" d="M448 512h-87.999c-22.094 0-39.999-17.922-39.999-40V360.001c0-22.094 17.905-39.999 39.999-39.999h12.922c8.32 0 16.844-6.656 19.062-15.031l8.484-31.953c2.484-9.312-2.812-17.023-11.852-17.023H360c-22.094 0-39.999-17.902-39.999-39.988v-16C320.001 177.905 337.906 160 360 160h24.008c8.82 0 16-7.156 16-16v-32.004c0-8.828-7.18-16.004-16-16.004H336c-44.187 0-79.991 35.828-79.991 80.011v40.004c0 22.085-17.922 39.988-40.003 39.988h-7.625c-9.039 0-16.379 7.711-16.379 17.023v31.953c0 8.375 6.746 15.031 15.07 15.031h8.934c22.082 0 40.003 17.905 40.003 39.999V472c0 22.078-17.922 40-40.003 40h-8c-8.844 0-16.004-7.172-16.004-16 0-8.844 7.16-16 16.004-16 8.824 0 16-7.172 16-16v-95.999c0-8.844-7.175-16-16-16H197.51c-20.719 0-37.511-16.578-37.511-37.577v-47.922c0-23.156 18.371-42.512 41.027-42.512h6.98c8.824 0 16-7.16 16-15.984v-40.004c0-57.441 46.559-103.995 103.995-103.995h64.008c22.086 0 39.984 17.902 39.984 39.988v48.004c0 22.085-17.898 40.003-39.984 40.003H352.001v16.004c0 8.824 7.156 15.984 16 15.984h29.969c22.672 0 37.398 19.355 33.062 42.512l-8.992 47.922c-3.93 20.999-23.82 37.577-44.539 37.577h-9.5c-8.844 0-16 7.156-16 16V464c0 8.828 7.156 16 16 16H448c17.672 0 32-14.328 32-32V64.007c0-17.688-14.328-32.003-32-32.003H64.007c-17.672 0-32.003 14.316-32.003 32.003V448c0 17.672 14.332 32 32.003 32h16c8.828 0 16.003 7.156 16.003 16 0 8.828-7.175 16-16.003 16h-16C28.668 512 0 483.344 0 448V64.007C0 28.648 28.668 0 64.007 0H448c35.359 0 64 28.648 64 64.007V448c0 35.344-28.641 64-64 64zm-304.001-32c8.844 0 16 7.156 16 16 0 8.828-7.156 16-16 16-8.828 0-16.004-7.172-16.004-16 0-8.844 7.176-16 16.004-16z"/>
|
||||
</svg>
|
||||
<facebook-button></facebook-button>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
`);
|
||||
|
||||
const form = shadow.querySelector('form');
|
||||
const form = this.shadowRoot.querySelector('form');
|
||||
|
||||
shadow.querySelector('#fb-icon').addEventListener('click', ev => {
|
||||
this.addEventListener('facebook:account', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.mode = 'facebook';
|
||||
FB.login((res) => {
|
||||
if (res.status === 'connected') {
|
||||
FB.api("/me?fields=id,name,email", ({ id, name, email, ...rest }) => {
|
||||
console.log(id, name, email, rest);
|
||||
form.querySelector('#email').value = email;
|
||||
form.querySelector('#login').value = name;
|
||||
form.querySelector('#password').value = crypto.randomUUID();
|
||||
form.querySelector('#facebook_id').value = id;
|
||||
form.submit();
|
||||
});
|
||||
}
|
||||
}, { scope: 'public_profile,email', return_scopes: true });
|
||||
|
||||
const { id, name, email } = ev.detail;
|
||||
form.querySelector('#email').value = email;
|
||||
form.querySelector('#login').value = name;
|
||||
form.querySelector('#password').value = crypto.randomUUID();
|
||||
form.querySelector('#facebook_id').value = id;
|
||||
form.querySelector('#account_type').value = 'User';
|
||||
form.submit();
|
||||
});
|
||||
|
||||
shadow.querySelector('#email-icon').addEventListener('click', ev => {
|
||||
this.shadowRoot.querySelector('#email-icon').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
|
@ -1,12 +1,8 @@
|
||||
customElements.define('register-user-type', class extends HTMLElement {
|
||||
#form;
|
||||
import { Component } from "../shared";
|
||||
|
||||
customElements.define('register-user-type', class extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -56,15 +52,15 @@ customElements.define('register-user-type', class extends HTMLElement {
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
`;
|
||||
`);
|
||||
|
||||
const user = shadow.querySelector('#user');
|
||||
const user = this.shadowRoot.querySelector('#user');
|
||||
user.addEventListener('click', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.dispatchEvent(new CustomEvent('account:type:user', { bubbles: true, composed: true }));
|
||||
});
|
||||
const service = shadow.querySelector('#local-service');
|
||||
const service = this.shadowRoot.querySelector('#local-service');
|
||||
service.addEventListener('click', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
@ -104,17 +104,59 @@ label {
|
||||
${BUTTON_STYLE}
|
||||
`;
|
||||
|
||||
export class PseudoForm extends HTMLElement {
|
||||
export class Component extends HTMLElement {
|
||||
#shadow;
|
||||
|
||||
static get observedAttributes() {
|
||||
return []
|
||||
}
|
||||
|
||||
constructor(html) {
|
||||
super();
|
||||
|
||||
this.#shadow = this.attachShadow({ mode: 'open' });
|
||||
this.#shadow.innerHTML = html;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV)
|
||||
return;
|
||||
const observed = this.constructor.observedAttributes;
|
||||
if (!Array.isArray(observed))
|
||||
return;
|
||||
if (!observed.includes(name))
|
||||
return;
|
||||
const field = this.constructor.attr2Field(name);
|
||||
if (!field)
|
||||
return;
|
||||
this[field] = newV;
|
||||
}
|
||||
|
||||
static attr2Field(name) {
|
||||
if ((this.constructor.attr2FieldBlacklist || []).includes(name))
|
||||
return;
|
||||
return name.replace('-', '_');
|
||||
}
|
||||
|
||||
static get attr2FieldBlacklist() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export class PseudoForm extends Component {
|
||||
reportValidity() {
|
||||
return this[S].querySelector('form').reportValidity();
|
||||
return this.shadowRoot.querySelector('form').reportValidity();
|
||||
}
|
||||
|
||||
checkValidity() {
|
||||
return this[S].querySelector('form').checkValidity();
|
||||
return this.shadowRoot.querySelector('form').checkValidity();
|
||||
}
|
||||
|
||||
get elements() {
|
||||
return this[S].querySelector('form').elements;
|
||||
return this.shadowRoot.querySelector('form').elements;
|
||||
}
|
||||
}
|
||||
|
||||
|
94
client/src/shared/facebook-button.js
Normal file
94
client/src/shared/facebook-button.js
Normal file
@ -0,0 +1,94 @@
|
||||
import { Component, FORM_STYLE, runFbReady } from "../shared";
|
||||
|
||||
customElements.define('facebook-button', class extends Component {
|
||||
#fb_sdk;
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['width', 'height', 'fb-sdk']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super(`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
#not-available {
|
||||
display: block;
|
||||
}
|
||||
#svg {
|
||||
display: none;
|
||||
}
|
||||
:host([fb-sdk="available"]) #not-available {
|
||||
display: none;
|
||||
}
|
||||
:host([fb-sdk="available"]) #svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
${ FORM_STYLE }
|
||||
</style>
|
||||
<p id="not-available">Skrypty Facebook są zablokowane przez rozszerzenie przeglądarki</p>
|
||||
<div id="svg">
|
||||
<svg id="fb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" xml:space="preserve">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#3B5998" d="M448 512h-87.999c-22.094 0-39.999-17.922-39.999-40V360.001c0-22.094 17.905-39.999 39.999-39.999h12.922c8.32 0 16.844-6.656 19.062-15.031l8.484-31.953c2.484-9.312-2.812-17.023-11.852-17.023H360c-22.094 0-39.999-17.902-39.999-39.988v-16C320.001 177.905 337.906 160 360 160h24.008c8.82 0 16-7.156 16-16v-32.004c0-8.828-7.18-16.004-16-16.004H336c-44.187 0-79.991 35.828-79.991 80.011v40.004c0 22.085-17.922 39.988-40.003 39.988h-7.625c-9.039 0-16.379 7.711-16.379 17.023v31.953c0 8.375 6.746 15.031 15.07 15.031h8.934c22.082 0 40.003 17.905 40.003 39.999V472c0 22.078-17.922 40-40.003 40h-8c-8.844 0-16.004-7.172-16.004-16 0-8.844 7.16-16 16.004-16 8.824 0 16-7.172 16-16v-95.999c0-8.844-7.175-16-16-16H197.51c-20.719 0-37.511-16.578-37.511-37.577v-47.922c0-23.156 18.371-42.512 41.027-42.512h6.98c8.824 0 16-7.16 16-15.984v-40.004c0-57.441 46.559-103.995 103.995-103.995h64.008c22.086 0 39.984 17.902 39.984 39.988v48.004c0 22.085-17.898 40.003-39.984 40.003H352.001v16.004c0 8.824 7.156 15.984 16 15.984h29.969c22.672 0 37.398 19.355 33.062 42.512l-8.992 47.922c-3.93 20.999-23.82 37.577-44.539 37.577h-9.5c-8.844 0-16 7.156-16 16V464c0 8.828 7.156 16 16 16H448c17.672 0 32-14.328 32-32V64.007c0-17.688-14.328-32.003-32-32.003H64.007c-17.672 0-32.003 14.316-32.003 32.003V448c0 17.672 14.332 32 32.003 32h16c8.828 0 16.003 7.156 16.003 16 0 8.828-7.175 16-16.003 16h-16C28.668 512 0 483.344 0 448V64.007C0 28.648 28.668 0 64.007 0H448c35.359 0 64 28.648 64 64.007V448c0 35.344-28.641 64-64 64zm-304.001-32c8.844 0 16 7.156 16 16 0 8.828-7.156 16-16 16-8.828 0-16.004-7.172-16.004-16 0-8.844 7.176-16 16.004-16z"/>
|
||||
</svg>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`);
|
||||
|
||||
this.shadowRoot.querySelector('#fb-icon').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
if (!this.#fb_sdk)
|
||||
return console.info("Facebook SDK is not available");
|
||||
FB.login((res) => {
|
||||
if (res.status === 'connected') {
|
||||
FB.api("/me?fields=id,name,email", ({ id, name, email }) => {
|
||||
console.info({ id, name, email });
|
||||
this.dispatchEvent(new CustomEvent('facebook:account', {
|
||||
bubbles: true, composed: true, detail: {
|
||||
id, name, email
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}, { scope: 'public_profile,email', return_scopes: true });
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
runFbReady(() => {
|
||||
this.setAttribute('fb-sdk', 'available');
|
||||
this.dispatchEvent(new CustomEvent('facebook:available', { bubbles: true, composed: true }));
|
||||
});
|
||||
}
|
||||
|
||||
get width() {
|
||||
return this.getAttribute('width')
|
||||
}
|
||||
|
||||
set width(v) {
|
||||
this.setAttribute('width', v);
|
||||
this.shadowRoot.querySelector('svg').setAttribute('width', v);
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this.getAttribute('width')
|
||||
}
|
||||
|
||||
set height(v) {
|
||||
this.setAttribute('height', v);
|
||||
this.shadowRoot.querySelector('svg').setAttribute('height', v);
|
||||
}
|
||||
|
||||
get fb_sdk() {
|
||||
return !!this.#fb_sdk;
|
||||
}
|
||||
|
||||
set fb_sdk(v) {
|
||||
this.setAttribute('fb-sdk', v);
|
||||
this.#fb_sdk = v === 'available';
|
||||
}
|
||||
});
|
@ -1,18 +1,12 @@
|
||||
import { BUTTON_STYLE, S } from "../shared.js";
|
||||
|
||||
customElements.define('image-input', class extends HTMLElement {
|
||||
#form;
|
||||
import { BUTTON_STYLE, Component, S } from "../shared.js";
|
||||
|
||||
customElements.define('image-input', class extends Component {
|
||||
static get observedAttributes() {
|
||||
return ['width', 'height', "account-id", "url"]
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.#form = this.attachShadow({ mode: "closed" });
|
||||
|
||||
shadow.innerHTML = `
|
||||
super(`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
@ -31,7 +25,7 @@ customElements.define('image-input', class extends HTMLElement {
|
||||
border-bottom: none;
|
||||
border-color: var(--border-light-gray-color);
|
||||
}
|
||||
${BUTTON_STYLE}
|
||||
${ BUTTON_STYLE }
|
||||
</style>
|
||||
<article>
|
||||
<section id="hidden">
|
||||
@ -45,9 +39,9 @@ customElements.define('image-input', class extends HTMLElement {
|
||||
<input id="save" type="button" value="Zapisz" />
|
||||
</div>
|
||||
</article>
|
||||
`;
|
||||
`);
|
||||
|
||||
shadow.querySelector('#save').addEventListener('click', ev => {
|
||||
this.shadowRoot.querySelector('#save').addEventListener('click', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
const c = document.createElement('canvas');
|
||||
@ -73,10 +67,10 @@ customElements.define('image-input', class extends HTMLElement {
|
||||
});
|
||||
|
||||
const f = new FileReader();
|
||||
const input = shadow.querySelector('#file');
|
||||
const view = shadow.querySelector('#view');
|
||||
const img = shadow.querySelector('img');
|
||||
const canvas = shadow.querySelector('canvas');
|
||||
const input = this.shadowRoot.querySelector('#file');
|
||||
const view = this.shadowRoot.querySelector('#view');
|
||||
const img = this.shadowRoot.querySelector('img');
|
||||
const canvas = this.shadowRoot.querySelector('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
img.addEventListener('load', () => {
|
||||
@ -119,13 +113,7 @@ customElements.define('image-input', class extends HTMLElement {
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
if (oldV === newV) return;
|
||||
switch (name) {
|
||||
case 'account-id':
|
||||
return this.account_id = newV;
|
||||
case 'url':
|
||||
return this.url = newV;
|
||||
}
|
||||
super.attributeChangedCallback(name, oldV, newV);
|
||||
}
|
||||
|
||||
get account_id() {
|
||||
@ -141,17 +129,25 @@ customElements.define('image-input', class extends HTMLElement {
|
||||
return isNaN(v) ? 0 : v;
|
||||
}
|
||||
|
||||
set width(v) {
|
||||
this.setAttribute('width', v);
|
||||
}
|
||||
|
||||
get height() {
|
||||
const v = parseInt(this.getAttribute('height'));
|
||||
return isNaN(v) ? 0 : v;
|
||||
}
|
||||
|
||||
set height(v) {
|
||||
this.setAttribute('height', v);
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this.getAttribute('url');
|
||||
}
|
||||
|
||||
set url(v) {
|
||||
this.setAttribute('url', v);
|
||||
this.#form.querySelector('img').src = v;
|
||||
this.shadowRoot.querySelector('img').src = v;
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user