aboutsummaryrefslogtreecommitdiff
path: root/packages/anastasis-webui/src/components
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-11-10 10:20:52 -0300
committerSebastian <sebasjm@gmail.com>2021-11-10 11:57:11 -0300
commita62deeef5d0cbe5fa98be390eac0e03bcae0f0b5 (patch)
treeb7e5f4944b3c19bcdb267a95701f1b9ad6fdac16 /packages/anastasis-webui/src/components
parente03b0d1b9b60dbafe6b70db3bd07158cd65773e5 (diff)
downloadwallet-core-a62deeef5d0cbe5fa98be390eac0e03bcae0f0b5.tar.xz
prettier
Diffstat (limited to 'packages/anastasis-webui/src/components')
-rw-r--r--packages/anastasis-webui/src/components/AsyncButton.tsx27
-rw-r--r--packages/anastasis-webui/src/components/Notifications.tsx59
-rw-r--r--packages/anastasis-webui/src/components/QR.tsx27
-rw-r--r--packages/anastasis-webui/src/components/app.tsx1
-rw-r--r--packages/anastasis-webui/src/components/fields/DateInput.tsx104
-rw-r--r--packages/anastasis-webui/src/components/fields/EmailInput.tsx49
-rw-r--r--packages/anastasis-webui/src/components/fields/FileInput.tsx92
-rw-r--r--packages/anastasis-webui/src/components/fields/ImageInput.tsx96
-rw-r--r--packages/anastasis-webui/src/components/fields/TextInput.tsx45
-rw-r--r--packages/anastasis-webui/src/components/menu/LangSelector.tsx99
-rw-r--r--packages/anastasis-webui/src/components/menu/SideBar.tsx302
-rw-r--r--packages/anastasis-webui/src/components/menu/index.tsx6
-rw-r--r--packages/anastasis-webui/src/components/picker/DatePicker.tsx314
-rw-r--r--packages/anastasis-webui/src/components/picker/DurationPicker.stories.tsx45
-rw-r--r--packages/anastasis-webui/src/components/picker/DurationPicker.tsx217
15 files changed, 895 insertions, 588 deletions
diff --git a/packages/anastasis-webui/src/components/AsyncButton.tsx b/packages/anastasis-webui/src/components/AsyncButton.tsx
index 92bef2219..33f3a7258 100644
--- a/packages/anastasis-webui/src/components/AsyncButton.tsx
+++ b/packages/anastasis-webui/src/components/AsyncButton.tsx
@@ -15,9 +15,9 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { ComponentChildren, h, VNode } from "preact";
// import { LoadingModal } from "../modal";
@@ -31,19 +31,26 @@ type Props = {
[rest: string]: any;
};
-export function AsyncButton({ onClick, disabled, children, ...rest }: Props): VNode {
+export function AsyncButton({
+ onClick,
+ disabled,
+ children,
+ ...rest
+}: Props): VNode {
const { isLoading, request } = useAsync(onClick);
// if (isSlow) {
// return <LoadingModal onCancel={cancel} />;
// }
- if (isLoading) {
+ if (isLoading) {
return <button class="button">Loading...</button>;
}
- return <span data-tooltip={rest['data-tooltip']} style={{marginLeft: 5}}>
- <button {...rest} onClick={request} disabled={disabled}>
- {children}
- </button>
- </span>;
+ return (
+ <span data-tooltip={rest["data-tooltip"]} style={{ marginLeft: 5 }}>
+ <button {...rest} onClick={request} disabled={disabled}>
+ {children}
+ </button>
+ </span>
+ );
}
diff --git a/packages/anastasis-webui/src/components/Notifications.tsx b/packages/anastasis-webui/src/components/Notifications.tsx
index 097ebb4de..e34550386 100644
--- a/packages/anastasis-webui/src/components/Notifications.tsx
+++ b/packages/anastasis-webui/src/components/Notifications.tsx
@@ -15,9 +15,9 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, VNode } from "preact";
@@ -27,7 +27,7 @@ export interface Notification {
type: MessageType;
}
-export type MessageType = 'INFO' | 'WARN' | 'ERROR' | 'SUCCESS'
+export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS";
interface Props {
notifications: Notification[];
@@ -36,24 +36,39 @@ interface Props {
function messageStyle(type: MessageType): string {
switch (type) {
- case "INFO": return "message is-info";
- case "WARN": return "message is-warning";
- case "ERROR": return "message is-danger";
- case "SUCCESS": return "message is-success";
- default: return "message"
+ case "INFO":
+ return "message is-info";
+ case "WARN":
+ return "message is-warning";
+ case "ERROR":
+ return "message is-danger";
+ case "SUCCESS":
+ return "message is-success";
+ default:
+ return "message";
}
}
-export function Notifications({ notifications, removeNotification }: Props): VNode {
- return <div class="block">
- {notifications.map((n, i) => <article key={i} class={messageStyle(n.type)}>
- <div class="message-header">
- <p>{n.message}</p>
- {removeNotification && <button class="delete" onClick={() => removeNotification && removeNotification(n)} />}
- </div>
- {n.description && <div class="message-body">
- {n.description}
- </div>}
- </article>)}
- </div>
-} \ No newline at end of file
+export function Notifications({
+ notifications,
+ removeNotification,
+}: Props): VNode {
+ return (
+ <div class="block">
+ {notifications.map((n, i) => (
+ <article key={i} class={messageStyle(n.type)}>
+ <div class="message-header">
+ <p>{n.message}</p>
+ {removeNotification && (
+ <button
+ class="delete"
+ onClick={() => removeNotification && removeNotification(n)}
+ />
+ )}
+ </div>
+ {n.description && <div class="message-body">{n.description}</div>}
+ </article>
+ ))}
+ </div>
+ );
+}
diff --git a/packages/anastasis-webui/src/components/QR.tsx b/packages/anastasis-webui/src/components/QR.tsx
index 48f1a7c12..9a05f6097 100644
--- a/packages/anastasis-webui/src/components/QR.tsx
+++ b/packages/anastasis-webui/src/components/QR.tsx
@@ -21,15 +21,28 @@ import qrcode from "qrcode-generator";
export function QR({ text }: { text: string }): VNode {
const divRef = useRef<HTMLDivElement>(null);
useEffect(() => {
- const qr = qrcode(0, 'L');
+ const qr = qrcode(0, "L");
qr.addData(text);
qr.make();
- if (divRef.current) divRef.current.innerHTML = qr.createSvgTag({
- scalable: true,
- });
+ if (divRef.current)
+ divRef.current.innerHTML = qr.createSvgTag({
+ scalable: true,
+ });
});
- return <div style={{ width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
- <div style={{ width: '50%', minWidth: 200, maxWidth: 300 }} ref={divRef} />
- </div>;
+ return (
+ <div
+ style={{
+ width: "100%",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ }}
+ >
+ <div
+ style={{ width: "50%", minWidth: 200, maxWidth: 300 }}
+ ref={divRef}
+ />
+ </div>
+ );
}
diff --git a/packages/anastasis-webui/src/components/app.tsx b/packages/anastasis-webui/src/components/app.tsx
index c6b4cfc14..4c6683c0c 100644
--- a/packages/anastasis-webui/src/components/app.tsx
+++ b/packages/anastasis-webui/src/components/app.tsx
@@ -1,6 +1,5 @@
import { FunctionalComponent, h } from "preact";
import { TranslationProvider } from "../context/translation";
-
import AnastasisClient from "../pages/home";
const App: FunctionalComponent = () => {
diff --git a/packages/anastasis-webui/src/components/fields/DateInput.tsx b/packages/anastasis-webui/src/components/fields/DateInput.tsx
index 3148c953f..0b6a7e316 100644
--- a/packages/anastasis-webui/src/components/fields/DateInput.tsx
+++ b/packages/anastasis-webui/src/components/fields/DateInput.tsx
@@ -19,56 +19,66 @@ export function DateInput(props: DateInputProps): VNode {
inputRef.current?.focus();
}
}, [props.grabFocus]);
- const [opened, setOpened] = useState(false)
+ const [opened, setOpened] = useState(false);
const value = props.bind[0] || "";
- const [dirty, setDirty] = useState(false)
- const showError = dirty && props.error
+ const [dirty, setDirty] = useState(false);
+ const showError = dirty && props.error;
- const calendar = subYears(new Date(), 30)
-
- return <div class="field">
- <label class="label">
- {props.label}
- {props.tooltip && <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
- <i class="mdi mdi-information" />
- </span>}
- </label>
- <div class="control">
- <div class="field has-addons">
- <p class="control">
- <input
- type="text"
- class={showError ? 'input is-danger' : 'input'}
- value={value}
- onInput={(e) => {
- const text = e.currentTarget.value
- setDirty(true)
- props.bind[1](text);
- }}
- ref={inputRef} />
- </p>
- <p class="control">
- <a class="button" onClick={() => { setOpened(true) }}>
- <span class="icon"><i class="mdi mdi-calendar" /></span>
- </a>
- </p>
+ const calendar = subYears(new Date(), 30);
+
+ return (
+ <div class="field">
+ <label class="label">
+ {props.label}
+ {props.tooltip && (
+ <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+ <i class="mdi mdi-information" />
+ </span>
+ )}
+ </label>
+ <div class="control">
+ <div class="field has-addons">
+ <p class="control">
+ <input
+ type="text"
+ class={showError ? "input is-danger" : "input"}
+ value={value}
+ onInput={(e) => {
+ const text = e.currentTarget.value;
+ setDirty(true);
+ props.bind[1](text);
+ }}
+ ref={inputRef}
+ />
+ </p>
+ <p class="control">
+ <a
+ class="button"
+ onClick={() => {
+ setOpened(true);
+ }}
+ >
+ <span class="icon">
+ <i class="mdi mdi-calendar" />
+ </span>
+ </a>
+ </p>
+ </div>
</div>
+ <p class="help">Using the format yyyy-mm-dd</p>
+ {showError && <p class="help is-danger">{props.error}</p>}
+ <DatePicker
+ opened={opened}
+ initialDate={calendar}
+ years={props.years}
+ closeFunction={() => setOpened(false)}
+ dateReceiver={(d) => {
+ setDirty(true);
+ const v = format(d, "yyyy-MM-dd");
+ props.bind[1](v);
+ }}
+ />
</div>
- <p class="help">Using the format yyyy-mm-dd</p>
- {showError && <p class="help is-danger">{props.error}</p>}
- <DatePicker
- opened={opened}
- initialDate={calendar}
- years={props.years}
- closeFunction={() => setOpened(false)}
- dateReceiver={(d) => {
- setDirty(true)
- const v = format(d, 'yyyy-MM-dd')
- props.bind[1](v);
- }}
- />
- </div>
- ;
-
+ );
}
diff --git a/packages/anastasis-webui/src/components/fields/EmailInput.tsx b/packages/anastasis-webui/src/components/fields/EmailInput.tsx
index e21418fea..fe676f284 100644
--- a/packages/anastasis-webui/src/components/fields/EmailInput.tsx
+++ b/packages/anastasis-webui/src/components/fields/EmailInput.tsx
@@ -18,27 +18,34 @@ export function EmailInput(props: TextInputProps): VNode {
}
}, [props.grabFocus]);
const value = props.bind[0];
- const [dirty, setDirty] = useState(false)
- const showError = dirty && props.error
- return (<div class="field">
- <label class="label">
- {props.label}
- {props.tooltip && <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
- <i class="mdi mdi-information" />
- </span>}
- </label>
- <div class="control has-icons-right">
- <input
- value={value}
- required
- placeholder={props.placeholder}
- type="email"
- class={showError ? 'input is-danger' : 'input'}
- onInput={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}}
- ref={inputRef}
- style={{ display: "block" }} />
+ const [dirty, setDirty] = useState(false);
+ const showError = dirty && props.error;
+ return (
+ <div class="field">
+ <label class="label">
+ {props.label}
+ {props.tooltip && (
+ <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+ <i class="mdi mdi-information" />
+ </span>
+ )}
+ </label>
+ <div class="control has-icons-right">
+ <input
+ value={value}
+ required
+ placeholder={props.placeholder}
+ type="email"
+ class={showError ? "input is-danger" : "input"}
+ onInput={(e) => {
+ setDirty(true);
+ props.bind[1]((e.target as HTMLInputElement).value);
+ }}
+ ref={inputRef}
+ style={{ display: "block" }}
+ />
+ </div>
+ {showError && <p class="help is-danger">{props.error}</p>}
</div>
- {showError && <p class="help is-danger">{props.error}</p>}
- </div>
);
}
diff --git a/packages/anastasis-webui/src/components/fields/FileInput.tsx b/packages/anastasis-webui/src/components/fields/FileInput.tsx
index 8b144ea43..52d6eab4a 100644
--- a/packages/anastasis-webui/src/components/fields/FileInput.tsx
+++ b/packages/anastasis-webui/src/components/fields/FileInput.tsx
@@ -15,14 +15,14 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, VNode } from "preact";
import { useLayoutEffect, useRef, useState } from "preact/hooks";
import { TextInputProps } from "./TextInput";
-const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024
+const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024;
export function FileInput(props: TextInputProps): VNode {
const inputRef = useRef<HTMLInputElement>(null);
@@ -34,48 +34,54 @@ export function FileInput(props: TextInputProps): VNode {
const value = props.bind[0];
// const [dirty, setDirty] = useState(false)
- const image = useRef<HTMLInputElement>(null)
- const [sizeError, setSizeError] = useState(false)
+ const image = useRef<HTMLInputElement>(null);
+ const [sizeError, setSizeError] = useState(false);
function onChange(v: string): void {
// setDirty(true);
props.bind[1](v);
}
- return <div class="field">
- <label class="label">
- <a onClick={() => image.current?.click()}>
- {props.label}
- </a>
- {props.tooltip && <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
- <i class="mdi mdi-information" />
- </span>}
- </label>
- <div class="control">
- <input
- ref={image} style={{ display: 'none' }}
- type="file" name={String(name)}
- onChange={e => {
- const f: FileList | null = e.currentTarget.files
- if (!f || f.length != 1) {
- return onChange("")
- }
- if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
- setSizeError(true)
- return onChange("")
- }
- setSizeError(false)
- return f[0].arrayBuffer().then(b => {
- const b64 = btoa(
- new Uint8Array(b)
- .reduce((data, byte) => data + String.fromCharCode(byte), '')
- )
- return onChange(`data:${f[0].type};base64,${b64}` as any)
- })
- }} />
- {props.error && <p class="help is-danger">{props.error}</p>}
- {sizeError && <p class="help is-danger">
- File should be smaller than 1 MB
- </p>}
+ return (
+ <div class="field">
+ <label class="label">
+ <a onClick={() => image.current?.click()}>{props.label}</a>
+ {props.tooltip && (
+ <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+ <i class="mdi mdi-information" />
+ </span>
+ )}
+ </label>
+ <div class="control">
+ <input
+ ref={image}
+ style={{ display: "none" }}
+ type="file"
+ name={String(name)}
+ onChange={(e) => {
+ const f: FileList | null = e.currentTarget.files;
+ if (!f || f.length != 1) {
+ return onChange("");
+ }
+ if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
+ setSizeError(true);
+ return onChange("");
+ }
+ setSizeError(false);
+ return f[0].arrayBuffer().then((b) => {
+ const b64 = btoa(
+ new Uint8Array(b).reduce(
+ (data, byte) => data + String.fromCharCode(byte),
+ "",
+ ),
+ );
+ return onChange(`data:${f[0].type};base64,${b64}` as any);
+ });
+ }}
+ />
+ {props.error && <p class="help is-danger">{props.error}</p>}
+ {sizeError && (
+ <p class="help is-danger">File should be smaller than 1 MB</p>
+ )}
+ </div>
</div>
- </div>
+ );
}
-
diff --git a/packages/anastasis-webui/src/components/fields/ImageInput.tsx b/packages/anastasis-webui/src/components/fields/ImageInput.tsx
index d5bf643d4..3f8cc58dd 100644
--- a/packages/anastasis-webui/src/components/fields/ImageInput.tsx
+++ b/packages/anastasis-webui/src/components/fields/ImageInput.tsx
@@ -15,15 +15,15 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, VNode } from "preact";
import { useLayoutEffect, useRef, useState } from "preact/hooks";
import emptyImage from "../../assets/empty.png";
import { TextInputProps } from "./TextInput";
-const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024
+const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024;
export function ImageInput(props: TextInputProps): VNode {
const inputRef = useRef<HTMLInputElement>(null);
@@ -35,47 +35,59 @@ export function ImageInput(props: TextInputProps): VNode {
const value = props.bind[0];
// const [dirty, setDirty] = useState(false)
- const image = useRef<HTMLInputElement>(null)
- const [sizeError, setSizeError] = useState(false)
+ const image = useRef<HTMLInputElement>(null);
+ const [sizeError, setSizeError] = useState(false);
function onChange(v: string): void {
// setDirty(true);
props.bind[1](v);
}
- return <div class="field">
- <label class="label">
- {props.label}
- {props.tooltip && <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
- <i class="mdi mdi-information" />
- </span>}
- </label>
- <div class="control">
- <img src={!value ? emptyImage : value} style={{ width: 200, height: 200 }} onClick={() => image.current?.click()} />
- <input
- ref={image} style={{ display: 'none' }}
- type="file" name={String(name)}
- onChange={e => {
- const f: FileList | null = e.currentTarget.files
- if (!f || f.length != 1) {
- return onChange(emptyImage)
- }
- if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
- setSizeError(true)
- return onChange(emptyImage)
- }
- setSizeError(false)
- return f[0].arrayBuffer().then(b => {
- const b64 = btoa(
- new Uint8Array(b)
- .reduce((data, byte) => data + String.fromCharCode(byte), '')
- )
- return onChange(`data:${f[0].type};base64,${b64}` as any)
- })
- }} />
- {props.error && <p class="help is-danger">{props.error}</p>}
- {sizeError && <p class="help is-danger">
- Image should be smaller than 1 MB
- </p>}
+ return (
+ <div class="field">
+ <label class="label">
+ {props.label}
+ {props.tooltip && (
+ <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+ <i class="mdi mdi-information" />
+ </span>
+ )}
+ </label>
+ <div class="control">
+ <img
+ src={!value ? emptyImage : value}
+ style={{ width: 200, height: 200 }}
+ onClick={() => image.current?.click()}
+ />
+ <input
+ ref={image}
+ style={{ display: "none" }}
+ type="file"
+ name={String(name)}
+ onChange={(e) => {
+ const f: FileList | null = e.currentTarget.files;
+ if (!f || f.length != 1) {
+ return onChange(emptyImage);
+ }
+ if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
+ setSizeError(true);
+ return onChange(emptyImage);
+ }
+ setSizeError(false);
+ return f[0].arrayBuffer().then((b) => {
+ const b64 = btoa(
+ new Uint8Array(b).reduce(
+ (data, byte) => data + String.fromCharCode(byte),
+ "",
+ ),
+ );
+ return onChange(`data:${f[0].type};base64,${b64}` as any);
+ });
+ }}
+ />
+ {props.error && <p class="help is-danger">{props.error}</p>}
+ {sizeError && (
+ <p class="help is-danger">Image should be smaller than 1 MB</p>
+ )}
+ </div>
</div>
- </div>
+ );
}
-
diff --git a/packages/anastasis-webui/src/components/fields/TextInput.tsx b/packages/anastasis-webui/src/components/fields/TextInput.tsx
index c093689c5..fd0c658ed 100644
--- a/packages/anastasis-webui/src/components/fields/TextInput.tsx
+++ b/packages/anastasis-webui/src/components/fields/TextInput.tsx
@@ -18,25 +18,32 @@ export function TextInput(props: TextInputProps): VNode {
}
}, [props.grabFocus]);
const value = props.bind[0];
- const [dirty, setDirty] = useState(false)
- const showError = dirty && props.error
- return (<div class="field">
- <label class="label">
- {props.label}
- {props.tooltip && <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
- <i class="mdi mdi-information" />
- </span>}
- </label>
- <div class="control has-icons-right">
- <input
- value={value}
- placeholder={props.placeholder}
- class={showError ? 'input is-danger' : 'input'}
- onInput={(e) => {setDirty(true); props.bind[1]((e.target as HTMLInputElement).value)}}
- ref={inputRef}
- style={{ display: "block" }} />
+ const [dirty, setDirty] = useState(false);
+ const showError = dirty && props.error;
+ return (
+ <div class="field">
+ <label class="label">
+ {props.label}
+ {props.tooltip && (
+ <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+ <i class="mdi mdi-information" />
+ </span>
+ )}
+ </label>
+ <div class="control has-icons-right">
+ <input
+ value={value}
+ placeholder={props.placeholder}
+ class={showError ? "input is-danger" : "input"}
+ onInput={(e) => {
+ setDirty(true);
+ props.bind[1]((e.target as HTMLInputElement).value);
+ }}
+ ref={inputRef}
+ style={{ display: "block" }}
+ />
+ </div>
+ {showError && <p class="help is-danger">{props.error}</p>}
</div>
- {showError && <p class="help is-danger">{props.error}</p>}
- </div>
);
}
diff --git a/packages/anastasis-webui/src/components/menu/LangSelector.tsx b/packages/anastasis-webui/src/components/menu/LangSelector.tsx
index 0f91abd7e..fa22a29c0 100644
--- a/packages/anastasis-webui/src/components/menu/LangSelector.tsx
+++ b/packages/anastasis-webui/src/components/menu/LangSelector.tsx
@@ -15,59 +15,78 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
-import langIcon from '../../assets/icons/languageicon.svg';
+import langIcon from "../../assets/icons/languageicon.svg";
import { useTranslationContext } from "../../context/translation";
-import { strings as messages } from '../../i18n/strings'
+import { strings as messages } from "../../i18n/strings";
type LangsNames = {
- [P in keyof typeof messages]: string
-}
+ [P in keyof typeof messages]: string;
+};
const names: LangsNames = {
- es: 'Español [es]',
- en: 'English [en]',
- fr: 'Français [fr]',
- de: 'Deutsch [de]',
- sv: 'Svenska [sv]',
- it: 'Italiano [it]',
-}
+ es: "Español [es]",
+ en: "English [en]",
+ fr: "Français [fr]",
+ de: "Deutsch [de]",
+ sv: "Svenska [sv]",
+ it: "Italiano [it]",
+};
function getLangName(s: keyof LangsNames | string): string {
- if (names[s]) return names[s]
- return String(s)
+ if (names[s]) return names[s];
+ return String(s);
}
export function LangSelector(): VNode {
- const [updatingLang, setUpdatingLang] = useState(false)
- const { lang, changeLanguage } = useTranslationContext()
+ const [updatingLang, setUpdatingLang] = useState(false);
+ const { lang, changeLanguage } = useTranslationContext();
- return <div class="dropdown is-active ">
- <div class="dropdown-trigger">
- <button class="button has-tooltip-left"
- data-tooltip="change language selection"
- aria-haspopup="true"
- aria-controls="dropdown-menu" onClick={() => setUpdatingLang(!updatingLang)}>
- <div class="icon is-small is-left">
- <img src={langIcon} />
- </div>
- <span>{getLangName(lang)}</span>
- <div class="icon is-right">
- <i class="mdi mdi-chevron-down" />
+ return (
+ <div class="dropdown is-active ">
+ <div class="dropdown-trigger">
+ <button
+ class="button has-tooltip-left"
+ data-tooltip="change language selection"
+ aria-haspopup="true"
+ aria-controls="dropdown-menu"
+ onClick={() => setUpdatingLang(!updatingLang)}
+ >
+ <div class="icon is-small is-left">
+ <img src={langIcon} />
+ </div>
+ <span>{getLangName(lang)}</span>
+ <div class="icon is-right">
+ <i class="mdi mdi-chevron-down" />
+ </div>
+ </button>
+ </div>
+ {updatingLang && (
+ <div class="dropdown-menu" id="dropdown-menu" role="menu">
+ <div class="dropdown-content">
+ {Object.keys(messages)
+ .filter((l) => l !== lang)
+ .map((l) => (
+ <a
+ key={l}
+ class="dropdown-item"
+ value={l}
+ onClick={() => {
+ changeLanguage(l);
+ setUpdatingLang(false);
+ }}
+ >
+ {getLangName(l)}
+ </a>
+ ))}
+ </div>
</div>
- </button>
+ )}
</div>
- {updatingLang && <div class="dropdown-menu" id="dropdown-menu" role="menu">
- <div class="dropdown-content">
- {Object.keys(messages)
- .filter((l) => l !== lang)
- .map(l => <a key={l} class="dropdown-item" value={l} onClick={() => { changeLanguage(l); setUpdatingLang(false) }}>{getLangName(l)}</a>)}
- </div>
- </div>}
- </div>
-} \ No newline at end of file
+ );
+}
diff --git a/packages/anastasis-webui/src/components/menu/SideBar.tsx b/packages/anastasis-webui/src/components/menu/SideBar.tsx
index a40f4be09..c73369dd6 100644
--- a/packages/anastasis-webui/src/components/menu/SideBar.tsx
+++ b/packages/anastasis-webui/src/components/menu/SideBar.tsx
@@ -15,16 +15,15 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
-import { Fragment, h, VNode } from 'preact';
-import { BackupStates, RecoveryStates } from '../../../../anastasis-core/lib';
-import { useAnastasisContext } from '../../context/anastasis';
-import { Translate } from '../../i18n';
-import { LangSelector } from './LangSelector';
+import { Fragment, h, VNode } from "preact";
+import { BackupStates, RecoveryStates } from "../../../../anastasis-core/lib";
+import { useAnastasisContext } from "../../context/anastasis";
+import { Translate } from "../../i18n";
+import { LangSelector } from "./LangSelector";
interface Props {
mobile?: boolean;
@@ -32,10 +31,10 @@ interface Props {
export function Sidebar({ mobile }: Props): VNode {
// const config = useConfigContext();
- const config = { version: 'none' }
+ const config = { version: "none" };
// FIXME: add replacement for __VERSION__ with the current version
- const process = { env: { __VERSION__: '0.0.0' } }
- const reducer = useAnastasisContext()!
+ const process = { env: { __VERSION__: "0.0.0" } };
+ const reducer = useAnastasisContext()!;
return (
<aside class="aside is-placed-left is-expanded">
@@ -44,114 +43,235 @@ export function Sidebar({ mobile }: Props): VNode {
</div>} */}
<div class="aside-tools">
<div class="aside-tools-label">
- <div><b>Anastasis</b></div>
- <div class="is-size-7 has-text-right" style={{ lineHeight: 0, marginTop: -10 }}>
+ <div>
+ <b>Anastasis</b>
+ </div>
+ <div
+ class="is-size-7 has-text-right"
+ style={{ lineHeight: 0, marginTop: -10 }}
+ >
Version {process.env.__VERSION__} ({config.version})
</div>
</div>
</div>
<div class="menu is-menu-main">
- {!reducer.currentReducerState &&
+ {!reducer.currentReducerState && (
<p class="menu-label">
<Translate>Backup or Recorver</Translate>
</p>
- }
+ )}
<ul class="menu-list">
- {!reducer.currentReducerState &&
+ {!reducer.currentReducerState && (
<li>
<div class="ml-4">
- <span class="menu-item-label"><Translate>Select one option</Translate></span>
- </div>
- </li>
- }
- {reducer.currentReducerState && reducer.currentReducerState.backup_state ? <Fragment>
- <li class={reducer.currentReducerState.backup_state === BackupStates.ContinentSelecting ||
- reducer.currentReducerState.backup_state === BackupStates.CountrySelecting ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Location</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.backup_state === BackupStates.UserAttributesCollecting ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Personal information</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.backup_state === BackupStates.AuthenticationsEditing ? 'is-active' : ''}>
- <div class="ml-4">
-
- <span class="menu-item-label"><Translate>Authorization methods</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.backup_state === BackupStates.PoliciesReviewing ? 'is-active' : ''}>
- <div class="ml-4">
-
- <span class="menu-item-label"><Translate>Policies</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.backup_state === BackupStates.SecretEditing ? 'is-active' : ''}>
- <div class="ml-4">
-
- <span class="menu-item-label"><Translate>Secret input</Translate></span>
+ <span class="menu-item-label">
+ <Translate>Select one option</Translate>
+ </span>
</div>
</li>
- {/* <li class={reducer.currentReducerState.backup_state === BackupStates.PoliciesPaying ? 'is-active' : ''}>
+ )}
+ {reducer.currentReducerState &&
+ reducer.currentReducerState.backup_state ? (
+ <Fragment>
+ <li
+ class={
+ reducer.currentReducerState.backup_state ===
+ BackupStates.ContinentSelecting ||
+ reducer.currentReducerState.backup_state ===
+ BackupStates.CountrySelecting
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Location</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.backup_state ===
+ BackupStates.UserAttributesCollecting
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Personal information</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.backup_state ===
+ BackupStates.AuthenticationsEditing
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Authorization methods</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.backup_state ===
+ BackupStates.PoliciesReviewing
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Policies</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.backup_state ===
+ BackupStates.SecretEditing
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Secret input</Translate>
+ </span>
+ </div>
+ </li>
+ {/* <li class={reducer.currentReducerState.backup_state === BackupStates.PoliciesPaying ? 'is-active' : ''}>
<div class="ml-4">
<span class="menu-item-label"><Translate>Payment (optional)</Translate></span>
</div>
</li> */}
- <li class={reducer.currentReducerState.backup_state === BackupStates.BackupFinished ? 'is-active' : ''}>
- <div class="ml-4">
-
- <span class="menu-item-label"><Translate>Backup completed</Translate></span>
- </div>
- </li>
- {/* <li class={reducer.currentReducerState.backup_state === BackupStates.TruthsPaying ? 'is-active' : ''}>
+ <li
+ class={
+ reducer.currentReducerState.backup_state ===
+ BackupStates.BackupFinished
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Backup completed</Translate>
+ </span>
+ </div>
+ </li>
+ {/* <li class={reducer.currentReducerState.backup_state === BackupStates.TruthsPaying ? 'is-active' : ''}>
<div class="ml-4">
<span class="menu-item-label"><Translate>Truth Paying</Translate></span>
</div>
</li> */}
- </Fragment> : (reducer.currentReducerState && reducer.currentReducerState?.recovery_state && <Fragment>
- <li class={reducer.currentReducerState.recovery_state === RecoveryStates.ContinentSelecting ||
- reducer.currentReducerState.recovery_state === RecoveryStates.CountrySelecting ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Location</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.recovery_state === RecoveryStates.UserAttributesCollecting ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Personal information</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.recovery_state === RecoveryStates.SecretSelecting ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Secret selection</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.recovery_state === RecoveryStates.ChallengeSelecting ||
- reducer.currentReducerState.recovery_state === RecoveryStates.ChallengeSolving ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Solve Challenges</Translate></span>
- </div>
- </li>
- <li class={reducer.currentReducerState.recovery_state === RecoveryStates.RecoveryFinished ? 'is-active' : ''}>
- <div class="ml-4">
- <span class="menu-item-label"><Translate>Secret recovered</Translate></span>
- </div>
- </li>
- </Fragment>)}
- {reducer.currentReducerState &&
+ </Fragment>
+ ) : (
+ reducer.currentReducerState &&
+ reducer.currentReducerState?.recovery_state && (
+ <Fragment>
+ <li
+ class={
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.ContinentSelecting ||
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.CountrySelecting
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Location</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.UserAttributesCollecting
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Personal information</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.SecretSelecting
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Secret selection</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.ChallengeSelecting ||
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.ChallengeSolving
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Solve Challenges</Translate>
+ </span>
+ </div>
+ </li>
+ <li
+ class={
+ reducer.currentReducerState.recovery_state ===
+ RecoveryStates.RecoveryFinished
+ ? "is-active"
+ : ""
+ }
+ >
+ <div class="ml-4">
+ <span class="menu-item-label">
+ <Translate>Secret recovered</Translate>
+ </span>
+ </div>
+ </li>
+ </Fragment>
+ )
+ )}
+ {reducer.currentReducerState && (
<li>
<div class="buttons ml-4">
- <button class="button is-danger is-right" onClick={() => reducer.reset()}>Reset session</button>
+ <button
+ class="button is-danger is-right"
+ onClick={() => reducer.reset()}
+ >
+ Reset session
+ </button>
</div>
</li>
- }
-
+ )}
+ {/* <li>
+ <div class="buttons ml-4">
+ <button class="button is-info is-right" >Manage providers</button>
+ </div>
+ </li> */}
</ul>
</div>
</aside>
);
}
-
diff --git a/packages/anastasis-webui/src/components/menu/index.tsx b/packages/anastasis-webui/src/components/menu/index.tsx
index fd4aab149..99d0f7646 100644
--- a/packages/anastasis-webui/src/components/menu/index.tsx
+++ b/packages/anastasis-webui/src/components/menu/index.tsx
@@ -85,8 +85,8 @@ export function NotificationCard({
n.type === "ERROR"
? "message is-danger"
: n.type === "WARN"
- ? "message is-warning"
- : "message is-info"
+ ? "message is-warning"
+ : "message is-info"
}
>
<div class="message-header">
@@ -113,7 +113,7 @@ export function NotYetReadyAppMenu({
return (
<div
class="has-aside-mobile-expanded"
- // class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+ // class={mobileOpen ? "has-aside-mobile-expanded" : ""}
onClick={() => setMobileOpen(false)}
>
<NavigationBar
diff --git a/packages/anastasis-webui/src/components/picker/DatePicker.tsx b/packages/anastasis-webui/src/components/picker/DatePicker.tsx
index eb5d8145d..d689db386 100644
--- a/packages/anastasis-webui/src/components/picker/DatePicker.tsx
+++ b/packages/anastasis-webui/src/components/picker/DatePicker.tsx
@@ -15,9 +15,9 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, Component } from "preact";
@@ -34,83 +34,71 @@ interface State {
selectYearMode: boolean;
currentDate: Date;
}
-const now = new Date()
+const now = new Date();
const monthArrShortFull = [
- 'January',
- 'February',
- 'March',
- 'April',
- 'May',
- 'June',
- 'July',
- 'August',
- 'September',
- 'October',
- 'November',
- 'December'
-]
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+];
const monthArrShort = [
- 'Jan',
- 'Feb',
- 'Mar',
- 'Apr',
- 'May',
- 'Jun',
- 'Jul',
- 'Aug',
- 'Sep',
- 'Oct',
- 'Nov',
- 'Dec'
-]
-
-const dayArr = [
- 'Sun',
- 'Mon',
- 'Tue',
- 'Wed',
- 'Thu',
- 'Fri',
- 'Sat'
-]
-
-const yearArr: number[] = []
-
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+];
+
+const dayArr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+
+const yearArr: number[] = [];
// inspired by https://codepen.io/m4r1vs/pen/MOOxyE
export class DatePicker extends Component<Props, State> {
-
closeDatePicker() {
this.props.closeFunction && this.props.closeFunction(); // Function gets passed by parent
}
/**
- * Gets fired when a day gets clicked.
- * @param {object} e The event thrown by the <span /> element clicked
- */
+ * Gets fired when a day gets clicked.
+ * @param {object} e The event thrown by the <span /> element clicked
+ */
dayClicked(e: any) {
-
const element = e.target; // the actual element clicked
- if (element.innerHTML === '') return false; // don't continue if <span /> empty
+ if (element.innerHTML === "") return false; // don't continue if <span /> empty
// get date from clicked element (gets attached when rendered)
- const date = new Date(element.getAttribute('data-value'));
+ const date = new Date(element.getAttribute("data-value"));
// update the state
this.setState({ currentDate: date });
- this.passDateToParent(date)
+ this.passDateToParent(date);
}
/**
- * returns days in month as array
- * @param {number} month the month to display
- * @param {number} year the year to display
- */
+ * returns days in month as array
+ * @param {number} month the month to display
+ * @param {number} year the year to display
+ */
getDaysByMonth(month: number, year: number) {
-
const calendar = [];
const date = new Date(year, month, 1); // month to display
@@ -122,15 +110,17 @@ export class DatePicker extends Component<Props, State> {
// the calendar is 7*6 fields big, so 42 loops
for (let i = 0; i < 42; i++) {
-
if (i >= firstDay && day !== null) day = day + 1;
if (day !== null && day > lastDate) day = null;
// append the calendar Array
calendar.push({
- day: (day === 0 || day === null) ? null : day, // null or number
- date: (day === 0 || day === null) ? null : new Date(year, month, day), // null or Date()
- today: (day === now.getDate() && month === now.getMonth() && year === now.getFullYear()) // boolean
+ day: day === 0 || day === null ? null : day, // null or number
+ date: day === 0 || day === null ? null : new Date(year, month, day), // null or Date()
+ today:
+ day === now.getDate() &&
+ month === now.getMonth() &&
+ year === now.getFullYear(), // boolean
});
}
@@ -138,51 +128,48 @@ export class DatePicker extends Component<Props, State> {
}
/**
- * Display previous month by updating state
- */
+ * Display previous month by updating state
+ */
displayPrevMonth() {
if (this.state.displayedMonth <= 0) {
this.setState({
displayedMonth: 11,
- displayedYear: this.state.displayedYear - 1
+ displayedYear: this.state.displayedYear - 1,
});
- }
- else {
+ } else {
this.setState({
- displayedMonth: this.state.displayedMonth - 1
+ displayedMonth: this.state.displayedMonth - 1,
});
}
}
/**
- * Display next month by updating state
- */
+ * Display next month by updating state
+ */
displayNextMonth() {
if (this.state.displayedMonth >= 11) {
this.setState({
displayedMonth: 0,
- displayedYear: this.state.displayedYear + 1
+ displayedYear: this.state.displayedYear + 1,
});
- }
- else {
+ } else {
this.setState({
- displayedMonth: this.state.displayedMonth + 1
+ displayedMonth: this.state.displayedMonth + 1,
});
}
}
/**
- * Display the selected month (gets fired when clicking on the date string)
- */
+ * Display the selected month (gets fired when clicking on the date string)
+ */
displaySelectedMonth() {
if (this.state.selectYearMode) {
this.toggleYearSelector();
- }
- else {
+ } else {
if (!this.state.currentDate) return false;
this.setState({
displayedMonth: this.state.currentDate.getMonth(),
- displayedYear: this.state.currentDate.getFullYear()
+ displayedYear: this.state.currentDate.getFullYear(),
});
}
}
@@ -194,17 +181,21 @@ export class DatePicker extends Component<Props, State> {
changeDisplayedYear(e: any) {
const element = e.target;
this.toggleYearSelector();
- this.setState({ displayedYear: parseInt(element.innerHTML, 10), displayedMonth: 0 });
+ this.setState({
+ displayedYear: parseInt(element.innerHTML, 10),
+ displayedMonth: 0,
+ });
}
/**
- * Pass the selected date to parent when 'OK' is clicked
- */
+ * Pass the selected date to parent when 'OK' is clicked
+ */
passSavedDateDateToParent() {
- this.passDateToParent(this.state.currentDate)
+ this.passDateToParent(this.state.currentDate);
}
passDateToParent(date: Date) {
- if (typeof this.props.dateReceiver === 'function') this.props.dateReceiver(date);
+ if (typeof this.props.dateReceiver === "function")
+ this.props.dateReceiver(date);
this.closeDatePicker();
}
@@ -233,94 +224,133 @@ export class DatePicker extends Component<Props, State> {
currentDate: initial,
displayedMonth: initial.getMonth(),
displayedYear: initial.getFullYear(),
- selectYearMode: false
- }
+ selectYearMode: false,
+ };
}
render() {
-
- const { currentDate, displayedMonth, displayedYear, selectYearMode } = this.state;
+ const {
+ currentDate,
+ displayedMonth,
+ displayedYear,
+ selectYearMode,
+ } = this.state;
return (
<div>
- <div class={`datePicker ${ this.props.opened && "datePicker--opened"}`}>
-
+ <div class={`datePicker ${this.props.opened && "datePicker--opened"}`}>
<div class="datePicker--titles">
- <h3 style={{
- color: selectYearMode ? 'rgba(255,255,255,.87)' : 'rgba(255,255,255,.57)'
- }} onClick={this.toggleYearSelector}>{currentDate.getFullYear()}</h3>
- <h2 style={{
- color: !selectYearMode ? 'rgba(255,255,255,.87)' : 'rgba(255,255,255,.57)'
- }} onClick={this.displaySelectedMonth}>
- {dayArr[currentDate.getDay()]}, {monthArrShort[currentDate.getMonth()]} {currentDate.getDate()}
+ <h3
+ style={{
+ color: selectYearMode
+ ? "rgba(255,255,255,.87)"
+ : "rgba(255,255,255,.57)",
+ }}
+ onClick={this.toggleYearSelector}
+ >
+ {currentDate.getFullYear()}
+ </h3>
+ <h2
+ style={{
+ color: !selectYearMode
+ ? "rgba(255,255,255,.87)"
+ : "rgba(255,255,255,.57)",
+ }}
+ onClick={this.displaySelectedMonth}
+ >
+ {dayArr[currentDate.getDay()]},{" "}
+ {monthArrShort[currentDate.getMonth()]} {currentDate.getDate()}
</h2>
</div>
- {!selectYearMode && <nav>
- <span onClick={this.displayPrevMonth} class="icon"><i style={{ transform: 'rotate(180deg)' }} class="mdi mdi-forward" /></span>
- <h4>{monthArrShortFull[displayedMonth]} {displayedYear}</h4>
- <span onClick={this.displayNextMonth} class="icon"><i class="mdi mdi-forward" /></span>
- </nav>}
+ {!selectYearMode && (
+ <nav>
+ <span onClick={this.displayPrevMonth} class="icon">
+ <i
+ style={{ transform: "rotate(180deg)" }}
+ class="mdi mdi-forward"
+ />
+ </span>
+ <h4>
+ {monthArrShortFull[displayedMonth]} {displayedYear}
+ </h4>
+ <span onClick={this.displayNextMonth} class="icon">
+ <i class="mdi mdi-forward" />
+ </span>
+ </nav>
+ )}
<div class="datePicker--scroll">
-
- {!selectYearMode && <div class="datePicker--calendar" >
-
- <div class="datePicker--dayNames">
- {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((day,i) => <span key={i}>{day}</span>)}
- </div>
-
- <div onClick={this.dayClicked} class="datePicker--days">
-
- {/*
+ {!selectYearMode && (
+ <div class="datePicker--calendar">
+ <div class="datePicker--dayNames">
+ {["S", "M", "T", "W", "T", "F", "S"].map((day, i) => (
+ <span key={i}>{day}</span>
+ ))}
+ </div>
+
+ <div onClick={this.dayClicked} class="datePicker--days">
+ {/*
Loop through the calendar object returned by getDaysByMonth().
*/}
- {this.getDaysByMonth(this.state.displayedMonth, this.state.displayedYear)
- .map(
- day => {
- let selected = false;
-
- if (currentDate && day.date) selected = (currentDate.toLocaleDateString() === day.date.toLocaleDateString());
-
- return (<span key={day.day}
- class={(day.today ? 'datePicker--today ' : '') + (selected ? 'datePicker--selected' : '')}
+ {this.getDaysByMonth(
+ this.state.displayedMonth,
+ this.state.displayedYear,
+ ).map((day) => {
+ let selected = false;
+
+ if (currentDate && day.date)
+ selected =
+ currentDate.toLocaleDateString() ===
+ day.date.toLocaleDateString();
+
+ return (
+ <span
+ key={day.day}
+ class={
+ (day.today ? "datePicker--today " : "") +
+ (selected ? "datePicker--selected" : "")
+ }
disabled={!day.date}
data-value={day.date}
>
{day.day}
- </span>)
- }
- )
- }
-
+ </span>
+ );
+ })}
+ </div>
</div>
-
- </div>}
-
- {selectYearMode && <div class="datePicker--selectYear">
- {(this.props.years || yearArr).map(year => (
- <span key={year} class={(year === displayedYear) ? 'selected' : ''} onClick={this.changeDisplayedYear}>
- {year}
- </span>
- ))}
-
- </div>}
-
+ )}
+
+ {selectYearMode && (
+ <div class="datePicker--selectYear">
+ {(this.props.years || yearArr).map((year) => (
+ <span
+ key={year}
+ class={year === displayedYear ? "selected" : ""}
+ onClick={this.changeDisplayedYear}
+ >
+ {year}
+ </span>
+ ))}
+ </div>
+ )}
</div>
</div>
- <div class="datePicker--background" onClick={this.closeDatePicker} style={{
- display: this.props.opened ? 'block' : 'none',
- }}
+ <div
+ class="datePicker--background"
+ onClick={this.closeDatePicker}
+ style={{
+ display: this.props.opened ? "block" : "none",
+ }}
/>
-
</div>
- )
+ );
}
}
-
for (let i = 2010; i <= now.getFullYear() + 10; i++) {
yearArr.push(i);
}
diff --git a/packages/anastasis-webui/src/components/picker/DurationPicker.stories.tsx b/packages/anastasis-webui/src/components/picker/DurationPicker.stories.tsx
index 275c80fa6..7f96cc15b 100644
--- a/packages/anastasis-webui/src/components/picker/DurationPicker.stories.tsx
+++ b/packages/anastasis-webui/src/components/picker/DurationPicker.stories.tsx
@@ -15,36 +15,41 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-
-import { h, FunctionalComponent } from 'preact';
-import { useState } from 'preact/hooks';
-import { DurationPicker as TestedComponent } from './DurationPicker';
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { h, FunctionalComponent } from "preact";
+import { useState } from "preact/hooks";
+import { DurationPicker as TestedComponent } from "./DurationPicker";
export default {
- title: 'Components/Picker/Duration',
+ title: "Components/Picker/Duration",
component: TestedComponent,
argTypes: {
- onCreate: { action: 'onCreate' },
- goBack: { action: 'goBack' },
- }
+ onCreate: { action: "onCreate" },
+ goBack: { action: "goBack" },
+ },
};
-function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) {
- const r = (args: any) => <Component {...args} />
- r.args = props
- return r
+function createExample<Props>(
+ Component: FunctionalComponent<Props>,
+ props: Partial<Props>,
+) {
+ const r = (args: any) => <Component {...args} />;
+ r.args = props;
+ return r;
}
export const Example = createExample(TestedComponent, {
- days: true, minutes: true, hours: true, seconds: true,
- value: 10000000
+ days: true,
+ minutes: true,
+ hours: true,
+ seconds: true,
+ value: 10000000,
});
export const WithState = () => {
- const [v,s] = useState<number>(1000000)
- return <TestedComponent value={v} onChange={s} days minutes hours seconds />
-}
+ const [v, s] = useState<number>(1000000);
+ return <TestedComponent value={v} onChange={s} days minutes hours seconds />;
+};
diff --git a/packages/anastasis-webui/src/components/picker/DurationPicker.tsx b/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
index 235a63e2d..8a1faf4d0 100644
--- a/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
+++ b/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
@@ -15,9 +15,9 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -30,75 +30,123 @@ export interface Props {
seconds?: boolean;
days?: boolean;
onChange: (value: number) => void;
- value: number
+ value: number;
}
// inspiration taken from https://github.com/flurmbo/react-duration-picker
-export function DurationPicker({ days, hours, minutes, seconds, onChange, value }: Props): VNode {
- const ss = 1000
- const ms = ss * 60
- const hs = ms * 60
- const ds = hs * 24
- const i18n = useTranslator()
-
- return <div class="rdp-picker">
- {days && <DurationColumn unit={i18n`days`} max={99}
- value={Math.floor(value / ds)}
- onDecrease={value >= ds ? () => onChange(value - ds) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined}
- onChange={diff => onChange(value + diff * ds)}
- />}
- {hours && <DurationColumn unit={i18n`hours`} max={23} min={1}
- value={Math.floor(value / hs) % 24}
- onDecrease={value >= hs ? () => onChange(value - hs) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined}
- onChange={diff => onChange(value + diff * hs)}
- />}
- {minutes && <DurationColumn unit={i18n`minutes`} max={59} min={1}
- value={Math.floor(value / ms) % 60}
- onDecrease={value >= ms ? () => onChange(value - ms) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined}
- onChange={diff => onChange(value + diff * ms)}
- />}
- {seconds && <DurationColumn unit={i18n`seconds`} max={59}
- value={Math.floor(value / ss) % 60}
- onDecrease={value >= ss ? () => onChange(value - ss) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined}
- onChange={diff => onChange(value + diff * ss)}
- />}
- </div>
+export function DurationPicker({
+ days,
+ hours,
+ minutes,
+ seconds,
+ onChange,
+ value,
+}: Props): VNode {
+ const ss = 1000;
+ const ms = ss * 60;
+ const hs = ms * 60;
+ const ds = hs * 24;
+ const i18n = useTranslator();
+
+ return (
+ <div class="rdp-picker">
+ {days && (
+ <DurationColumn
+ unit={i18n`days`}
+ max={99}
+ value={Math.floor(value / ds)}
+ onDecrease={value >= ds ? () => onChange(value - ds) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined}
+ onChange={(diff) => onChange(value + diff * ds)}
+ />
+ )}
+ {hours && (
+ <DurationColumn
+ unit={i18n`hours`}
+ max={23}
+ min={1}
+ value={Math.floor(value / hs) % 24}
+ onDecrease={value >= hs ? () => onChange(value - hs) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined}
+ onChange={(diff) => onChange(value + diff * hs)}
+ />
+ )}
+ {minutes && (
+ <DurationColumn
+ unit={i18n`minutes`}
+ max={59}
+ min={1}
+ value={Math.floor(value / ms) % 60}
+ onDecrease={value >= ms ? () => onChange(value - ms) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined}
+ onChange={(diff) => onChange(value + diff * ms)}
+ />
+ )}
+ {seconds && (
+ <DurationColumn
+ unit={i18n`seconds`}
+ max={59}
+ value={Math.floor(value / ss) % 60}
+ onDecrease={value >= ss ? () => onChange(value - ss) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined}
+ onChange={(diff) => onChange(value + diff * ss)}
+ />
+ )}
+ </div>
+ );
}
interface ColProps {
- unit: string,
- min?: number,
- max: number,
- value: number,
+ unit: string;
+ min?: number;
+ max: number;
+ value: number;
onIncrease?: () => void;
onDecrease?: () => void;
onChange?: (diff: number) => void;
}
-function InputNumber({ initial, onChange }: { initial: number, onChange: (n: number) => void }) {
- const [value, handler] = useState<{v:string}>({
- v: toTwoDigitString(initial)
- })
-
- return <input
- value={value.v}
- onBlur={(e) => onChange(parseInt(value.v, 10))}
- onInput={(e) => {
- e.preventDefault()
- const n = Number.parseInt(e.currentTarget.value, 10);
- if (isNaN(n)) return handler({v:toTwoDigitString(initial)})
- return handler({v:toTwoDigitString(n)})
- }}
- style={{ width: 50, border: 'none', fontSize: 'inherit', background: 'inherit' }} />
-}
+function InputNumber({
+ initial,
+ onChange,
+}: {
+ initial: number;
+ onChange: (n: number) => void;
+}) {
+ const [value, handler] = useState<{ v: string }>({
+ v: toTwoDigitString(initial),
+ });
-function DurationColumn({ unit, min = 0, max, value, onIncrease, onDecrease, onChange }: ColProps): VNode {
+ return (
+ <input
+ value={value.v}
+ onBlur={(e) => onChange(parseInt(value.v, 10))}
+ onInput={(e) => {
+ e.preventDefault();
+ const n = Number.parseInt(e.currentTarget.value, 10);
+ if (isNaN(n)) return handler({ v: toTwoDigitString(initial) });
+ return handler({ v: toTwoDigitString(n) });
+ }}
+ style={{
+ width: 50,
+ border: "none",
+ fontSize: "inherit",
+ background: "inherit",
+ }}
+ />
+ );
+}
- const cellHeight = 35
+function DurationColumn({
+ unit,
+ min = 0,
+ max,
+ value,
+ onIncrease,
+ onDecrease,
+ onChange,
+}: ColProps): VNode {
+ const cellHeight = 35;
return (
<div class="rdp-column-container">
<div class="rdp-masked-div">
@@ -106,49 +154,58 @@ function DurationColumn({ unit, min = 0, max, value, onIncrease, onDecrease, onC
<hr class="rdp-reticule" style={{ top: cellHeight * 3 - 1 }} />
<div class="rdp-column" style={{ top: 0 }}>
-
<div class="rdp-cell" key={value - 2}>
- {onDecrease && <button style={{ width: '100%', textAlign: 'center', margin: 5 }}
- onClick={onDecrease}>
- <span class="icon">
- <i class="mdi mdi-chevron-up" />
- </span>
- </button>}
+ {onDecrease && (
+ <button
+ style={{ width: "100%", textAlign: "center", margin: 5 }}
+ onClick={onDecrease}
+ >
+ <span class="icon">
+ <i class="mdi mdi-chevron-up" />
+ </span>
+ </button>
+ )}
</div>
<div class="rdp-cell" key={value - 1}>
- {value > min ? toTwoDigitString(value - 1) : ''}
+ {value > min ? toTwoDigitString(value - 1) : ""}
</div>
<div class="rdp-cell rdp-center" key={value}>
- {onChange ?
- <InputNumber initial={value} onChange={(n) => onChange(n - value)} /> :
+ {onChange ? (
+ <InputNumber
+ initial={value}
+ onChange={(n) => onChange(n - value)}
+ />
+ ) : (
toTwoDigitString(value)
- }
+ )}
<div>{unit}</div>
</div>
<div class="rdp-cell" key={value + 1}>
- {value < max ? toTwoDigitString(value + 1) : ''}
+ {value < max ? toTwoDigitString(value + 1) : ""}
</div>
<div class="rdp-cell" key={value + 2}>
- {onIncrease && <button style={{ width: '100%', textAlign: 'center', margin: 5 }}
- onClick={onIncrease}>
- <span class="icon">
- <i class="mdi mdi-chevron-down" />
- </span>
- </button>}
+ {onIncrease && (
+ <button
+ style={{ width: "100%", textAlign: "center", margin: 5 }}
+ onClick={onIncrease}
+ >
+ <span class="icon">
+ <i class="mdi mdi-chevron-down" />
+ </span>
+ </button>
+ )}
</div>
-
</div>
</div>
</div>
);
}
-
function toTwoDigitString(n: number) {
if (n < 10) {
return `0${n}`;
}
return `${n}`;
-} \ No newline at end of file
+}