Add tsx syntax to Login.
This commit is contained in:
parent
5b52fd34d6
commit
9648d6027f
|
@ -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;
|
||||
}
|
|
@ -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],
|
||||
});
|
||||
}
|
|
@ -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
146
src/pages/Login.tsx
Normal 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");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue