created login page

This commit is contained in:
Fran Jurmanović
2021-05-30 13:29:30 +02:00
parent ffad98acd6
commit eb0cca567d
11 changed files with 230 additions and 66 deletions

View File

@@ -9,6 +9,7 @@ import { RouterService } from "core/services";
class AppLinkElement extends HTMLElement {
@closest appMain: AppMainElement;
@attr to: string;
@attr goBack: string;
@attr title: string;
@target main: Element;
routerService: RouterService;
@@ -17,27 +18,44 @@ class AppLinkElement extends HTMLElement {
}
public connectedCallback(): void {
this.update();
this.routerService = this.appMain?.routerService;
this.main.addEventListener("click", this.goTo);
this.update();
if (isTrue(this.goBack)) {
window.addEventListener("routechanged", () => {
this.update();
});
}
}
public disconnectedCallback(): void {
this.main.removeEventListener("click", this.goTo);
}
public disconnectedCallback(): void {}
goTo = () => {
this.routerService.goTo(this.to);
if (!isTrue(this.goBack) && this.to) {
this.routerService.goTo(this.to);
} else {
this.routerService.goBack();
}
this.update();
};
get disabled() {
return isTrue(this.goBack) && this.routerService.emptyState;
}
render() {
return html`${this.disabled
? html`<span data-target="app-link.main" style="color:grey"
>${this.title}</span
>`
: html`<span
data-target="app-link.main"
data-action="click:app-link#goTo"
style="text-decoration: underline; cursor: pointer;"
>${this.title}</span
>`}`;
}
update() {
render(
html`<span
data-target="app-link.main"
style="text-decoration: underline; cursor: pointer;"
>${this.title}</span
>`,
this
);
render(this.render(), this);
}
}

View File

@@ -11,11 +11,13 @@ class AppMainElement extends HTMLElement {
public authStore: AuthStore;
private httpClient: HttpClient;
public appService: AppService;
@closest appMain;
constructor() {
super();
}
connectedCallback() {
if (this.appMain !== this) return;
this.httpClient = new HttpClient();
this.appService = new AppService(this, this.httpClient);
this.routerService = new RouterService(this);
@@ -32,16 +34,22 @@ class AppMainElement extends HTMLElement {
component: "home-page",
},
{
path: "/rb",
path: "/register",
component: "register-page",
layout: "menu-layout",
},
{
path: "/login",
component: "login-page",
layout: "menu-layout",
},
{
path: "/unauthorized",
component: "register-page",
component: "login-page",
},
{
path: "token-expired",
component: "register-page",
component: "login-page",
},
]);
this.routerService.init();

View File

