diff --git a/client/src/app.js b/client/src/app.js index bc21853..d29ca55 100644 --- a/client/src/app.js +++ b/client/src/app.js @@ -15,14 +15,14 @@ import "./local-businesses/local-business.js"; import "./login-form.js"; import "./register-form.js"; -import "./register-form/register-basic-form"; +import "./register-form/register-business-account-form"; import "./register-form/register-item-form-row.js"; -import "./register-form/register-items-form.js"; -import "./register-form/register-business-form.js"; -import "./register-form/register-user-type.js"; -import "./register-form/register-user-form.js"; -import "./register-form/register-business-contacts.js"; -import "./register-form/register-submit-form.js"; +import "./register-form/register-business-items-form.js"; +import "./register-form/register-business-details-form.js"; +import "./register-form/register-account-type.js"; +import "./register-form/register-user-account-form.js"; +import "./register-form/register-business-contact-form.js"; +import "./register-form/register-business-submit-form.js"; import "./business-items/business-item.js"; import "./business-items/business-item-editor.js"; @@ -64,3 +64,15 @@ if (!document.querySelector('#facebook-jssdk')) { js.src = "https://connect.facebook.net/en_US/sdk.js"; document.head.appendChild(js); } + +Object.prototype.entry = function (key) { + const owner = this; + return { + owner, orElse(v) { + if (owner[key] === undefined) owner[key] = v; + return owner[key]; + }, get() { + return owner[key]; + } + } +}; diff --git a/client/src/register-form.js b/client/src/register-form.js index a9276db..bdfc5dc 100644 --- a/client/src/register-form.js +++ b/client/src/register-form.js @@ -1,6 +1,19 @@ import { FORM_STYLE, Component } from "./shared.js"; import { RegisterForm } from "./register-form/model.js"; +/* + +
+ + + + + + + +
+*/ + customElements.define('register-form', class extends Component { #form = new RegisterForm; @@ -47,57 +60,54 @@ customElements.define('register-form', class extends Component {
-
- - - - - - -
`); - const finalForm = this.shadowRoot.querySelector('#step-4'); - this.shadowRoot.addEventListener('account:type:user', ev => { - ev.stopPropagation(); - this.#form.account_type = 'User'; - - finalForm.accountType = 'User'; - this.step = 40; - }); - this.shadowRoot.addEventListener('account:type:local-service', ev => { - ev.stopPropagation(); - this.#form.account_type = 'Business'; - - finalForm.accountType = 'Business'; - this.step = 1; - }); this.shadowRoot.addEventListener('form:next', ev => { ev.stopPropagation(); - const form = this.shadowRoot.querySelector(`#step-${ this.step }`); - if (this.#copyForm(form, finalForm)) { - this.step = this.step + 1; - } + this.step = this.step + 1; }); this.shadowRoot.addEventListener('form:prev', ev => { ev.stopPropagation(); this.step = this.step - 1; }); - this.addEventListener('account:basic', ev => { - console.log(ev); - console.log(ev.detail); - for (const [key, value] of Object.entries(ev.detail)) { - this.#form[key] = value; - } - console.log(this.#form, this.#form.payload); - }); - finalForm.addEventListener('submit', ev => { - ev.preventDefault(); + + this.shadowRoot.addEventListener('account:type', ev => { ev.stopPropagation(); + this.#form.account_type = ev.detail; + if (this.#form.account_type === 'User') { + this.#showUserAccountForm(); + } else { + this.#showBusinessAccountForm(); + } + }); + this.addEventListener('account:basic', ev => { + this.#copyDetail(ev) + this.#showBusinessDetailsForm(); + }); + this.addEventListener('account:business', ev => { + this.#copyDetail(ev) + }); + this.addEventListener('account:items', ev => { + const items = Object.entries(ev.detail).reduce((items, [fieldName, value]) => { + const m = fieldName.match(/(items)\[(\d+)]\[(\w+)]/); + if (!Array.isArray(m)) return items; + const [_full, _items, n, name] = m; + items.entry(n).orElse({})[name] = value; + return items; + }, {}); + this.#form.items = Array.from(Object.values(items)); }); } + #copyDetail(ev) { + ev.stopPropagation(); + for (const [key, value] of Object.entries(ev.detail)) { + this.#form[key] = value; + } + } + connectedCallback() { - this.step = 0; + super.connectedCallback(); + this.#showAccountTypeForm(); } get step() { @@ -110,23 +120,77 @@ customElements.define('register-form', class extends Component { this.setAttribute('step', n); } - #copyForm(form, finalForm) { - form.reportValidity(); + #host(body) { + this.shadowRoot.querySelector('#host').innerHTML = body; + } - for (const el of form.elements) { - if (el.name === '') continue; - if (!el.reportValidity()) { - return false; - } + #showAccountTypeForm() { + this.#host(` + + `); + } + + #showUserAccountForm() { + this.#host(` + + `); + } + + #showBusinessAccountForm() { + this.#host(` + + `); + } + + #showBusinessDetailsForm() { + this.#host(` + + `); + } + + #transfer(page, direction) { + const current = direction === 'next' + ? this.#nextPage(page) + : this.#prevPage(page); + if (!current) return; + } + + #nextPage(page) { + switch (page) { + case "account-type": + return this.#form.account_type === 'User' + ? 'user-account' + : 'business-account'; + case "user-account": return null; + case "business-account": return 'business-details'; + case "business-details": return 'business-items'; + case "business-items": return 'business-contact'; + case "business-contact": return 'business-submit'; + case "business-submit": return null; + } + } + + #prevPage(page) { + switch (page) { + case "account-type": + return null; + case "user-account": return 'account-type'; + case "business-account": return 'account-type'; + case "business-details": return 'business-account'; + case "business-items": return 'business-details'; + case "business-contact": return 'business-items'; + case "business-submit": return 'business-contact'; } - const inputs = form.inputs; - if (inputs) - finalForm.setItems(inputs); - else - for (const el of form.elements) { - if (el.name === '') continue; - finalForm.updateField(el.name, el.value); - } - return true; } }); diff --git a/client/src/register-form/model.js b/client/src/register-form/model.js index ad47d10..5a018ab 100644 --- a/client/src/register-form/model.js +++ b/client/src/register-form/model.js @@ -1,13 +1,54 @@ +import { PseudoForm } from "../shared.js"; + +export class RegisterFormComponent extends PseudoForm { + #mounted = false; + + get submitEventName() { + return null; + } + + mountFormHandler() { + if (this.#mounted) return; + this.#mounted = true; + + const form = this.shadowRoot.querySelector('form'); + form.addEventListener('submit', ev => { + ev.preventDefault(); + ev.stopPropagation(); + + if (form.reportValidity()) { + this.shadowRoot.querySelector('form-navigation').next(); + } + }); + this.addEventListener('form:next', () => { + this.#dispatchForm() + }); + } + + #dispatchForm() { + const detail = [...this.elements].filter(el => el.name && el.name.length).reduce((memo, el) => ({ + ...memo, + [el.name]: el.value, + }), {}); + console.warn('#dispatchForm', detail, this.elements) + this.dispatchEvent(new CustomEvent(this.submitEventName, { composed: true, bubbles: true, detail })); + } + + get elements() { + return this.shadowRoot.querySelector('form').elements; + } +} + export class RegisterForm { - #email; //: String, - #login; //: String, - #password; //: String, - #facebook_id; //: Option, - #account_type; //: db::AccountType, + #email = ''; //: String, + #login = ''; //: String, + #password = ''; //: String, + #facebook_id = null; //: Option, + #account_type = 'User'; //: db::AccountType, #items = null; //: Option>, #contacts = null; //: Option>, - #name; //: Option, - #description; //: Option, + #name = null; //: Option, + #description = null; //: Option, get email() { return this.#email; @@ -68,6 +109,10 @@ export class RegisterForm { return this.#items; } + set items(a) { + this.#items = a; + } + appendItem(item) { this.#items = this.#items || []; this.#items.push(item); @@ -99,27 +144,23 @@ export class RegisterForm { } get payload() { - const { - email, - login, - password, - facebook_id, - account_type, - items, - contacts, - name, - description - } = this; - return { - email, - login, - password, - facebook_id, - account_type, - items, - contacts, - name, - description - }; + return [ + 'email', + 'login', + 'password', + 'facebook_id', + 'account_type', + 'items', + 'contacts', + 'name', + 'description' + ].reduce((m, k) => { + const v = this[k]; + if (v === undefined || v === null) { + return m; + } + m[k] = v; + return m; + }, {}) } } diff --git a/client/src/register-form/register-user-type.js b/client/src/register-form/register-account-type.js similarity index 92% rename from client/src/register-form/register-user-type.js rename to client/src/register-form/register-account-type.js index 3cb293b..2f53a10 100644 --- a/client/src/register-form/register-user-type.js +++ b/client/src/register-form/register-account-type.js @@ -1,6 +1,6 @@ import { Component, BUTTON_STYLE, TIP_STYLE } from "../shared"; -customElements.define('register-user-type', class extends Component { +customElements.define('register-account-type', class extends Component { constructor() { super(` -
-
- - -
-
- - -
-
- - -
- - -
- `); - - const form = this.shadowRoot.querySelector('form'); - form.addEventListener('submit', ev => { - ev.preventDefault(); - ev.stopPropagation(); - - if (form.reportValidity()) { - this.shadowRoot.querySelector('form-navigation').next(); - } - }); - this.addEventListener('form:next', () => { - this.#dispatchForm() - }); - } - - #dispatchForm() { - const detail = [...this.shadowRoot.querySelector('form').elements].filter(el => el.name && el.name.length).reduce((memo, el) => ({ - ...memo, - [el.name]: el.value, - }), {}); - this.dispatchEvent(new CustomEvent('account:basic', { composed: true, bubbles: true, detail })); - } -}); diff --git a/client/src/register-form/register-business-account-form.js b/client/src/register-form/register-business-account-form.js new file mode 100644 index 0000000..0f0db84 --- /dev/null +++ b/client/src/register-form/register-business-account-form.js @@ -0,0 +1,57 @@ +import { FORM_STYLE } from "../shared"; +import { RegisterFormComponent } from "./model"; + +customElements.define('register-business-account-form', class extends RegisterFormComponent { + static get observedAttributes() { + return ['login', 'password', 'email'] + } + + constructor() { + super(` + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+ `); + + this.mountFormHandler(); + } + + get submitEventName() { + return 'account:basic'; + } + + set email(v) { + this.#input('email').value = v; + } + + set login(v) { + this.#input('login').value = v; + } + + set password(v) { + this.#input('password').value = v; + } + + #input(id) { + return this.shadowRoot.querySelector(`#${ id }`); + } +}); diff --git a/client/src/register-form/register-business-contact-form.js b/client/src/register-form/register-business-contact-form.js new file mode 100644 index 0000000..8767d3a --- /dev/null +++ b/client/src/register-form/register-business-contact-form.js @@ -0,0 +1,22 @@ +import { RegisterFormComponent } from "./model.js"; + +customElements.define('register-business-contact-form', class extends RegisterFormComponent { + constructor() { + super(` + +
+
+ +
+
+ `); + + this.mountFormHandler(); + } + + get submitEventName() { + return 'account:contacts'; + } +}); diff --git a/client/src/register-form/register-business-contacts.js b/client/src/register-form/register-business-contacts.js deleted file mode 100644 index 7ce1120..0000000 --- a/client/src/register-form/register-business-contacts.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from "../shared.js"; - -customElements.define('register-business-contacts', class extends Component { - constructor() { - super(` - -
-
- `); - } -}); diff --git a/client/src/register-form/register-business-details-form.js b/client/src/register-form/register-business-details-form.js new file mode 100644 index 0000000..8927d26 --- /dev/null +++ b/client/src/register-form/register-business-details-form.js @@ -0,0 +1,48 @@ +import { FORM_STYLE, TIP_STYLE } from "../shared"; +import { RegisterFormComponent } from "./model"; + +customElements.define('register-business-details-form', class extends RegisterFormComponent { + static get observedAttributes() { + return ["name", "description"]; + } + constructor() { + super(` + +
+
+ + +
+
+ + +
Produkty dodawane są w nastepnym kroku
+
+ +
+ `); + + this.mountFormHandler(); + } + + get submitEventName() { + return 'account:business'; + } + + set name(v) { + this.#input('name').value = v; + } + + set description(v) { + this.#input('description').value = (v || '').trim(); + } + + #input(id) { + return this.shadowRoot.querySelector(`#${ id }`); + } +}) diff --git a/client/src/register-form/register-business-form.js b/client/src/register-form/register-business-form.js deleted file mode 100644 index 66dffc8..0000000 --- a/client/src/register-form/register-business-form.js +++ /dev/null @@ -1,41 +0,0 @@ -import { FORM_STYLE, TIP_STYLE, PseudoForm } from "../shared"; - -customElements.define('register-business-form', class extends PseudoForm { - constructor() { - super(` - -
-
- - -
-
- - -
Produkty dodawane są w nastepnym kroku
-
- -
- `); - - this.shadowRoot.querySelector('form').addEventListener('submit', ev => { - ev.preventDefault(); - ev.stopPropagation(); - this.#dispatchForm(); - this.shadowRoot.querySelector('form-navigation').next(); - }); - } - - #dispatchForm() { - const detail = [...this.shadowRoot.querySelector('form').elements].filter(el => el.name && el.name.length).reduce((memo, el) => ({ - ...memo, - [el.name]: el.value, - }), {}); - this.dispatchEvent(new CustomEvent('account:business', { composed: true, bubbles: true, detail })); - } -}) diff --git a/client/src/register-form/register-items-form.js b/client/src/register-form/register-business-items-form.js similarity index 76% rename from client/src/register-form/register-items-form.js rename to client/src/register-form/register-business-items-form.js index e94d960..2263497 100644 --- a/client/src/register-form/register-items-form.js +++ b/client/src/register-form/register-business-items-form.js @@ -1,6 +1,5 @@ -import { FORM_STYLE, PseudoForm } from "../shared"; - -import "./register-item-form-row" +import { FORM_STYLE } from "../shared"; +import { RegisterFormComponent } from "./model"; const updateItems = (form) => { let idx = 0; @@ -10,7 +9,7 @@ const updateItems = (form) => { return idx; } -customElements.define('register-items-form', class extends PseudoForm { +customElements.define('register-business-items-form', class extends RegisterFormComponent { constructor() { super(`