1
0
Fork 0

Add tsx syntax to Login.

This commit is contained in:
Kitteh 2021-05-24 09:18:17 +01:00
parent 5b52fd34d6
commit 9648d6027f
4 changed files with 146 additions and 310 deletions

View file

@ -1,100 +0,0 @@
import { addClipboardNotifications } from "../pageUtils";
import { makeElement } from "z-makeelement";
import ClipboardJS from "clipboard";
import FileSaver from "file-saver";
import UIkit from "uikit";
import i18next from "i18next";
type FileSaverType = {
saveAs: (blob: Blob, name: string) => void;
};
type ModalType = HTMLElement & {
show: () => void;
};
export function CopyableModal(name: string, contentString: string): ModalType {
const modal = makeElement({
tag: "div",
class: "modal-sections",
attributes: {
"uk-modal": "",
},
children: makeElement({
tag: "div",
class: "uk-modal-dialog",
children: [
makeElement({
tag: "button",
class: "uk-modal-close-default",
attributes: {
"uk-close": "",
type: "button",
},
}),
makeElement({
tag: "div",
class: "uk-modal-header",
children: makeElement({
tag: "h2",
class: "uk-modal-title",
text: name,
}),
}),
makeElement({
tag: "div",
class: ["uk-modal-body"],
children: makeElement({
tag: "pre",
class: "wrap-pre",
text: contentString,
}),
}),
makeElement({
tag: "div",
class: ["uk-modal-footer", "uk-text-right"],
children: [
makeElement({
tag: "button",
class: ["uk-button", "uk-button-primary"],
attributes: {
type: "button",
"data-clipboard-text": contentString,
},
text: i18next.t("copy_modal_download_btn"),
onclick: () => {
const blob = new Blob([contentString], {
type: "text/plain;charset=utf-8",
});
(FileSaver as FileSaverType).saveAs(blob, "result.txt");
},
}),
makeElement({
tag: "button",
class: ["uk-button", "uk-button-primary"],
attributes: {
type: "button",
"data-clipboard-text": contentString,
},
text: i18next.t("copy_modal_copy_btn"),
thenRun: (e) => {
const clipboard = new ClipboardJS(e);
addClipboardNotifications(clipboard);
},
}),
makeElement({
tag: "button",
class: ["uk-button", "uk-button-secondary", "uk-modal-close"],
attributes: { type: "button" },
text: i18next.t("copy_modal_close_btn"),
}),
],
}),
],
}),
}) as ModalType;
modal.show = () => {
UIkit.modal(modal).show();
};
return modal;
}

View file

@ -1,38 +0,0 @@
import { makeElement } from "z-makeelement";
import i18next from "i18next";
export function FileUploadInput(name: string): Element {
const fileInput = makeElement({
tag: "input",
attributes: {
name: name,
type: "file",
},
});
const selectInput = makeElement({
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
type: "text",
placeholder: i18next.t("file_upload_input_btn"),
},
});
const fileIcon = makeElement({
tag: "a",
class: "uk-form-icon",
attributes: {
"uk-icon": "icon: upload",
role: "img",
},
});
return makeElement({
tag: "div",
attributes: {
"uk-form-custom": "target: true",
},
children: [fileIcon, fileInput, selectInput],
});
}

View file

@ -1,172 +0,0 @@
import { Form } from "../elements/Form";
import { Margin } from "../elements/Margin";
import { MarginInline } from "../elements/MarginInline";
import { Page } from "../types/Page";
import { lookupSelf } from "../api/sys/lookupSelf";
import { makeElement } from "z-makeelement";
import { setErrorText } from "../pageUtils";
import { usernameLogin } from "../api/auth/usernameLogin";
import i18next from "i18next";
export class LoginPage extends Page {
constructor() {
super();
}
async render(): Promise<void> {
const tokenLoginForm = Form(
[
Margin(
makeElement({
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: "true",
type: "password",
placeholder: i18next.t("token_input"),
name: "token",
},
}),
),
MarginInline(
makeElement({
tag: "button",
class: ["uk-button", "uk-button-primary"],
text: i18next.t("log_in_btn"),
attributes: {
type: "submit",
},
}),
),
],
async (form: HTMLFormElement) => {
const formData = new FormData(form);
const token = formData.get("token");
this.state.token = token as string;
try {
await lookupSelf();
await this.router.changePage("HOME");
} catch (e: unknown) {
const error = e as Error;
document.getElementById("tokenInput").classList.add("uk-form-danger");
if (error.message == "permission denied") {
setErrorText(i18next.t("token_login_error"));
} else {
setErrorText(error.message);
}
}
},
);
const usernameLoginForm = Form(
[
Margin(
makeElement({
tag: "input",
id: "usernameInput",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: "true",
type: "text",
placeholder: i18next.t("username_input"),
name: "username",
},
}),
),
Margin(
makeElement({
tag: "input",
id: "passwordInput",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: "true",
type: "password",
placeholder: i18next.t("password_input"),
name: "password",
},
}),
),
MarginInline(
makeElement({
tag: "button",
class: ["uk-button", "uk-button-primary"],
text: i18next.t("log_in_btn"),
attributes: {
type: "submit",
},
}),
),
],
async (form: HTMLFormElement) => {
const formData = new FormData(form);
try {
const res = await usernameLogin(
formData.get("username") as string,
formData.get("password") as string,
);
this.state.token = res;
await this.router.changePage("HOME");
} catch (e: unknown) {
const error = e as Error;
document.getElementById("usernameInput").classList.add("uk-form-danger");
document.getElementById("passwordInput").classList.add("uk-form-danger");
setErrorText(error.message);
}
},
);
await this.router.setPageContent(
makeElement({
tag: "div",
children: [
makeElement({
tag: "ul",
class: ["uk-subnav", "uk-subnav-pill"],
attributes: { "uk-switcher": "" },
children: [
makeElement({
tag: "li",
id: "tokenInput",
children: makeElement({
tag: "a",
text: i18next.t("log_in_with_token"),
}),
}),
makeElement({
tag: "li",
children: makeElement({
tag: "a",
text: i18next.t("log_in_with_username"),
}),
}),
],
}),
makeElement({
tag: "p",
id: "errorText",
class: "uk-text-danger",
}),
makeElement({
tag: "ul",
class: ["uk-switcher", "uk-margin"],
children: [
makeElement({
tag: "li",
children: tokenLoginForm,
}),
makeElement({
tag: "li",
children: usernameLoginForm,
}),
],
}),
],
}),
);
}
get name(): string {
return i18next.t("log_in_title");
}
}

