diff options
author | Sebastian <sebasjm@gmail.com> | 2022-12-09 12:07:01 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-12-09 12:07:01 -0300 |
commit | 6b6f80466ee07f591203c28a724ce4e7128af85d (patch) | |
tree | 4460721b74245625fe70443d466da677362abf1d /packages/demobank-ui/src/components | |
parent | f2b319921c53010446e05ac4f24eef9995f65836 (diff) | |
download | wallet-core-6b6f80466ee07f591203c28a724ce4e7128af85d.tar.xz |
remove unused
Diffstat (limited to 'packages/demobank-ui/src/components')
15 files changed, 0 insertions, 1584 deletions
diff --git a/packages/demobank-ui/src/components/AsyncButton.tsx b/packages/demobank-ui/src/components/AsyncButton.tsx deleted file mode 100644 index 0e1391109..000000000 --- a/packages/demobank-ui/src/components/AsyncButton.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { ComponentChildren, h, VNode } from "preact"; -import { useLayoutEffect, useRef } from "preact/hooks"; -import { useAsync } from "../hooks/async.js"; - -type Props = { - children: ComponentChildren; - disabled?: boolean; - onClick?: () => Promise<void>; - grabFocus?: boolean; - [rest: string]: any; -}; - -export function AsyncButton({ - onClick, - grabFocus, - disabled, - children, - ...rest -}: Props): VNode { - const { isLoading, request } = useAsync(onClick); - - const buttonRef = useRef<HTMLButtonElement>(null); - useLayoutEffect(() => { - if (grabFocus) buttonRef.current?.focus(); - }, [grabFocus]); - - // if (isSlow) { - // return <LoadingModal onCancel={cancel} />; - // } - if (isLoading) return <button class="button">Loading...</button>; - - return ( - <span data-tooltip={rest["data-tooltip"]} style={{ marginLeft: 5 }}> - <button {...rest} ref={buttonRef} onClick={request} disabled={disabled}> - {children} - </button> - </span> - ); -} diff --git a/packages/demobank-ui/src/components/FileButton.tsx b/packages/demobank-ui/src/components/FileButton.tsx deleted file mode 100644 index d7ed52f5d..000000000 --- a/packages/demobank-ui/src/components/FileButton.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useRef, useState } from "preact/hooks"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export interface FileTypeContent { - content: string; - type: string; - name: string; -} - -interface Props { - label: string; - onChange: (v: FileTypeContent | undefined) => void; -} -export function FileButton(props: Props): VNode { - const fileInputRef = useRef<HTMLInputElement>(null); - const [sizeError, setSizeError] = useState(false); - return ( - <div> - <button class="button" onClick={(e) => fileInputRef.current?.click()}> - <span>{props.label}</span> - </button> - <input - ref={fileInputRef} - style={{ display: "none" }} - type="file" - onChange={(e) => { - const f: FileList | null = e.currentTarget.files; - if (!f || f.length != 1) return props.onChange(undefined); - - if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { - setSizeError(true); - return props.onChange(undefined); - } - setSizeError(false); - return f[0].arrayBuffer().then((b) => { - const content = new Uint8Array(b).reduce( - (data, byte) => data + String.fromCharCode(byte), - "", - ); - return props.onChange({ - content, - name: f[0].name, - type: f[0].type, - }); - }); - }} - /> - {sizeError && ( - <p class="help is-danger">File should be smaller than 1 MB</p> - )} - </div> - ); -} diff --git a/packages/demobank-ui/src/components/Notifications.tsx b/packages/demobank-ui/src/components/Notifications.tsx deleted file mode 100644 index 6dd3a2d50..000000000 --- a/packages/demobank-ui/src/components/Notifications.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; - -export interface Notification { - message: string; - description?: string | VNode; - type: MessageType; -} - -export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS"; - -interface Props { - notifications: Notification[]; - removeNotification?: (n: Notification) => void; -} - -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"; - } -} - -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/demobank-ui/src/components/fields/DateInput.tsx b/packages/demobank-ui/src/components/fields/DateInput.tsx deleted file mode 100644 index 0eeb1b2fd..000000000 --- a/packages/demobank-ui/src/components/fields/DateInput.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { format, subYears } from "date-fns"; -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; -import { DatePicker } from "../picker/DatePicker.js"; - -export interface DateInputProps { - label: string; - grabFocus?: boolean; - tooltip?: string; - error?: string; - years?: Array<number>; - onConfirm?: () => void; - bind: [string, (x: string) => void]; -} - -export function DateInput(props: DateInputProps): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (props.grabFocus) inputRef.current?.focus(); - }, [props.grabFocus]); - const [opened, setOpened] = useState(false); - - const value = props.bind[0] || ""; - 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} - onKeyPress={(e) => { - if (e.key === "Enter" && props.onConfirm) props.onConfirm(); - }} - 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> - ); -} diff --git a/packages/demobank-ui/src/components/fields/EmailInput.tsx b/packages/demobank-ui/src/components/fields/EmailInput.tsx deleted file mode 100644 index 9f6624aa5..000000000 --- a/packages/demobank-ui/src/components/fields/EmailInput.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -export interface TextInputProps { - label: string; - grabFocus?: boolean; - error?: string; - placeholder?: string; - tooltip?: string; - onConfirm?: () => void; - bind: [string, (x: string) => void]; -} - -export function EmailInput(props: TextInputProps): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (props.grabFocus) inputRef.current?.focus(); - }, [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"} - onKeyPress={(e) => { - if (e.key === "Enter" && props.onConfirm) props.onConfirm(); - }} - 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> - ); -} diff --git a/packages/demobank-ui/src/components/fields/FileInput.tsx b/packages/demobank-ui/src/components/fields/FileInput.tsx deleted file mode 100644 index cc49a632d..000000000 --- a/packages/demobank-ui/src/components/fields/FileInput.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export interface FileTypeContent { - content: string; - type: string; - name: string; -} - -export interface FileInputProps { - label: string; - grabFocus?: boolean; - disabled?: boolean; - error?: string; - placeholder?: string; - tooltip?: string; - onChange: (v: FileTypeContent | undefined) => void; -} - -export function FileInput(props: FileInputProps): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (props.grabFocus) inputRef.current?.focus(); - }, [props.grabFocus]); - - const fileInputRef = useRef<HTMLInputElement>(null); - const [sizeError, setSizeError] = useState(false); - return ( - <div class="field"> - <label class="label"> - <a class="button" onClick={(e) => fileInputRef.current?.click()}> - <div class="icon is-small "> - <i class="mdi mdi-folder" /> - </div> - <span>{props.label}</span> - </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={fileInputRef} - style={{ display: "none" }} - type="file" - // name={String(name)} - onChange={(e) => { - const f: FileList | null = e.currentTarget.files; - if (!f || f.length != 1) return props.onChange(undefined); - - if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { - setSizeError(true); - return props.onChange(undefined); - } - setSizeError(false); - return f[0].arrayBuffer().then((b) => { - const b64 = btoa( - new Uint8Array(b).reduce( - (data, byte) => data + String.fromCharCode(byte), - "", - ), - ); - return props.onChange({ - content: `data:${f[0].type};base64,${b64}`, - name: f[0].name, - type: f[0].type, - }); - }); - }} - /> - {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> - ); -} diff --git a/packages/demobank-ui/src/components/fields/ImageInput.tsx b/packages/demobank-ui/src/components/fields/ImageInput.tsx deleted file mode 100644 index 15b25f1c2..000000000 --- a/packages/demobank-ui/src/components/fields/ImageInput.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; -import emptyImage from "../../assets/empty.png"; -import { TextInputProps } from "./TextInput.js"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export function ImageInput(props: TextInputProps): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (props.grabFocus) inputRef.current?.focus(); - }, [props.grabFocus]); - - const value = props.bind[0]; - // const [dirty, setDirty] = 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> - )} - </div> - </div> - ); -} diff --git a/packages/demobank-ui/src/components/fields/NumberInput.tsx b/packages/demobank-ui/src/components/fields/NumberInput.tsx deleted file mode 100644 index 69af18c77..000000000 --- a/packages/demobank-ui/src/components/fields/NumberInput.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -export interface TextInputProps { - label: string; - grabFocus?: boolean; - error?: string; - placeholder?: string; - tooltip?: string; - onConfirm?: () => void; - bind: [string, (x: string) => void]; -} - -export function PhoneNumberInput(props: TextInputProps): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (props.grabFocus) inputRef.current?.focus(); - }, [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} - type="tel" - placeholder={props.placeholder} - class={showError ? "input is-danger" : "input"} - onKeyPress={(e) => { - if (e.key === "Enter" && props.onConfirm) props.onConfirm(); - }} - 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> - ); -} diff --git a/packages/demobank-ui/src/components/fields/TextInput.tsx b/packages/demobank-ui/src/components/fields/TextInput.tsx deleted file mode 100644 index 5c6fe3157..000000000 --- a/packages/demobank-ui/src/components/fields/TextInput.tsx +++ /dev/null @@ -1,80 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -export interface TextInputProps { - inputType?: "text" | "number" | "multiline" | "password"; - label: string; - grabFocus?: boolean; - disabled?: boolean; - error?: string; - placeholder?: string; - tooltip?: string; - onConfirm?: () => void; - bind: [string, (x: string) => void]; -} - -const TextInputType = function ({ inputType, grabFocus, ...rest }: any): VNode { - const inputRef = useRef<HTMLInputElement>(null); - useLayoutEffect(() => { - if (grabFocus) inputRef.current?.focus(); - }, [grabFocus]); - - return inputType === "multiline" ? ( - <textarea {...rest} rows={5} ref={inputRef} style={{ height: "unset" }} /> - ) : ( - <input {...rest} type={inputType} ref={inputRef} /> - ); -}; - -export function TextInput(props: TextInputProps): VNode { - 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"> - <TextInputType - inputType={props.inputType} - value={value} - grabFocus={props.grabFocus} - disabled={props.disabled} - placeholder={props.placeholder} - class={showError ? "input is-danger" : "input"} - onKeyPress={(e: any) => { - if (e.key === "Enter" && props.onConfirm) props.onConfirm(); - }} - onInput={(e: any) => { - setDirty(true); - props.bind[1]((e.target as HTMLInputElement).value); - }} - style={{ display: "block" }} - /> - </div> - {showError && <p class="help is-danger">{props.error}</p>} - </div> - ); -} diff --git a/packages/demobank-ui/src/components/menu/NavigationBar.tsx b/packages/demobank-ui/src/components/menu/NavigationBar.tsx deleted file mode 100644 index 5c57d2c95..000000000 --- a/packages/demobank-ui/src/components/menu/NavigationBar.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; - -interface Props { - onMobileMenu: () => void; - title: string; -} - -export function NavigationBar({ onMobileMenu, title }: Props): VNode { - return ( - <nav - class="navbar is-fixed-top" - role="navigation" - aria-label="main navigation" - > - <div class="navbar-brand"> - <span class="navbar-item" style={{ fontSize: 24, fontWeight: 900 }}> - {title} - </span> - </div> - - <div class="navbar-menu "> - <div class="navbar-end"> - <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}> - {/* <LangSelector /> */} - </div> - </div> - </div> - </nav> - ); -} diff --git a/packages/demobank-ui/src/components/menu/SideBar.tsx b/packages/demobank-ui/src/components/menu/SideBar.tsx deleted file mode 100644 index 32fe216ab..000000000 --- a/packages/demobank-ui/src/components/menu/SideBar.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; -import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; - -interface Props { - mobile?: boolean; -} - -export function Sidebar({ mobile }: Props): VNode { - // const config = useConfigContext(); - const config = { version: "none" }; - // FIXME: add replacement for __VERSION__ with the current version - const process = { env: { __VERSION__: "0.0.0" } }; - const { i18n } = useTranslationContext(); - - return ( - <aside class="aside is-placed-left is-expanded"> - <div class="aside-tools"> - <div class="aside-tools-label"> - <div> - <b>euFin bank</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"> - <p class="menu-label"> - <i18n.Translate>Bank menu</i18n.Translate> - </p> - <ul class="menu-list"> - <li> - <div class="ml-4"> - <span class="menu-item-label"> - <i18n.Translate>Select option1</i18n.Translate> - </span> - </div> - </li> - <li> - <div class="ml-4"> - <span class="menu-item-label"> - <i18n.Translate>Select option2</i18n.Translate> - </span> - </div> - </li> - </ul> - </div> - </aside> - ); -} diff --git a/packages/demobank-ui/src/components/menu/index.tsx b/packages/demobank-ui/src/components/menu/index.tsx deleted file mode 100644 index c0a845a62..000000000 --- a/packages/demobank-ui/src/components/menu/index.tsx +++ /dev/null @@ -1,135 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import { ComponentChildren, Fragment, h, VNode } from "preact"; -import Match from "preact-router/match"; -import { useEffect, useState } from "preact/hooks"; -import { NavigationBar } from "./NavigationBar.js"; -import { Sidebar } from "./SideBar.js"; - -interface MenuProps { - title: string; -} - -function WithTitle({ - title, - children, -}: { - title: string; - children: ComponentChildren; -}): VNode { - useEffect(() => { - document.title = `${title}`; - }, [title]); - return <Fragment>{children}</Fragment>; -} - -export function Menu({ title }: MenuProps): VNode { - const [mobileOpen, setMobileOpen] = useState(false); - - return ( - <Match> - {({ path }: { path: string }) => { - const titleWithSubtitle = title; // title ? title : (!admin ? getInstanceTitle(path, instance) : getAdminTitle(path, instance)) - return ( - <WithTitle title={titleWithSubtitle}> - <div - class={mobileOpen ? "has-aside-mobile-expanded" : ""} - onClick={() => setMobileOpen(false)} - > - <NavigationBar - onMobileMenu={() => setMobileOpen(!mobileOpen)} - title={titleWithSubtitle} - /> - - <Sidebar mobile={mobileOpen} /> - </div> - </WithTitle> - ); - }} - </Match> - ); -} - -interface NotYetReadyAppMenuProps { - title: string; - onLogout?: () => void; -} - -interface NotifProps { - notification?: Notification; -} -export function NotificationCard({ - notification: n, -}: NotifProps): VNode | null { - if (!n) return null; - return ( - <div class="notification"> - <div class="columns is-vcentered"> - <div class="column is-12"> - <article - class={ - n.type === "ERROR" - ? "message is-danger" - : n.type === "WARN" - ? "message is-warning" - : "message is-info" - } - > - <div class="message-header"> - <p>{n.message}</p> - </div> - {n.description && <div class="message-body">{n.description}</div>} - </article> - </div> - </div> - </div> - ); -} - -export function NotYetReadyAppMenu({ - onLogout, - title, -}: NotYetReadyAppMenuProps): VNode { - const [mobileOpen, setMobileOpen] = useState(false); - - useEffect(() => { - document.title = `Taler Backoffice: ${title}`; - }, [title]); - - return ( - <div - class="has-aside-mobile-expanded" - // class={mobileOpen ? "has-aside-mobile-expanded" : ""} - onClick={() => setMobileOpen(false)} - > - <NavigationBar - onMobileMenu={() => setMobileOpen(!mobileOpen)} - title={title} - /> - {onLogout && <Sidebar mobile={mobileOpen} />} - </div> - ); -} - -export interface Notification { - message: string; - description?: string | VNode; - type: MessageType; -} - -export type ValueOrFunction<T> = T | ((p: T) => T); -export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS"; diff --git a/packages/demobank-ui/src/components/picker/DatePicker.tsx b/packages/demobank-ui/src/components/picker/DatePicker.tsx deleted file mode 100644 index 0a93144ec..000000000 --- a/packages/demobank-ui/src/components/picker/DatePicker.tsx +++ /dev/null @@ -1,347 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, Component } from "preact"; - -interface Props { - closeFunction?: () => void; - dateReceiver?: (d: Date) => void; - initialDate?: Date; - years?: Array<number>; - opened?: boolean; -} -interface State { - displayedMonth: number; - displayedYear: number; - selectYearMode: boolean; - currentDate: Date; -} -const now = new Date(); - -const monthArrShortFull = [ - "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[] = []; - -// 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 - */ - dayClicked(e: any) { - const element = e.target; // the actual element clicked - - 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")); - - // update the state - this.setState({ currentDate: date }); - this.passDateToParent(date); - } - - /** - * 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 - - const firstDay = new Date(year, month, 1).getDay(); // first weekday of month - const lastDate = new Date(year, month + 1, 0).getDate(); // last date of month - - let day: number | null = 0; - - // 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 - }); - } - - return calendar; - } - - /** - * Display previous month by updating state - */ - displayPrevMonth() { - if (this.state.displayedMonth <= 0) - this.setState({ - displayedMonth: 11, - displayedYear: this.state.displayedYear - 1, - }); - else - this.setState({ - displayedMonth: this.state.displayedMonth - 1, - }); - } - - /** - * Display next month by updating state - */ - displayNextMonth() { - if (this.state.displayedMonth >= 11) - this.setState({ - displayedMonth: 0, - displayedYear: this.state.displayedYear + 1, - }); - else - this.setState({ - displayedMonth: this.state.displayedMonth + 1, - }); - } - - /** - * Display the selected month (gets fired when clicking on the date string) - */ - displaySelectedMonth() { - if (this.state.selectYearMode) this.toggleYearSelector(); - else { - if (!this.state.currentDate) return false; - this.setState({ - displayedMonth: this.state.currentDate.getMonth(), - displayedYear: this.state.currentDate.getFullYear(), - }); - } - } - - toggleYearSelector() { - this.setState({ selectYearMode: !this.state.selectYearMode }); - } - - changeDisplayedYear(e: any) { - const element = e.target; - this.toggleYearSelector(); - this.setState({ - displayedYear: parseInt(element.innerHTML, 10), - displayedMonth: 0, - }); - } - - /** - * Pass the selected date to parent when 'OK' is clicked - */ - passSavedDateDateToParent() { - this.passDateToParent(this.state.currentDate); - } - passDateToParent(date: Date) { - if (typeof this.props.dateReceiver === "function") - this.props.dateReceiver(date); - this.closeDatePicker(); - } - - componentDidUpdate() { - // if (this.state.selectYearMode) { - // document.getElementsByClassName('selected')[0].scrollIntoView(); // works in every browser incl. IE, replace with scrollIntoViewIfNeeded when browsers support it - // } - } - - constructor(props: any) { - super(props); - - this.closeDatePicker = this.closeDatePicker.bind(this); - this.dayClicked = this.dayClicked.bind(this); - this.displayNextMonth = this.displayNextMonth.bind(this); - this.displayPrevMonth = this.displayPrevMonth.bind(this); - this.getDaysByMonth = this.getDaysByMonth.bind(this); - this.changeDisplayedYear = this.changeDisplayedYear.bind(this); - this.passDateToParent = this.passDateToParent.bind(this); - this.toggleYearSelector = this.toggleYearSelector.bind(this); - this.displaySelectedMonth = this.displaySelectedMonth.bind(this); - - const initial = props.initialDate || now; - - this.state = { - currentDate: initial, - displayedMonth: initial.getMonth(), - displayedYear: initial.getFullYear(), - selectYearMode: false, - }; - } - - render() { - const { currentDate, displayedMonth, displayedYear, selectYearMode } = - this.state; - - return ( - <div> - <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()} - </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> - )} - - <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"> - {/* - 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" : "") - } - disabled={!day.date} - data-value={day.date} - > - {day.day} - </span> - ); - })} - </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> - )} - </div> - </div> - - <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/demobank-ui/src/components/picker/DurationPicker.stories.tsx b/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx deleted file mode 100644 index db417b949..000000000 --- a/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, FunctionalComponent } from "preact"; -import { useState } from "preact/hooks"; -import { DurationPicker as TestedComponent } from "./DurationPicker.js"; - -export default { - title: "Components/Picker/Duration", - component: TestedComponent, - argTypes: { - 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; -} - -export const Example = createExample(TestedComponent, { - 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 />; -}; diff --git a/packages/demobank-ui/src/components/picker/DurationPicker.tsx b/packages/demobank-ui/src/components/picker/DurationPicker.tsx deleted file mode 100644 index 973f2f507..000000000 --- a/packages/demobank-ui/src/components/picker/DurationPicker.tsx +++ /dev/null @@ -1,210 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; -import { useState } from "preact/hooks"; -import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; -import "../../scss/DurationPicker.scss"; - -export interface Props { - hours?: boolean; - minutes?: boolean; - seconds?: boolean; - days?: boolean; - onChange: (value: number) => void; - 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 } = useTranslationContext(); - - return ( - <div class="rdp-picker"> - {days && ( - <DurationColumn - unit={i18n.str`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.str`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.str`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.str`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; - 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 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"> - <hr class="rdp-reticule" style={{ top: cellHeight * 2 - 1 }} /> - <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> - )} - </div> - <div class="rdp-cell" key={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)} - /> - ) : ( - toTwoDigitString(value) - )} - <div>{unit}</div> - </div> - - <div class="rdp-cell" key={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> - )} - </div> - </div> - </div> - </div> - ); -} - -function toTwoDigitString(n: number) { - if (n < 10) return `0${n}`; - - return `${n}`; -} |