@@ -33,6 +33,10 @@ class InputFieldElement extends HTMLElement {
return !!this.error;
}
get required(): boolean {
return this.rules.includes("required");
}
@update
validate(): boolean {
let _return = true;
@@ -67,12 +71,14 @@ class InputFieldElement extends HTMLElement {
update() {
render(
html`<span data-target="input-field.main">
html`<div data-target="input-field.main">
${this.label &&
html`<label for="${this.randId}">${this.label}</label>`}
html`<label for="${this.randId}"
>${this.label}${this.required ? " (*)" : ""}</label
>`}
<input type="${this.type}" data-target="input-field.inp" />
${this.error && html`<span>${this.error}</span>`}
</span>`,
</div>`,
this
);
}

View File

@@ -46,7 +46,8 @@ class AuthStore {
userRegister = async (formObject) => {
try {
await this.authService.register(formObject);
const response = await this.authService.register(formObject);
return response;
} catch (err) {
throw err;
}

View File

@@ -1,3 +1,3 @@
export default function isTrue(bool: string) {
return bool === "true";
export default function isTrue(text: string) {
return text === "true";
}

View File

@@ -6,6 +6,8 @@ import { BaseLayoutElement } from "common/layouts";
@controller
class MenuLayoutElement extends BaseLayoutElement {
@closest appMain;
constructor() {
super();
}
@@ -13,13 +15,16 @@ class MenuLayoutElement extends BaseLayoutElement {
@update
connectedCallback() {}
render() {
return html`
<div>
<app-link data-go-back="true" data-title="Go back"></app-link>
</div>
<div data-target="menu-layout.slotted"></div>
`;
}
update() {
render(
html`
<div>Menu</div>
<div data-target="menu-layout.slotted"></div>
`,
this
);
render(this.render(), this);
}
}

View File

@@ -29,12 +29,15 @@ class HomePageElement extends HTMLElement {
return html`<div>${until(this.getPong())}</div>`;
};
render() {
return html`
<app-link data-to="/home" data-title="Home"></app-link> |
<app-link data-to="/" data-title="Main"></app-link> |
<app-link data-to="/login" data-title="Login"></app-link>
`;
}
update() {
render(
html`<app-link data-to="/home" data-title="Home"></app-link> |
<app-link data-to="/" data-title="Main"></app-link> |
<app-link data-to="/rb" data-title="$1"></app-link>`,
this
);
render(this.render(), this);
}
}

View File

@@ -1,2 +1,4 @@
export * from "./home-page/HomePageElement";
export * from "./register-page/RegisterPageElement";
export * from "./login-page/LoginPageElement";
export * from "./not-found/NotFoundElement";

View File

@@ -0,0 +1,87 @@
import { attr, targets, controller, target } from "@github/catalyst";
import { closest, index, update, isTrue } from "core/utils";
import { html, render, until } from "@github/jtml";
import { AuthService, PingService } from "services/";
import { AppMainElement, InputFieldElement } from "components/";
@controller
class LoginPageElement extends HTMLElement {
@targets inputs: Array<InputFieldElement>;
@closest appMain: AppMainElement;
authService: AuthService;
constructor() {
super();
}
@update
connectedCallback() {
this.authService = new AuthService(this.appMain.appService);
}
get values(): Object {
const formObject = {};
this.inputs.forEach((input: InputFieldElement) => {
const inputType = input.inp;
formObject[input.name] = (inputType as HTMLInputElement).value;
});
return formObject;
}
onSubmit = async () => {
try {
if (!this.validate()) {
return;
}
const response = await this.appMain.authStore.userLogin(
this.values
);
if (response?.token) {
this.appMain.routerService.goTo("/");
}
} catch (err) {}
};
validate(): boolean {
let _return = true;
this.inputs.forEach((input: InputFieldElement) => {
const valid: boolean = input.validate();
if (!valid) _return = false;
});
return _return;
}
render() {
return html`
<form>
<input-field
data-type="email"
data-name="email"
data-label="E-mail"
data-targets="login-page.inputs"
data-rules="required|isEmail"
></input-field>
<input-field
data-type="password"
data-name="password"
data-label="Password"
data-targets="login-page.inputs"
data-rules="required"
>
</input-field>
<button type="button" data-action="click:login-page#onSubmit">
Login
</button>
</form>
<div>
<app-link
data-to="/register"
data-title="Create new account"
></app-link>
</div>
`;
}
update() {
render(this.render(), this);
}
}

View File

@@ -0,0 +1,25 @@
import { controller } from "@github/catalyst";
import { closest, update } from "core/utils";
import { html, render } from "@github/jtml";
import { AppMainElement } from "components/";
@controller
class NotFoundElement extends HTMLElement {
@closest appMain: AppMainElement;
constructor() {
super();
}
@update
connectedCallback() {}
render() {
return html`
<div>404 - Page not found</div>
<div><app-link data-to="/" data-title="Homepage"></app-link></div>
`;
}
update() {
render(this.render(), this);
}
}

View File

@@ -31,12 +31,12 @@ class RegisterPageElement extends HTMLElement {
if (!this.validate()) {
return;
}
const response = await this.appMain.authStore.userLogin(
const response = await this.appMain.authStore.userRegister(
this.values
);
if (response?.token) {
this.appMain.routerService.goTo("/");
if (response?.id) {
this.appMain.routerService.goTo("/login");
}
} catch (err) {}
};
@@ -50,33 +50,42 @@ class RegisterPageElement extends HTMLElement {
return _return;
}
render() {
return html`
<form>
<input-field
data-type="text"
data-name="username"
data-label="Username"
data-targets="register-page.inputs"
data-rules="required"
></input-field>
<input-field
data-type="email"
data-name="email"
data-label="E-mail"
data-targets="register-page.inputs"
data-rules="required|isEmail"
></input-field>
<input-field
data-type="password"
data-name="password"
data-label="Password"
data-targets="register-page.inputs"
data-rules="required"
>
</input-field>
<button
type="button"
data-action="click:register-page#onSubmit"
>
Register
</button>
</form>
`;
}
update() {
render(
html`
<form>
<input-field
data-type="email"
data-name="email"
data-label="E-mail"
data-targets="register-page.inputs"
data-rules="required|isEmail"
></input-field>
<input-field
data-type="password"
data-name="password"
data-label="Password"
data-targets="register-page.inputs"
>
</input-field>
<button
type="button"
data-action="click:register-page#onSubmit"
>
Register
</button>
</form>
`,
this
);
render(this.render(), this);
}
}