146
src/pages/Login.tsx Normal file
View file

@ -0,0 +1,146 @@
import { Component, JSX, render } from "preact";
import { Form } from "../elements/ReactForm";
import { Margin } from "../elements/ReactMargin";
import { MarginInline } from "../elements/ReactMarginInline";
import { Page } from "../types/Page";
import { lookupSelf } from "../api/sys/lookupSelf";
import { setErrorText } from "../pageUtils";
import { usernameLogin } from "../api/auth/usernameLogin";
import i18next from "i18next";
export class TokenLoginForm extends Component<{ page: Page }, unknown> {
constructor() {
super();
}
render(): JSX.Element {
return (
<Form onSubmit={(data) => this.onSubmit(data)}>
<Margin>
<input
class="uk-input uk-form-width-medium"
id="tokenInput"
name="token"
type="password"
placeholder={i18next.t("token_input")}
required
/>
</Margin>
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("log_in_btn")}
</button>
</MarginInline>
</Form>
);
}
async onSubmit(data: FormData): Promise<void> {
const page = this.props.page;
const token = data.get("token");
page.state.token = token as string;
try {
await lookupSelf();
await page.router.changePage("HOME");
} catch (e: unknown) {
const error = e as Error;
document.getElementById("tokenInput").classList.add("uk-form-danger");
if (error.message == "permission denied") {
setErrorText(i18next.t("token_login_error"));
} else {
setErrorText(error.message);
}
}
}
}
export class UsernameLoginForm extends Component<{ page: Page }, unknown> {
constructor() {
super();
}
render(): JSX.Element {
return (
<Form onSubmit={(data) => this.onSubmit(data)}>
<Margin>
<input
class="uk-input uk-form-width-medium"
id="usernameInput"
name="username"
type="text"
placeholder={i18next.t("username_input")}
required
/>
</Margin>
<Margin>
<input
class="uk-input uk-form-width-medium"
id="passwordInput"
name="password"
type="password"
placeholder={i18next.t("password_input")}
required
/>
</Margin>
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("log_in_btn")}
</button>
</MarginInline>
</Form>
);
}
async onSubmit(data: FormData): Promise<void> {
const page = this.props.page;
try {
const res = await usernameLogin(
data.get("username") as string,
data.get("password") as string,
);
page.state.token = res;
await page.router.changePage("HOME");
} catch (e: unknown) {
const error = e as Error;
document.getElementById("usernameInput").classList.add("uk-form-danger");
document.getElementById("passwordInput").classList.add("uk-form-danger");
setErrorText(error.message);
}
}
}
export class LoginPage extends Page {
constructor() {
super();
}
async render(): Promise<void> {
render(
<div>
<ul class="uk-subnav uk-subnav-pill" uk-switcher=".switcher-container">
<li>
<a>{i18next.t("log_in_with_token")}</a>
</li>
<li>
<a>{i18next.t("log_in_with_username")}</a>
</li>
</ul>
<p id="errorText" class="uk-text-danger" />
<ul class="uk-switcher uk-margin switcher-container">
<li>
<TokenLoginForm page={this} />
</li>
<li>
<UsernameLoginForm page={this} />
</li>
</ul>
</div>,
this.router.pageContentElement,
);
}
get name(): string {
return i18next.t("log_in_title");
}
}