Create local business
This commit is contained in:
parent
7abf25345f
commit
a727a78bcb
114
client/dist/app.js
vendored
114
client/dist/app.js
vendored
@ -8,6 +8,9 @@ form legend {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
form.inline div {
|
||||
display: flex;
|
||||
}
|
||||
form > div {
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
@ -127,6 +130,9 @@ customElements.define("form-navigation", class extends HTMLElement {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
input {
|
||||
max-width: 200px;
|
||||
}
|
||||
input.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
@ -138,17 +144,9 @@ customElements.define("form-navigation", class extends HTMLElement {
|
||||
</div>
|
||||
</form>
|
||||
`, c.querySelector("#prev").addEventListener("click", (a)=>{
|
||||
a.stopPropagation(), a.preventDefault(), this.dispatchEvent(new CustomEvent("form:prev", {
|
||||
bubbles: !0,
|
||||
composed: !0,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
a.stopPropagation(), a.preventDefault(), this.prev();
|
||||
}), c.querySelector("#next").addEventListener("click", (a)=>{
|
||||
a.stopPropagation(), a.preventDefault(), this.dispatchEvent(new CustomEvent("form:next", {
|
||||
bubbles: !0,
|
||||
composed: !0,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
a.stopPropagation(), a.preventDefault(), this.next();
|
||||
});
|
||||
}
|
||||
attributeChangedCallback(b, c, d) {
|
||||
@ -160,6 +158,20 @@ customElements.define("form-navigation", class extends HTMLElement {
|
||||
this[S].querySelector("#prev").className = "hidden" === d ? "hidden" : "";
|
||||
}
|
||||
}
|
||||
next() {
|
||||
this.dispatchEvent(new CustomEvent("form:next", {
|
||||
bubbles: !0,
|
||||
composed: !0,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
}
|
||||
prev() {
|
||||
this.dispatchEvent(new CustomEvent("form:prev", {
|
||||
bubbles: !0,
|
||||
composed: !0,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
}
|
||||
});
|
||||
customElements.define("local-service", class extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
@ -372,17 +384,19 @@ customElements.define("ow-account", class extends HTMLElement {
|
||||
#form > * {
|
||||
display: none;
|
||||
}
|
||||
:host([mode="login"]) login-form, :host([mode="login"]) #switch-register {
|
||||
display: block;
|
||||
:host([mode="login"]) #form > login-form, :host([mode="login"]) #switch-register {
|
||||
display: block !important;
|
||||
}
|
||||
:host([mode="register"]) register-form, :host([mode="register"]) #switch-login {
|
||||
display: block;
|
||||
:host([mode="register"]) #form > register-form, :host([mode="register"]) #switch-login {
|
||||
display: block !important;
|
||||
}
|
||||
#display {
|
||||
display: none;
|
||||
}
|
||||
:host([mode="display"]) #display { display: block; }
|
||||
:host([mode="display"]) #form { display: none; }
|
||||
:host([mode="form"]) #form,
|
||||
:host([mode="login"]) #form { display: block; }
|
||||
|
||||
a{
|
||||
display: block;
|
||||
@ -406,6 +420,7 @@ 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" />
|
||||
@ -658,13 +673,20 @@ customElements.define("price-input", class extends HTMLElement {
|
||||
${FORM_STYLE}
|
||||
</style>
|
||||
<div id="view">
|
||||
<input id="price" type="number" min="0.00" max="10000.00" step="0.01" />
|
||||
<input
|
||||
id="price" type="number" min="0.00" max="10000.00" step="0.01"
|
||||
placeholder="Cena, np: 12.23"
|
||||
/>
|
||||
<span id="currency"></span>
|
||||
</div>
|
||||
`;
|
||||
let d = c.querySelector("#price");
|
||||
d.addEventListener("change", (a)=>{
|
||||
a.stopPropagation(), this.value = d.value;
|
||||
});
|
||||
}
|
||||
connectedCallback() {
|
||||
this[S].querySelector("#currency").textContent = this.currency;
|
||||
this[S].querySelector("#currency").textContent = this.currency, this[S].querySelector("#price").value = this.value;
|
||||
}
|
||||
attributeChangedCallback(b, c, d) {
|
||||
if (c === d) return;
|
||||
@ -681,6 +703,9 @@ customElements.define("price-input", class extends HTMLElement {
|
||||
break;
|
||||
case "readonly":
|
||||
d ? e.setAttribute("readonly", "readonly") : e.removeAttribute("readonly");
|
||||
break;
|
||||
case "name":
|
||||
this.setAttribute("name", d);
|
||||
}
|
||||
}
|
||||
get value() {
|
||||
@ -721,7 +746,7 @@ customElements.define("register-basic-form", class extends PseudoForm {
|
||||
<form id="step-1">
|
||||
<div>
|
||||
<label>Login</label>
|
||||
<input id="login" name="login" placeholder="Login" type="text" required />
|
||||
<input id="login" name="login" placeholder="Login" type="text" required autofocus />
|
||||
</div>
|
||||
<div>
|
||||
<label>E-Mail</label>
|
||||
@ -736,11 +761,7 @@ customElements.define("register-basic-form", class extends PseudoForm {
|
||||
`;
|
||||
let d = c.querySelector("form");
|
||||
d.addEventListener("submit", (a)=>{
|
||||
a.preventDefault(), a.stopPropagation(), this.dispatchEvent(new CustomEvent("form:next", {
|
||||
bubbles: !0,
|
||||
composed: !0,
|
||||
detail: d
|
||||
}));
|
||||
a.preventDefault(), a.stopPropagation(), c.querySelector("form-navigation").next();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -771,8 +792,13 @@ customElements.define("register-item-form-row", class extends PseudoForm {
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${FORM_STYLE}
|
||||
|
||||
section {
|
||||
form {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
div {
|
||||
min-width: 100px;
|
||||
max-width: 48%;
|
||||
}
|
||||
</style>
|
||||
<form class="inline">
|
||||
@ -801,8 +827,8 @@ customElements.define("register-item-form-row", class extends PseudoForm {
|
||||
}
|
||||
get inputs() {
|
||||
return [
|
||||
this[S].querySelector(".item-name").cloneNode(!0),
|
||||
this[S].querySelector(".item-price").cloneNode(!0),
|
||||
d(this[S].querySelector(".item-name")),
|
||||
d(this[S].querySelector(".item-price")),
|
||||
];
|
||||
}
|
||||
updateNames() {
|
||||
@ -822,7 +848,11 @@ customElements.define("register-item-form-row", class extends PseudoForm {
|
||||
return super.reportValidity() && this[S].querySelector("price-input").reportValidity();
|
||||
}
|
||||
});
|
||||
let d = (a)=>{
|
||||
let d = ({ name: a , value: b })=>({
|
||||
name: a,
|
||||
value: b
|
||||
});
|
||||
let d1 = (a)=>{
|
||||
let b = 0;
|
||||
for (let c of a.querySelectorAll("register-item-form-row"))c.idx = b++;
|
||||
return b;
|
||||
@ -856,11 +886,11 @@ customElements.define("register-items-form", class extends PseudoForm {
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`, this.addEventListener("item:removed", (a)=>{
|
||||
a.stopPropagation(), d(this);
|
||||
a.stopPropagation(), d1(this);
|
||||
}), this.addEventListener("form:next", (a)=>{
|
||||
for (let b of this.querySelectorAll("item-form-row"))b.reportValidity() || (a.stopPropagation(), a.preventDefault());
|
||||
}), c.querySelector("#add-item").addEventListener("click", (a)=>{
|
||||
a.stopPropagation(), a.preventDefault(), this.appendChild(document.createElement("register-item-form-row")), d(this);
|
||||
a.stopPropagation(), a.preventDefault(), this.appendChild(document.createElement("register-item-form-row")), d1(this);
|
||||
});
|
||||
}
|
||||
get inputs() {
|
||||
@ -883,7 +913,7 @@ customElements.define("register-company-form", class extends PseudoForm {
|
||||
</style>
|
||||
<form id="step-2">
|
||||
<div>
|
||||
<input name="name" placeholder="Nazwa usługi" type="text" required />
|
||||
<input name="name" placeholder="Nazwa usługi" type="text" required autofocus />
|
||||
</div>
|
||||
<div>
|
||||
<label>description</label>
|
||||
@ -891,7 +921,9 @@ customElements.define("register-company-form", class extends PseudoForm {
|
||||
</div>
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`;
|
||||
`, c.querySelector("form").addEventListener("submit", (a)=>{
|
||||
a.preventDefault(), a.stopPropagation(), c.querySelector("form-navigation").next();
|
||||
});
|
||||
}
|
||||
});
|
||||
customElements.define("register-submit-form", class extends PseudoForm {
|
||||
@ -905,12 +937,20 @@ customElements.define("register-submit-form", class extends PseudoForm {
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${FORM_STYLE}
|
||||
.item-view {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.item-view > * {
|
||||
min-width: 100px;
|
||||
max-width: 48%;
|
||||
}
|
||||
</style>
|
||||
<form id="step-4">
|
||||
<form id="step-4" method="post" action="/register">
|
||||
<div id="copied">
|
||||
<input id="hidden-login" name="login" type="hidden" />
|
||||
<input id="hidden-email" name="email" type="hidden" />
|
||||
<input id="hidden-pass" name="pass" type="hidden" />
|
||||
<input id="hidden-pass" name="password" type="hidden" />
|
||||
<input id="hidden-name" name="name" type="hidden" />
|
||||
<input id="hidden-description" name="description" type="hidden" />
|
||||
</div>
|
||||
@ -951,8 +991,14 @@ customElements.define("register-submit-form", class extends PseudoForm {
|
||||
setItems(a) {
|
||||
let c = this[S].querySelector("#items");
|
||||
for (let d of (c.innerHTML = "", a)){
|
||||
let e = c.appendChild(document.createElement("div")), [f, g] = d;
|
||||
f.setAttribute("readonly", "readonly"), e.appendChild(f), e.appendChild(document.createElement("price-view")).value = g.value, g.setAttribute("readonly", "readonly"), g.setAttribute("type", "hidden"), e.appendChild(g);
|
||||
let e = c.appendChild(document.createElement("div"));
|
||||
e.className = "item-view";
|
||||
let [f, g] = d;
|
||||
e.innerHTML = `
|
||||
<input type="text" name="${f.name}" value="${f.value}" readonly />
|
||||
<input type="hidden" name="${g.name}" value="${g.value}" readonly />
|
||||
<price-view value="${g.value}"></price-view>
|
||||
`;
|
||||
}
|
||||
}
|
||||
set accountType(a) {
|
||||
|
2
client/dist/app.js.map
vendored
2
client/dist/app.js.map
vendored
File diff suppressed because one or more lines are too long
@ -18,6 +18,9 @@ customElements.define('form-navigation', class extends HTMLElement {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
input {
|
||||
max-width: 200px;
|
||||
}
|
||||
input.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
@ -32,20 +35,12 @@ customElements.define('form-navigation', class extends HTMLElement {
|
||||
shadow.querySelector('#prev').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.dispatchEvent(new CustomEvent('form:prev', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
this.prev();
|
||||
});
|
||||
shadow.querySelector('#next').addEventListener('click', ev => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.dispatchEvent(new CustomEvent('form:next', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
this.next();
|
||||
});
|
||||
}
|
||||
|
||||
@ -62,4 +57,20 @@ customElements.define('form-navigation', class extends HTMLElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next() {
|
||||
this.dispatchEvent(new CustomEvent('form:next', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
}
|
||||
|
||||
prev() {
|
||||
this.dispatchEvent(new CustomEvent('form:prev', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: this.parentElement
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { S } from "./shared";
|
||||
import { S } from "../shared";
|
||||
|
||||
customElements.define('ow-nav', class extends HTMLElement {
|
||||
constructor() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { S } from "./shared";
|
||||
import { S } from "../shared";
|
||||
|
||||
customElements.define('ow-path', class extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
|
@ -15,17 +15,19 @@ customElements.define('ow-account', class extends HTMLElement {
|
||||
#form > * {
|
||||
display: none;
|
||||
}
|
||||
:host([mode="login"]) login-form, :host([mode="login"]) #switch-register {
|
||||
display: block;
|
||||
:host([mode="login"]) #form > login-form, :host([mode="login"]) #switch-register {
|
||||
display: block !important;
|
||||
}
|
||||
:host([mode="register"]) register-form, :host([mode="register"]) #switch-login {
|
||||
display: block;
|
||||
:host([mode="register"]) #form > register-form, :host([mode="register"]) #switch-login {
|
||||
display: block !important;
|
||||
}
|
||||
#display {
|
||||
display: none;
|
||||
}
|
||||
:host([mode="display"]) #display { display: block; }
|
||||
:host([mode="display"]) #form { display: none; }
|
||||
:host([mode="form"]) #form,
|
||||
:host([mode="login"]) #form { display: block; }
|
||||
|
||||
a{
|
||||
display: block;
|
||||
@ -49,6 +51,7 @@ 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" />
|
||||
|
@ -25,15 +25,24 @@ customElements.define('price-input', class extends HTMLElement {
|
||||
${FORM_STYLE}
|
||||
</style>
|
||||
<div id="view">
|
||||
<input id="price" type="number" min="0.00" max="10000.00" step="0.01" />
|
||||
<input
|
||||
id="price" type="number" min="0.00" max="10000.00" step="0.01"
|
||||
placeholder="Cena, np: 12.23"
|
||||
/>
|
||||
<span id="currency"></span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const price = shadow.querySelector('#price');
|
||||
price.addEventListener('change', ev => {
|
||||
ev.stopPropagation();
|
||||
this.value = price.value;
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this[S].querySelector('#currency').textContent = this.currency;
|
||||
// this[S].querySelector('#price').textContent = this.formatted;
|
||||
this[S].querySelector('#price').value = this.value;
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldV, newV) {
|
||||
@ -61,6 +70,7 @@ customElements.define('price-input', class extends HTMLElement {
|
||||
break;
|
||||
}
|
||||
case 'name': {
|
||||
this.setAttribute('name', newV);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ customElements.define('register-basic-form', class extends PseudoForm {
|
||||
<form id="step-1">
|
||||
<div>
|
||||
<label>Login</label>
|
||||
<input id="login" name="login" placeholder="Login" type="text" required />
|
||||
<input id="login" name="login" placeholder="Login" type="text" required autofocus />
|
||||
</div>
|
||||
<div>
|
||||
<label>E-Mail</label>
|
||||
@ -34,7 +34,7 @@ customElements.define('register-basic-form', class extends PseudoForm {
|
||||
form.addEventListener('submit', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.dispatchEvent(new CustomEvent('form:next', { bubbles: true, composed: true, detail: form }));
|
||||
shadow.querySelector('form-navigation').next();
|
||||
})
|
||||
}
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ customElements.define('register-company-form', class extends PseudoForm {
|
||||
</style>
|
||||
<form id="step-2">
|
||||
<div>
|
||||
<input name="name" placeholder="Nazwa usługi" type="text" required />
|
||||
<input name="name" placeholder="Nazwa usługi" type="text" required autofocus />
|
||||
</div>
|
||||
<div>
|
||||
<label>description</label>
|
||||
@ -23,5 +23,11 @@ customElements.define('register-company-form', class extends PseudoForm {
|
||||
<form-navigation></form-navigation>
|
||||
</form>
|
||||
`;
|
||||
|
||||
shadow.querySelector('form').addEventListener('submit', ev => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
shadow.querySelector('form-navigation').next();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -25,8 +25,13 @@ customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${ FORM_STYLE }
|
||||
|
||||
section {
|
||||
form {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
div {
|
||||
min-width: 100px;
|
||||
max-width: 48%;
|
||||
}
|
||||
</style>
|
||||
<form class="inline">
|
||||
@ -65,11 +70,10 @@ customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get inputs() {
|
||||
return [
|
||||
this[S].querySelector('.item-name').cloneNode(true),
|
||||
this[S].querySelector('.item-price').cloneNode(true),
|
||||
extract(this[S].querySelector('.item-name')),
|
||||
extract(this[S].querySelector('.item-price')),
|
||||
];
|
||||
}
|
||||
|
||||
@ -93,3 +97,5 @@ customElements.define('register-item-form-row', class extends PseudoForm {
|
||||
return super.reportValidity() && this[S].querySelector('price-input').reportValidity();
|
||||
}
|
||||
});
|
||||
|
||||
const extract = ({ name, value }) => ({ name, value })
|
||||
|
@ -11,12 +11,20 @@ customElements.define('register-submit-form', class extends PseudoForm {
|
||||
:host { display: block; }
|
||||
* { font-family: 'Noto Sans', sans-serif; }
|
||||
${ FORM_STYLE }
|
||||
.item-view {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.item-view > * {
|
||||
min-width: 100px;
|
||||
max-width: 48%;
|
||||
}
|
||||
</style>
|
||||
<form id="step-4">
|
||||
<form id="step-4" method="post" action="/register">
|
||||
<div id="copied">
|
||||
<input id="hidden-login" name="login" type="hidden" />
|
||||
<input id="hidden-email" name="email" type="hidden" />
|
||||
<input id="hidden-pass" name="pass" type="hidden" />
|
||||
<input id="hidden-pass" name="password" type="hidden" />
|
||||
<input id="hidden-name" name="name" type="hidden" />
|
||||
<input id="hidden-description" name="description" type="hidden" />
|
||||
</div>
|
||||
@ -62,15 +70,14 @@ customElements.define('register-submit-form', class extends PseudoForm {
|
||||
host.innerHTML = ``;
|
||||
for (const row of items) {
|
||||
const el = host.appendChild(document.createElement('div'));
|
||||
el.className = 'item-view';
|
||||
const [name, price] = row;
|
||||
|
||||
name.setAttribute('readonly', 'readonly');
|
||||
el.appendChild(name);
|
||||
|
||||
el.appendChild(document.createElement('price-view')).value = price.value;
|
||||
price.setAttribute('readonly', 'readonly');
|
||||
price.setAttribute('type', 'hidden');
|
||||
el.appendChild(price);
|
||||
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>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,9 @@ form legend {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
form.inline div {
|
||||
display: flex;
|
||||
}
|
||||
form > div {
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
|
@ -1 +1,2 @@
|
||||
ALTER TABLE accounts ADD COLUMN email text not null default '' unique;
|
||||
ALTER TABLE accounts
|
||||
ADD COLUMN email text not null default '' unique;
|
||||
|
@ -1 +1,2 @@
|
||||
ALTER TABLE accounts ADD COLUMN facebook_id TEXT DEFAULT NULL;
|
||||
ALTER TABLE accounts
|
||||
ADD COLUMN facebook_id TEXT DEFAULT NULL;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::routes::render_index;
|
||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
||||
use actix_web::{web, web::Data, App, HttpResponse, HttpServer};
|
||||
use actix_web::{web, web::Data, App, HttpServer};
|
||||
|
||||
mod auth;
|
||||
mod model;
|
||||
|
@ -4,7 +4,7 @@ use sqlx::{FromRow, Type};
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, PartialOrd, PartialEq, Serialize, Deserialize, Type)]
|
||||
#[derive(Debug, PartialOrd, PartialEq, Copy, Clone, Serialize, Deserialize, Type)]
|
||||
pub enum AccountType {
|
||||
User,
|
||||
Business,
|
||||
@ -63,7 +63,7 @@ pub struct Token {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, FromRow)]
|
||||
pub struct LocalService {
|
||||
pub struct LocalBusiness {
|
||||
pub id: i32,
|
||||
pub owner_id: i32,
|
||||
pub name: String,
|
||||
@ -72,7 +72,7 @@ pub struct LocalService {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, FromRow)]
|
||||
pub struct LocalServiceItem {
|
||||
pub struct LocalBusinessItem {
|
||||
pub id: i32,
|
||||
pub local_service_id: i32,
|
||||
pub name: String,
|
||||
|
@ -36,6 +36,12 @@ impl Page {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BusinessItemInput {
|
||||
pub name: String,
|
||||
pub price: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LocalService {
|
||||
pub id: i32,
|
||||
@ -43,11 +49,11 @@ pub struct LocalService {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub state: db::LocalServiceState,
|
||||
pub items: Vec<db::LocalServiceItem>,
|
||||
pub items: Vec<db::LocalBusinessItem>,
|
||||
}
|
||||
|
||||
impl<'v> From<(db::LocalService, &'v mut Vec<db::LocalServiceItem>)> for LocalService {
|
||||
fn from((service, items): (db::LocalService, &'v mut Vec<db::LocalServiceItem>)) -> Self {
|
||||
impl<'v> From<(db::LocalBusiness, &'v mut Vec<db::LocalBusinessItem>)> for LocalService {
|
||||
fn from((service, items): (db::LocalBusiness, &'v mut Vec<db::LocalBusinessItem>)) -> Self {
|
||||
Self {
|
||||
id: service.id,
|
||||
owner_id: service.owner_id,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::model::db;
|
||||
use crate::model::db::AccountType;
|
||||
use crate::model::view::Page;
|
||||
use crate::model::view::{self, Page};
|
||||
use crate::utils;
|
||||
use actix_files::Files;
|
||||
use actix_identity::Identity;
|
||||
@ -39,8 +39,8 @@ pub async fn index(db: Data<sqlx::PgPool>, id: Identity) -> HttpResponse {
|
||||
_ => None,
|
||||
};
|
||||
let (services, mut items) = {
|
||||
use crate::model::db::{LocalService, LocalServiceItem};
|
||||
let services: Vec<LocalService> = sqlx::query_as(
|
||||
use crate::model::db::{LocalBusiness, LocalBusinessItem};
|
||||
let services: Vec<LocalBusiness> = sqlx::query_as(
|
||||
r#"
|
||||
SELECT id, owner_id, name, description, state
|
||||
FROM local_services
|
||||
@ -58,7 +58,7 @@ ORDER BY id
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let items: Vec<LocalServiceItem> = sqlx::query_as(
|
||||
let items: Vec<LocalBusinessItem> = sqlx::query_as(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
@ -132,6 +132,9 @@ struct RegisterForm {
|
||||
password: String,
|
||||
facebook_id: Option<String>,
|
||||
account_type: db::AccountType,
|
||||
items: Option<Vec<view::BusinessItemInput>>,
|
||||
name: Option<String>,
|
||||
description: Option<String>,
|
||||
}
|
||||
|
||||
#[post("/register")]
|
||||
@ -143,13 +146,17 @@ async fn register(
|
||||
let form = form.into_inner();
|
||||
let pool = db.into_inner();
|
||||
if form.account_type == AccountType::Admin {
|
||||
return HttpResponse::BadRequest().body("Breach attempt detected!");
|
||||
return HttpResponse::BadRequest().body("Security breach attempt detected!");
|
||||
}
|
||||
|
||||
let mut t = pool.begin().await.unwrap();
|
||||
|
||||
let pass = match utils::encrypt(&form.password) {
|
||||
Ok(pass) => pass,
|
||||
Err(e) => {
|
||||
tracing::error!("{:?}", e);
|
||||
dbg!(e);
|
||||
t.rollback().await.unwrap();
|
||||
return HttpResponse::BadRequest().body(
|
||||
AccountTemplate {
|
||||
account: None,
|
||||
@ -165,7 +172,7 @@ async fn register(
|
||||
let res: sqlx::Result<db::Account> = sqlx::query_as(
|
||||
r#"
|
||||
INSERT INTO accounts (login, email, pass, facebook_id, account_type)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, login, email, pass, facebook_id, account_type
|
||||
"#,
|
||||
)
|
||||
@ -173,24 +180,19 @@ RETURNING id, login, email, pass, facebook_id, account_type
|
||||
.bind(form.email)
|
||||
.bind(pass)
|
||||
.bind(form.facebook_id)
|
||||
.fetch_one(&*pool)
|
||||
.bind(form.account_type)
|
||||
.fetch_one(&mut t)
|
||||
.await;
|
||||
match res {
|
||||
let account = match res {
|
||||
Ok(res) => {
|
||||
id.remember(format!("{}", res.id));
|
||||
HttpResponse::Ok().body(
|
||||
AccountTemplate {
|
||||
account: Some(res),
|
||||
error: None,
|
||||
page: Page::Register,
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
)
|
||||
res
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{e}");
|
||||
HttpResponse::BadRequest().body(
|
||||
tracing::error!("{e}");
|
||||
dbg!(e);
|
||||
t.rollback().await.unwrap();
|
||||
return HttpResponse::BadRequest().body(
|
||||
AccountTemplate {
|
||||
account: None,
|
||||
error: Some("Problem z utworzeniem konta".into()),
|
||||
@ -198,9 +200,92 @@ RETURNING id, login, email, pass, facebook_id, account_type
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if matches!(form.account_type, AccountType::Business) {
|
||||
let name = form.name.as_deref().unwrap_or_default();
|
||||
let owner_id = account.id;
|
||||
let description = form.description.as_deref().unwrap_or_default();
|
||||
|
||||
let res: sqlx::Result<db::LocalBusiness> = sqlx::query_as(
|
||||
r#"
|
||||
INSERT INTO local_services (name, owner_id, description)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, owner_id, name, description, state
|
||||
"#,
|
||||
)
|
||||
.bind(name)
|
||||
.bind(owner_id)
|
||||
.bind(description)
|
||||
.fetch_one(&mut t)
|
||||
.await;
|
||||
let business = match res {
|
||||
Ok(business) => business,
|
||||
Err(e) => {
|
||||
tracing::error!("{e}");
|
||||
dbg!(e);
|
||||
t.rollback().await.unwrap();
|
||||
return HttpResponse::BadRequest().body(
|
||||
AccountTemplate {
|
||||
account: None,
|
||||
error: Some("Problem z utworzeniem konta".into()),
|
||||
page: Page::Register,
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
for (idx, item) in form.items.as_deref().unwrap_or_default().iter().enumerate() {
|
||||
let res: sqlx::Result<db::LocalBusinessItem> = sqlx::query_as(
|
||||
r#"
|
||||
INSERT INTO local_service_items (local_service_id, name, price, item_order)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, local_service_id, name, price, item_order
|
||||
"#,
|
||||
)
|
||||
.bind(business.id)
|
||||
.bind(&item.name)
|
||||
.bind(item.price as i32)
|
||||
.bind(idx as i32)
|
||||
.fetch_one(&mut t)
|
||||
.await;
|
||||
match res {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
tracing::error!("{e}");
|
||||
dbg!(e);
|
||||
t.rollback().await.unwrap();
|
||||
return HttpResponse::BadRequest().body(
|
||||
AccountTemplate {
|
||||
account: None,
|
||||
error: Some("Problem z utworzeniem konta".into()),
|
||||
page: Page::Register,
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.commit().await.unwrap();
|
||||
|
||||
HttpResponse::SeeOther()
|
||||
.append_header(("Location", "/"))
|
||||
.body(
|
||||
AccountTemplate {
|
||||
account: Some(account),
|
||||
error: None,
|
||||
page: Page::Register,
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[post("/logout")]
|
||||
|
Loading…
Reference in New Issue
Block a user