merchant-backoffice

ZZZ: Inactive/Deprecated
Log | Files | Refs | Submodules | README

commit b923b0d6a489b13fd1d5d405a2febb8a7150bc12
parent 1d4d3869beec94df25306678a615dbbf480ac268
Author: Sebastian <sebasjm@gmail.com>
Date:   Thu, 18 Feb 2021 09:46:01 -0300

added copyright and replace default import

Diffstat:
MTODO | 4++--
Mpreact.config.js | 18+++++++++---------
Dsrc/components/auth/LoginPage.tsx | 83-------------------------------------------------------------------------------
Asrc/components/auth/index.tsx | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/footer/index.tsx | 2+-
Asrc/components/hooks/index.ts | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/components/hooks/useBackend.ts | 44--------------------------------------------
Dsrc/components/hooks/useLang.ts | 27---------------------------
Dsrc/components/hooks/useLocalStorage.ts | 62--------------------------------------------------------------
Msrc/components/modal/index.tsx | 2+-
Msrc/components/navbar/index.tsx | 18+++++++++---------
Msrc/components/notifications/Notifications.stories.tsx | 20++++++++++----------
Msrc/components/notifications/index.tsx | 2+-
Msrc/components/sidebar/index.tsx | 2+-
Msrc/components/yup/YupField.tsx | 20++++++++++----------
Msrc/declaration.d.ts | 4++--
Msrc/i18n/index.ts | 2+-
Msrc/index.ts | 7+++++--
Dsrc/routes/dashboard/index.tsx | 483-------------------------------------------------------------------------------
Dsrc/routes/forms/index.tsx | 280-------------------------------------------------------------------------------
Dsrc/routes/home/index.tsx | 61-------------------------------------------------------------
Msrc/routes/index.tsx | 25++++++++++++-------------
Msrc/routes/instances/CardTable.tsx | 14+++++++-------
Msrc/routes/instances/Create.stories.tsx | 6+++---
Dsrc/routes/instances/Create.tsx | 112-------------------------------------------------------------------------------
Asrc/routes/instances/CreatePage.tsx | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/routes/instances/DeleteModal.tsx | 12++++++------
Msrc/routes/instances/EmptyTable.tsx | 2+-
Msrc/routes/instances/Table.tsx | 2+-
Dsrc/routes/instances/Update.tsx | 118-------------------------------------------------------------------------------
Dsrc/routes/instances/UpdateModal.stories.tsx | 45---------------------------------------------
Dsrc/routes/instances/UpdateModal.tsx | 58----------------------------------------------------------
Asrc/routes/instances/UpdatePage.tsx | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/routes/instances/View.stories.tsx | 22+++++++++++-----------
Msrc/routes/instances/View.tsx | 16++++++++--------
Msrc/routes/instances/index.tsx | 26+++++++++++++-------------
Msrc/routes/notfound/index.tsx | 7+++----
Dsrc/routes/profile/index.tsx | 239-------------------------------------------------------------------------------
Mtests/header.test.tsx | 10+++++-----
Mtsconfig.json | 21---------------------
40 files changed, 522 insertions(+), 1754 deletions(-)

diff --git a/TODO b/TODO @@ -18,6 +18,8 @@ Already done: * refactor update page * Login button should be centered * format duration as human readable + * add copyright headers to every source file + * replace default exports for named exports Next to do: * implement proper error handling @@ -25,9 +27,7 @@ Next to do: Queue: * replace Yup and type definition with a taler-library for the purpose (first wait Florian to refactor wallet core) - * replace default exports for named exports * implement pnpm - * add copyright headers to every source file * add more doc style comments * check the field names in forms dont break spaces * update spanish lang diff --git a/preact.config.js b/preact.config.js @@ -14,22 +14,22 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ // import { DefinePlugin } from 'webpack'; -import { config } from 'dotenv'; -const { parsed } = config(); +// import { config } from 'dotenv'; +// const { parsed } = config(); export default { webpack(config, env, helpers, options) { config.node.process = 'mock' // config.plugins.push( - // new DefinePlugin({ - // // 'process.env.BACKEND_ENDPOINT': JSON.stringify(parsed['BACKEND_ENDPOINT']), - // }), + // new DefinePlugin({ + // // 'process.env.BACKEND_ENDPOINT': JSON.stringify(parsed['BACKEND_ENDPOINT']), + // }), // ); } } diff --git a/src/components/auth/LoginPage.tsx b/src/components/auth/LoginPage.tsx @@ -1,82 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 useBackend from "../hooks/useBackend"; - -interface Props { - onConfirm?: () => void; -} - -export default function LoginPage({ onConfirm }: Props): VNode { - const [backend, setBackend] = useBackend() - const [url, setUrl] = useState(backend.url) - const [token, setToken] = useState(backend.token) - const [changeToken, setChangeToken] = useState(false) - - return <div class="modal is-active is-clipped"> - <div class="modal-background" /> - <div class="modal-card"> - <header class="modal-card-head"> - <p class="modal-card-title">Authentication required</p> - </header> - <section class="modal-card-body"> - Please enter your auth token. Token should have "secret-token:" and start with Bearer or ApiKey - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Change Token</label> - </div> - <div class="field-body"> - <div class="field has-addons"> - <label class="b-checkbox checkbox"> - <input type="checkbox" checked={changeToken} onClick={(): void => setChangeToken(!changeToken)} /> - <span class="check" /> - </label> - - <p class="control is-expanded"> - <input class="input" type="text" placeholder={changeToken ? "set new token" : "hidden token value"} disabled={!changeToken} name="id" value={token} onInput={(e): void => setToken(e?.currentTarget.value)} /> - </p> - </div> - </div> - </div> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">URL</label> - </div> - <div class="field-body"> - <div class="field"> - <p class="control is-expanded"> - <input class="input" type="text" placeholder="set new url" name="id" value={url} onInput={(e): void => setUrl(e?.currentTarget.value)} /> - </p> - </div> - </div> - </div> - </section> - <footer class="modal-card-foot"> - <button class="button is-info" onClick={(): void => { - setBackend({token, url}); - onConfirm && onConfirm(); - }} >Confirm</button> - </footer> - </div> - </div> -} -\ No newline at end of file diff --git a/src/components/auth/index.tsx b/src/components/auth/index.tsx @@ -0,0 +1,82 @@ +/* + This file is part of GNU Taler + (C) 2021 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 { useBackend } from "../hooks"; + +interface Props { + onConfirm?: () => void; +} + +export function LoginPage({ onConfirm }: Props): VNode { + const [backend, setBackend] = useBackend() + const [url, setUrl] = useState(backend.url) + const [token, setToken] = useState(backend.token) + const [changeToken, setChangeToken] = useState(false) + + return <div class="modal is-active is-clipped"> + <div class="modal-background" /> + <div class="modal-card"> + <header class="modal-card-head"> + <p class="modal-card-title">Authentication required</p> + </header> + <section class="modal-card-body"> + Please enter your auth token. Token should have "secret-token:" and start with Bearer or ApiKey + <div class="field is-horizontal"> + <div class="field-label is-normal"> + <label class="label">Change Token</label> + </div> + <div class="field-body"> + <div class="field has-addons"> + <label class="b-checkbox checkbox"> + <input type="checkbox" checked={changeToken} onClick={(): void => setChangeToken(!changeToken)} /> + <span class="check" /> + </label> + + <p class="control is-expanded"> + <input class="input" type="text" placeholder={changeToken ? "set new token" : "hidden token value"} disabled={!changeToken} name="id" value={token} onInput={(e): void => setToken(e?.currentTarget.value)} /> + </p> + </div> + </div> + </div> + <div class="field is-horizontal"> + <div class="field-label is-normal"> + <label class="label">URL</label> + </div> + <div class="field-body"> + <div class="field"> + <p class="control is-expanded"> + <input class="input" type="text" placeholder="set new url" name="id" value={url} onInput={(e): void => setUrl(e?.currentTarget.value)} /> + </p> + </div> + </div> + </div> + </section> + <footer class="modal-card-foot"> + <button class="button is-info" onClick={(): void => { + setBackend({ token, url }); + onConfirm && onConfirm(); + }} >Confirm</button> + </footer> + </div> + </div> +} +\ No newline at end of file diff --git a/src/components/footer/index.tsx b/src/components/footer/index.tsx @@ -21,7 +21,7 @@ import { h, VNode } from 'preact'; -export default function Footer(): VNode { +export function Footer(): VNode { return ( <footer class="footer"> <div class="container-fluid"> diff --git a/src/components/hooks/index.ts b/src/components/hooks/index.ts @@ -0,0 +1,87 @@ +/* + This file is part of GNU Taler + (C) 2021 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 { StateUpdater, useState } from "preact/hooks"; +import { mutate } from 'swr'; + +interface State { + token?: string; + url: string; +} + +export function useBackend(): [State, StateUpdater<State>] { + const [url, setUrl] = useLocalStorage('backend-url', window.location.origin) + const [token, setToken] = useLocalStorage('backend-token') + + const updater: StateUpdater<State> = (value: State | ((value: State) => State)) => { + const valueToStore = value instanceof Function ? value({ token, url: url || window.location.origin }) : value; + setUrl(valueToStore.url) + setToken(valueToStore.token) + + mutate('/private/instances', null) + } + + return [{ token, url: url || window.location.origin }, updater] +} + +export function useLang(): [string, StateUpdater<string>] { + return useNotNullLocalStorage('lang-preference', typeof window !== "undefined" ? navigator.language || (navigator as any).userLanguage : 'en') +} + +export function useLocalStorage(key: string, initialValue?: string): [string | undefined, StateUpdater<string | undefined>] { + const [storedValue, setStoredValue] = useState<string | undefined>((): string | undefined => { + return typeof window !== "undefined" ? window.localStorage.getItem(key) || initialValue : initialValue; + }); + + const setValue = (value?: string | ((val?: string) => string | undefined)) => { + const valueToStore = value instanceof Function ? value(storedValue) : value; + setStoredValue(valueToStore); + if (typeof window !== "undefined") { + if (!valueToStore) { + window.localStorage.removeItem(key) + } else { + window.localStorage.setItem(key, valueToStore); + } + } + }; + + return [storedValue, setValue]; +} + +export function useNotNullLocalStorage(key: string, initialValue: string): [string, StateUpdater<string>] { + const [storedValue, setStoredValue] = useState<string>((): string => { + return typeof window !== "undefined" ? window.localStorage.getItem(key) || initialValue : initialValue; + }); + + const setValue = (value: string | ((val: string) => string)) => { + const valueToStore = value instanceof Function ? value(storedValue) : value; + setStoredValue(valueToStore); + if (typeof window !== "undefined") { + if (!valueToStore) { + window.localStorage.removeItem(key) + } else { + window.localStorage.setItem(key, valueToStore); + } + } + }; + + return [storedValue, setValue]; +} diff --git a/src/components/hooks/useBackend.ts b/src/components/hooks/useBackend.ts @@ -1,44 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { StateUpdater } from "preact/hooks"; -import {useLocalStorage} from "./useLocalStorage"; -import { mutate } from 'swr'; - -interface State { - token?: string; - url: string; -} - -export default function useBackend(): [State, StateUpdater<State>] { - const [url, setUrl] = useLocalStorage('backend-url', window.location.origin) - const [token, setToken] = useLocalStorage('backend-token') - - const updater: StateUpdater<State> = (value:State | ((value: State) => State)) => { - const valueToStore = value instanceof Function ? value({token, url: url || window.location.origin}) : value; - setUrl(valueToStore.url) - setToken(valueToStore.token) - - mutate('/private/instances', null) - } - - return [{token, url: url || window.location.origin}, updater] -} diff --git a/src/components/hooks/useLang.ts b/src/components/hooks/useLang.ts @@ -1,27 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { StateUpdater } from "preact/hooks"; -import { useNotNullLocalStorage } from "./useLocalStorage"; - -export default function useLang(): [string, StateUpdater<string>] { - return useNotNullLocalStorage('lang-preference', typeof window !== "undefined" ? navigator.language || (navigator as any).userLanguage : 'en' ) -} diff --git a/src/components/hooks/useLocalStorage.ts b/src/components/hooks/useLocalStorage.ts @@ -1,62 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { StateUpdater, useState } from "preact/hooks"; - -export function useLocalStorage(key: string, initialValue?: string): [string | undefined, StateUpdater<string | undefined>] { - const [storedValue, setStoredValue] = useState<string | undefined>((): string | undefined => { - return typeof window !== "undefined" ? window.localStorage.getItem(key) || initialValue : initialValue; - }); - - const setValue = (value?: string | ((val?: string) => string | undefined)) => { - const valueToStore = value instanceof Function ? value(storedValue) : value; - setStoredValue(valueToStore); - if (typeof window !== "undefined") { - if (!valueToStore) { - window.localStorage.removeItem(key) - } else { - window.localStorage.setItem(key, valueToStore); - } - } - }; - - return [storedValue, setValue]; -} - -export function useNotNullLocalStorage(key: string, initialValue: string): [string, StateUpdater<string>] { - const [storedValue, setStoredValue] = useState<string>((): string => { - return typeof window !== "undefined" ? window.localStorage.getItem(key) || initialValue : initialValue; - }); - - const setValue = (value: string | ((val: string) => string)) => { - const valueToStore = value instanceof Function ? value(storedValue) : value; - setStoredValue(valueToStore); - if (typeof window !== "undefined") { - if (!valueToStore) { - window.localStorage.removeItem(key) - } else { - window.localStorage.setItem(key, valueToStore); - } - } - }; - - return [storedValue, setValue]; -} diff --git a/src/components/modal/index.tsx b/src/components/modal/index.tsx @@ -31,7 +31,7 @@ interface Props { danger?: boolean; } -export default function ConfirmModal({ active, description, onCancel, onConfirm, children, danger }: Props): VNode { +export function ConfirmModal({ active, description, onCancel, onConfirm, children, danger }: Props): VNode { return <div class={active ? "modal is-active" : "modal"}> <div class="modal-background " onClick={onCancel} /> <div class="modal-card"> diff --git a/src/components/navbar/index.tsx b/src/components/navbar/index.tsx @@ -14,15 +14,15 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from 'preact'; import { useState } from 'preact/hooks'; -import LoginPage from '../auth/LoginPage'; -import i18n from '../../i18n' +import { LoginPage } from '../auth'; +import { translations } from '../../i18n' // TODO: Fix compilation problem // import * as logo from '../../assets/logo.jpeg'; @@ -31,12 +31,12 @@ interface Props { setLang: (l: string) => void; } -export default function NavigationBar({ lang, setLang }: Props): VNode { +export function NavigationBar({ lang, setLang }: Props): VNode { const [showLogin, setShowLogin] = useState(false) return (<nav class="navbar is-fixed-top" role="navigation" aria-label="main navigation"> <div class="navbar-brand"> <a class="navbar-item" href="https://taler.net"> - <img src="https://taler.net/static/images/logo-2020.jpg" style={{height: 50, maxHeight: 50}} /> + <img src="https://taler.net/static/images/logo-2020.jpg" style={{ height: 50, maxHeight: 50 }} /> </a> <a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample"> @@ -53,7 +53,7 @@ export default function NavigationBar({ lang, setLang }: Props): VNode { <div class="control has-icons-left"> <div class="select"> <select onChange={(e): void => setLang(e.currentTarget.value)}> - {Object.keys(i18n).map(l => <option selected={lang === l} value={l}>{l}</option>)} + {Object.keys(translations).map(l => <option selected={lang === l} value={l}>{l}</option>)} </select> </div> <div class="icon is-small is-left"> diff --git a/src/components/notifications/Notifications.stories.tsx b/src/components/notifications/Notifications.stories.tsx @@ -14,24 +14,24 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ /* eslint-disable @typescript-eslint/camelcase */ import { h, VNode } from 'preact'; -import Notification from './index' +import { Notifications } from './index' export default { title: 'Components/Notification', - component: Notification, + component: Notifications, }; export const NotificationInfo = (): VNode => { return <div> - <Notification notifications={[{ + <Notifications notifications={[{ messageId: 'unauthorized', type: 'INFO', }]} /> @@ -40,7 +40,7 @@ export const NotificationInfo = (): VNode => { export const NotificationWarn = (): VNode => { return <div> - <Notification notifications={[{ + <Notifications notifications={[{ messageId: 'unauthorized', type: 'WARN', }]} /> @@ -49,7 +49,7 @@ export const NotificationWarn = (): VNode => { export const NotificationError = (): VNode => { return <div> - <Notification notifications={[{ + <Notifications notifications={[{ messageId: 'unauthorized', type: 'ERROR', }]} /> @@ -58,7 +58,7 @@ export const NotificationError = (): VNode => { export const NotificationSuccess = (): VNode => { return <div> - <Notification notifications={[{ + <Notifications notifications={[{ messageId: 'unauthorized', type: 'SUCCESS', }]} /> diff --git a/src/components/notifications/index.tsx b/src/components/notifications/index.tsx @@ -37,7 +37,7 @@ function messageStyle(type: MessageType): string { } } -export default function Notifications({ notifications }: Props): VNode { +export function Notifications({ notifications }: Props): VNode { return <div class="toast"> {notifications.map(n => <article class={messageStyle(n.type)}> <div class="message-header"> diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx @@ -21,7 +21,7 @@ import { h, VNode } from 'preact'; -export default function Sidebar(): VNode { +export function Sidebar(): VNode { return ( <aside class="aside is-placed-left is-expanded"> <div class="aside-tools"> diff --git a/src/components/yup/YupField.tsx b/src/components/yup/YupField.tsx @@ -14,16 +14,16 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from "preact"; import { Text, useText } from "preact-i18n"; import { useState } from "preact/hooks"; import { useBackendConfig } from "../hooks/backend"; -import useBackend from "../hooks/useBackend"; +import { useBackend } from "../hooks"; import { intervalToDuration, formatDuration } from 'date-fns' function readableDuration(duration: number): string { @@ -50,7 +50,7 @@ interface Props2 { } -export default function YupField(name: string, field: string, errors: any, object: any, valueHandler: any, info: any): VNode { +export function YupField(name: string, field: string, errors: any, object: any, valueHandler: any, info: any): VNode { const updateField = (f: string) => (v: string): void => valueHandler((prev: any) => ({ ...prev, [f]: v })) const values = { name, errors, @@ -202,9 +202,9 @@ function YupInputWithAddon({ name, readonly, value, errors, onChange, addon, atT <div class="field-body"> <div class="field"> <div class="field has-addons"> - { !atTheEnd && <div class="control"> + {!atTheEnd && <div class="control"> <a class="button is-static">{addon}</a> - </div> } + </div>} <p class="control is-expanded"> <input class={errors[name] ? "input is-danger" : "input"} type="text" placeholder={dict.placeholder} readonly={readonly} @@ -212,9 +212,9 @@ function YupInputWithAddon({ name, readonly, value, errors, onChange, addon, atT onChange={(e): void => onChange(e.currentTarget.value)} /> <Text id={`fields.instance.${name}.help`} /> </p> - { atTheEnd && <div class="control"> + {atTheEnd && <div class="control"> <a class="button is-static">{addon}</a> - </div> } + </div>} </div> {errors[name] ? <p class="help is-danger"><Text id={`validation.${errors[name].type}`} fields={errors[name].params}>{errors[name].message}</Text></p> : null} </div> diff --git a/src/declaration.d.ts b/src/declaration.d.ts @@ -26,8 +26,8 @@ declare module "*.css" { export default mapping; } declare module "*.jpeg" { - const value: any; - export = value; + const mapping: Record<string, string>; + export default mapping; } declare module "*.scss" { diff --git a/src/i18n/index.ts b/src/i18n/index.ts @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -export default { +export const translations = { es: { confirm_modal: { title: 'confirmar accion', diff --git a/src/index.ts b/src/index.ts @@ -21,6 +21,9 @@ import "./scss/main.scss" -import App from './routes/index'; +// Automatic code splitting only supports default exports, not named exports: +// https://github.com/preactjs/preact-cli#route-based-code-splitting -export default App; +import PageRouter from './routes/index'; + +export default PageRouter; diff --git a/src/routes/dashboard/index.tsx b/src/routes/dashboard/index.tsx @@ -1,482 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 default function BulmaIndex({}): VNode { - return <div id="page"> - <section class="section is-title-bar"> - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <ul> - <li>Admin</li> - <li>Dashboard</li> - </ul> - </div> - </div> - </div> - </section> - <section class="hero is-hero-bar"> - <div class="hero-body"> - <div class="level"> - <div class="level-left"> - <div class="level-item"><h1 class="title"> - Dashboard - </h1></div> - </div> - <div class="level-right" style="display: none;"> - <div class="level-item" /> - </div> - </div> - </div> - </section> - <section class="section is-main-section"> - <div class="tile is-ancestor"> - <div class="tile is-parent"> - <div class="card tile is-child"> - <div class="card-content"> - <div class="level is-mobile"> - <div class="level-item"> - <div class="is-widget-label"><h3 class="subtitle is-spaced"> - Clients - </h3> - <h1 class="title"> - 512 - </h1> - </div> - </div> - <div class="level-item has-widget-icon"> - <div class="is-widget-icon"><span class="icon has-text-primary is-large"><i - class="mdi mdi-account-multiple mdi-48px" /></span> - </div> - </div> - </div> - </div> - </div> - </div> - <div class="tile is-parent"> - <div class="card tile is-child"> - <div class="card-content"> - <div class="level is-mobile"> - <div class="level-item"> - <div class="is-widget-label"><h3 class="subtitle is-spaced"> - Sales - </h3> - <h1 class="title"> - $7,770 - </h1> - </div> - </div> - <div class="level-item has-widget-icon"> - <div class="is-widget-icon"><span class="icon has-text-info is-large"><i - class="mdi mdi-cart-outline mdi-48px" /></span> - </div> - </div> - </div> - </div> - </div> - </div> - <div class="tile is-parent"> - <div class="card tile is-child"> - <div class="card-content"> - <div class="level is-mobile"> - <div class="level-item"> - <div class="is-widget-label"><h3 class="subtitle is-spaced"> - Performance - </h3> - <h1 class="title"> - 256% - </h1> - </div> - </div> - <div class="level-item has-widget-icon"> - <div class="is-widget-icon"><span class="icon has-text-success is-large"><i - class="mdi mdi-finance mdi-48px" /></span> - </div> - </div> - </div> - </div> - </div> - </div> - </div> - <div class="card"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-finance" /></span> - Performance - </p> - <a href="#" class="card-header-icon"> - <span class="icon"><i class="mdi mdi-reload" /></span> - </a> - </header> - <div class="card-content"> - <div class="chart-area"> - <div style="height: 100%;"> - <div class="chartjs-size-monitor"> - <div class="chartjs-size-monitor-expand"> - <div /> - </div> - <div class="chartjs-size-monitor-shrink"> - <div /> - </div> - </div> - <canvas id="big-line-chart" width="2992" height="1000" class="chartjs-render-monitor" style="display: block; height: 400px; width: 1197px;" /> - </div> - </div> - </div> - </div> - <div class="card has-table has-mobile-sort-spaced"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-account-multiple" /></span> - Clients - </p> - <a href="#" class="card-header-icon"> - <span class="icon"><i class="mdi mdi-reload" /></span> - </a> - </header> - <div class="card-content"> - <div class="b-table has-pagination"> - <div class="table-wrapper has-mobile-cards"> - <table class="table is-fullwidth is-striped is-hoverable is-sortable is-fullwidth"> - <thead> - <tr> - <th /> - <th>Name</th> - <th>Company</th> - <th>City</th> - <th>Progress</th> - <th>Created</th> - <th /> - </tr> - </thead> - <tbody> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/rebecca-bauch.svg" class="is-rounded" /> - </div> - </td> - <td>Rebecca Bauch</td> - <td>Daugherty-Daniel</td> - <td>South Cory</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="79">79</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Oct 25, 2020">Oct 25, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/felicita-yundt.svg" class="is-rounded" /> - </div> - </td> - <td>Felicita Yundt</td> - <td>Johns-Weissnat</td> - <td>East Ariel</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="67">67</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Jan 8, 2020">Jan 8, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/mr-larry-satterfield-v.svg" class="is-rounded" /> - </div> - </td> - <td>Mr. Larry Satterfield V</td> - <td>Hyatt Ltd</td> - <td>Windlerburgh</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="16">16</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Dec 18, 2020">Dec 18, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/mr-broderick-kub.svg" class="is-rounded" /> - </div> - </td> - <td>Mr. Broderick Kub</td> - <td>Kshlerin, Bauch and Ernser</td> - <td>New Kirstenport</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="71">71</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Sep 13, 2020">Sep 13, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/barry-weber.svg" class="is-rounded" /> - </div> - </td> - <td>Barry Weber</td> - <td>Schulist, Mosciski and Heidenreich</td> - <td>East Violettestad</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="80">80</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Jul 24, 2020">Jul 24, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/bert-kautzer-md.svg" class="is-rounded" /> - </div> - </td> - <td>Bert Kautzer MD</td> - <td>Gerhold and Sons</td> - <td>Mayeport</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="62">62</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Mar 30, 2020">Mar 30, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/lonzo-steuber.svg" class="is-rounded" /> - </div> - </td> - <td>Lonzo Steuber</td> - <td>Skiles Ltd</td> - <td>Marilouville</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="17">17</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Feb 12, 2020">Feb 12, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/jonathon-hahn.svg" class="is-rounded" /> - </div> - </td> - <td>Jonathon Hahn</td> - <td>Flatley Ltd</td> - <td>Billiemouth</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="74">74</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Dec 30, 2020">Dec 30, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/ryley-wuckert.svg" class="is-rounded" /> - </div> - </td> - <td>Ryley Wuckert</td> - <td>Heller-Little</td> - <td>Emeraldtown</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="54">54</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Jun 28, 2020">Jun 28, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - <tr> - <td class="is-image-cell"> - <div class="image"> - <img src="https://avatars.dicebear.com/4.5/api/male/sienna-hayes.svg" class="is-rounded" /> - </div> - </td> - <td>Sienna Hayes</td> - <td>Conn, Jerde and Douglas</td> - <td>Jonathanfort</td> - <td class="is-progress-cell"> - <progress max="100" class="progress is-small is-primary" value="55">55</progress> - </td> - <td> - <small class="has-text-grey is-abbr-like" title="Mar 7, 2020">Mar 7, 2020</small> - </td> - <td class="is-actions-cell"> - <div class="buttons is-right"> - <button class="button is-small is-primary" type="button"> - <span class="icon"><i class="mdi mdi-eye" /></span> - </button> - <button class="button is-small is-danger jb-modal" type="button"> - <span class="icon"><i class="mdi mdi-trash-can" /></span> - </button> - </div> - </td> - </tr> - </tbody> - </table> - </div> - <div class="notification"> - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <div class="buttons has-addons"> - <button type="button" class="button is-active">1</button> - <button type="button" class="button">2</button> - <button type="button" class="button">3</button> - </div> - </div> - </div> - <div class="level-right"> - <div class="level-item"> - <small>Page 1 of 3</small> - </div> - </div> - </div> - </div> - </div> - </div> - </div> - </section> -</div> - -} - -/** - * <div id="sample-modal" class="modal"> - <div class="modal-background jb-modal-close"></div> - <div class="modal-card"> - <header class="modal-card-head"> - <p class="modal-card-title">Confirm action</p> - <button class="delete jb-modal-close" aria-label="close"></button> - </header> - <section class="modal-card-body"> - <p>This will permanently delete <b>Some Object</b></p> - <p>This is sample modal</p> - </section> - <footer class="modal-card-foot"> - <button class="button jb-modal-close">Cancel</button> - <button class="button is-danger jb-modal-close">Delete</button> - </footer> - </div> - <button class="modal-close is-large jb-modal-close" aria-label="close"></button> -</div> - - */ -\ No newline at end of file diff --git a/src/routes/forms/index.tsx b/src/routes/forms/index.tsx @@ -1,279 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 default function BulmaForms({}): VNode { - return <div id="page"> - <section class="section is-title-bar"> - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <ul> - <li>Admin</li> - <li>Forms</li> - </ul> - </div> - </div> - </div> - </section> - <section class="hero is-hero-bar"> - <div class="hero-body"> - <div class="level"> - <div class="level-left"> - <div class="level-item"><h1 class="title"> - Forms - </h1></div> - </div> - <div class="level-right" style="display: none;"> - <div class="level-item" /> - </div> - </div> - </div> - </section> - <section class="section is-main-section"> - <div class="card"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-ballot" /></span> - Forms - </p> - </header> - <div class="card-content"> - <form method="get"> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">From</label> - </div> - <div class="field-body"> - <div class="field"> - <p class="control is-expanded has-icons-left"> - <input class="input" type="text" placeholder="Name" /> - <span class="icon is-small is-left"><i class="mdi mdi-account" /></span> - </p> - </div> - <div class="field"> - <p class="control is-expanded has-icons-left has-icons-right"> - <input class="input is-success" type="email" placeholder="Email" value="alex@smith.com" /> - <span class="icon is-small is-left"><i class="mdi mdi-mail" /></span> - <span class="icon is-small is-right"><i class="mdi mdi-check" /></span> - </p> - </div> - </div> - </div> - <div class="field is-horizontal"> - <div class="field-label" /> - <div class="field-body"> - <div class="field is-expanded"> - <div class="field has-addons"> - <p class="control"> - <a class="button is-static"> - +44 - </a> - </p> - <p class="control is-expanded"> - <input class="input" type="tel" placeholder="Your phone number" /> - </p> - </div> - <p class="help">Do not enter the first zero</p> - </div> - </div> - </div> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Department</label> - </div> - <div class="field-body"> - <div class="field is-narrow"> - <div class="control"> - <div class="select is-fullwidth"> - <select> - <option>Business development</option> - <option>Marketing</option> - <option>Sales</option> - </select> - </div> - </div> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Subject</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input class="input is-danger" type="text" placeholder="e.g. Partnership opportunity" /> - </div> - <p class="help is-danger"> - This field is required - </p> - </div> - </div> - </div> - - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Question</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <textarea class="textarea" placeholder="Explain how we can help you" /> - </div> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label"> - {/* Left empty for spacing */} - </div> - <div class="field-body"> - <div class="field"> - <div class="field is-grouped"> - <div class="control"> - <button type="submit" class="button is-primary"> - <span>Submit</span> - </button> - </div> - <div class="control"> - <button type="button" class="button is-primary is-outlined"> - <span>Reset</span> - </button> - </div> - </div> - </div> - </div> - </div> - </form> - </div> - </div> - <div class="card"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-ballot-outline default" /></span> - Custom elements - </p> - </header> - <div class="card-content"> - <div class="field has-check is-horizontal"> - <div class="field-label"><label class="label">Checkbox</label></div> - <div class="field-body"> - <div class="field"> - <div class="field is-grouped-multiline is-grouped"> - <div class="control"> - <label class="b-checkbox checkbox"><input type="checkbox" value="lorem" /> - <span class="check is-primary" /> - <span class="control-label">Lorem</span> - </label> - </div> - <div class="control"> - <label class="b-checkbox checkbox"><input type="checkbox" value="ipsum" /> - <span class="check is-primary" /> - <span class="control-label">Ipsum</span> - </label> - </div> - <div class="control"> - <label class="b-checkbox checkbox"><input type="checkbox" value="dolore" /> - <span class="check is-primary" /> - <span class="control-label">Dolore</span> - </label> - </div> - </div> - </div> - </div> - </div> - <hr /> - <div class="field has-check is-horizontal"> - <div class="field-label"><label class="label">Radio</label></div> - <div class="field-body"> - <div class="field"> - <div class="field is-grouped-multiline is-grouped"> - <div class="control"><label class="b-radio radio"><input type="radio" name="sample-radio" value="one" /> - <span class="check" /> - <span class="control-label">One</span> - </label></div> - <div class="control"><label class="b-radio radio"><input type="radio" name="sample-radio" value="two" /> - <span class="check" /> - <span class="control-label">Two</span> - </label> - </div> - </div> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label"><label class="label">Switch</label></div> - <div class="field-body"> - <div class="field"> - <label class="switch is-rounded"><input type="checkbox" value="false" /> - <span class="check" /> - <span class="control-label">Default</span> - </label> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label is-normal"><label class="label">File</label></div> - <div class="field-body"> - <div class="field"> - <div class="field file"> - <label class="upload control"> - <a class="button is-primary"> - <span class="icon"><i class="mdi mdi-upload" /></span> - <span>Pick a file</span> - </a> - <input type="file" /> - </label> - </div> - </div> - </div> - </div> - </div> - </div> - </section> - - - {/* <div id="sample-modal" class="modal"> - <div class="modal-background jb-modal-close" /> - <div class="modal-card"> - <header class="modal-card-head"> - <p class="modal-card-title">Confirm action</p> - <button class="delete jb-modal-close" aria-label="close" /> - </header> - <section class="modal-card-body"> - <p>This will permanently delete <b>Some Object</b></p> - <p>This is sample modal</p> - </section> - <footer class="modal-card-foot"> - <button class="button jb-modal-close">Cancel</button> - <button class="button is-danger jb-modal-close">Delete</button> - </footer> - </div> - <button class="modal-close is-large jb-modal-close" aria-label="close" /> - </div> */} -</div> -} -\ No newline at end of file diff --git a/src/routes/home/index.tsx b/src/routes/home/index.tsx @@ -1,61 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { FunctionalComponent, h } from 'preact'; -const Home: FunctionalComponent = () => { - return ( - <div> - <h1 class="title">Bulma</h1> - - <p class="subtitle"> - Modern CSS framework based on <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox">Flexbox</a> - </p> - - <div class="field"> - <div class="control"> - <input class="input" type="text" placeholder="Input" /> - </div> - </div> - - <div class="field"> - <p class="control"> - <span class="select"> - <select> - <option>Select dropdown</option> - </select> - </span> - </p> - </div> - - <div class="container"> - <div class="notification is-primary"> - This container is <strong>centered</strong> on desktop and larger viewports. - </div> - </div> - <div class="buttons"> - <a class="button is-primary">Primary</a> - <a class="button is-link">Link</a> - </div> - </div> - ); -}; - -export default Home; diff --git a/src/routes/index.tsx b/src/routes/index.tsx @@ -14,38 +14,37 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from 'preact'; import { Route, Router } from 'preact-router'; import { IntlProvider } from 'preact-i18n'; - +import { Footer } from '../components/footer'; +import { Sidebar } from '../components/sidebar'; import NotFoundPage from './notfound'; import Instances from './instances'; -import Footer from '../components/footer'; -import Sidebar from '../components/sidebar'; -import NavigationBar from '../components/navbar'; -import Notifications from '../components/notifications'; +import { NavigationBar } from '../components/navbar'; +import { Notifications } from '../components/notifications'; import { useNotifications } from '../hooks/notifications'; -import i18n from '../i18n'; -import useLang from '../components/hooks/useLang'; +import { translations } from '../i18n'; +import { useLang } from '../components/hooks'; export default function PageRouter(): VNode { const { notifications, pushNotification } = useNotifications() const [lang, setLang] = useLang() return ( - <IntlProvider definition={(i18n as any)[lang] || i18n.en }> + <IntlProvider definition={(translations as any)[lang] || translations.en}> <div id="app"> <NavigationBar lang={lang} setLang={setLang} /> <Sidebar /> <Notifications notifications={notifications} /> <Router> <Route path="/" component={Instances} pushNotification={pushNotification} /> - <NotFoundPage default /> + <NotFoundPage /> </Router> <Footer /> </div> diff --git a/src/routes/instances/CardTable.tsx b/src/routes/instances/CardTable.tsx @@ -14,17 +14,17 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from "preact"; import { Text } from "preact-i18n"; import { useEffect, useState } from "preact/hooks"; import { MerchantBackend, WidthId as WithId } from "../../declaration"; -import EmptyTable from "./EmptyTable"; -import Table from "./Table"; +import { EmptyTable } from "./EmptyTable"; +import { Table } from "./Table"; interface Props { instances: MerchantBackend.Instances.Instance[]; @@ -48,7 +48,7 @@ function buildActions(intances: MerchantBackend.Instances.Instance[], selected: .map(id => ({ element: id, type: action })) } -export default function CardTable({ instances, onCreate, onSelect, selected }: Props): VNode { +export function CardTable({ instances, onCreate, onSelect, selected }: Props): VNode { const [actionQueue, actionQueueHandler] = useState<Actions[]>([]); const [rowSelection, rowSelectionHandler] = useState<string[]>([]) diff --git a/src/routes/instances/Create.stories.tsx b/src/routes/instances/Create.stories.tsx @@ -21,12 +21,12 @@ /* eslint-disable @typescript-eslint/camelcase */ import { h, VNode } from 'preact'; -import Create from './Create' +import {CreatePage} from './CreatePage' export default { title: 'Instances/CreateModal', - component: Create, + component: CreatePage, argTypes: { element: { control: 'object' }, onCancel: { action: 'onCancel' }, @@ -34,4 +34,4 @@ export default { } }; -export const Example = (a: any): VNode => <Create {...a} />; +export const Example = (a: any): VNode => <CreatePage {...a} />; diff --git a/src/routes/instances/Create.tsx b/src/routes/instances/Create.tsx @@ -1,111 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { MerchantBackend } from "../../declaration"; -import * as yup from 'yup'; -import YupField from "../../components/yup/YupField" -import { InstanceCreateSchema as schema } from '../../schemas' -import { Text } from "preact-i18n"; - -interface Props { - onCreate: (d: MerchantBackend.Instances.InstanceConfigurationMessage) => void; - isLoading: boolean; - goBack: () => void; -} - -interface KeyValue { - [key: string]: string; -} - -function with_defaults(): Partial<MerchantBackend.Instances.InstanceConfigurationMessage> { - return { - default_pay_delay: { d_ms: 1000 }, - default_wire_fee_amortization: 10, - default_wire_transfer_delay: { d_ms: 2000 }, - }; -} - -export default function CreateModal({ onCreate, isLoading, goBack }: Props): VNode { - const [value, valueHandler] = useState(with_defaults()) - const [errors, setErrors] = useState<KeyValue>({}) - - const submit = (): void => { - try { - schema.validateSync(value, { abortEarly: false }) - onCreate(schema.cast(value) as MerchantBackend.Instances.InstanceConfigurationMessage); - goBack() - } catch (err) { - const errors = err.inner as yup.ValidationError[] - const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message } }), {}) - setErrors(pathMessages) - } - } - - return <div> - <section class="section is-title-bar"> - - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <ul> - <li><Text id="text.merchant" /></li> - <li><Text id="text.instances" /></li> - </ul> - </div> - </div> - </div> - </section> - - <section class={isLoading ? "hero is-hero-bar" : "hero is-hero-bar is-loading"}> - <div class="hero-body"> - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <h1 class="title"> - <Text id="text.create_new_instances" /> - </h1> - </div> - </div> - <div class="level-right" style="display: none;"> - <div class="level-item" /> - </div> - </div> - </div> - </section> - - <section class="section is-main-section"> - <div class="columns"> - <div class="column" /> - <div class="column is-two-thirds"> - {Object.keys(schema.fields).map(f => YupField(f, f, errors, value, valueHandler, schema.fields[f].describe()))} - <div class="buttons is-right"> - <button class="button" onClick={goBack} ><Text id="cancel" /></button> - <button class="button is-success" onClick={submit} ><Text id="confirm" /></button> - </div> - </div> - <div class="column" /> - </div> - </section> - - </div> -} -\ No newline at end of file diff --git a/src/routes/instances/CreatePage.tsx b/src/routes/instances/CreatePage.tsx @@ -0,0 +1,111 @@ +/* + This file is part of GNU Taler + (C) 2021 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 { MerchantBackend } from "../../declaration"; +import * as yup from 'yup'; +import { YupField } from "../../components/yup/YupField" +import { InstanceCreateSchema as schema } from '../../schemas' +import { Text } from "preact-i18n"; + +interface Props { + onCreate: (d: MerchantBackend.Instances.InstanceConfigurationMessage) => void; + isLoading: boolean; + goBack: () => void; +} + +interface KeyValue { + [key: string]: string; +} + +function with_defaults(): Partial<MerchantBackend.Instances.InstanceConfigurationMessage> { + return { + default_pay_delay: { d_ms: 1000 }, + default_wire_fee_amortization: 10, + default_wire_transfer_delay: { d_ms: 2000 }, + }; +} + +export function CreatePage({ onCreate, isLoading, goBack }: Props): VNode { + const [value, valueHandler] = useState(with_defaults()) + const [errors, setErrors] = useState<KeyValue>({}) + + const submit = (): void => { + try { + schema.validateSync(value, { abortEarly: false }) + onCreate(schema.cast(value) as MerchantBackend.Instances.InstanceConfigurationMessage); + goBack() + } catch (err) { + const errors = err.inner as yup.ValidationError[] + const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message } }), {}) + setErrors(pathMessages) + } + } + + return <div> + <section class="section is-title-bar"> + + <div class="level"> + <div class="level-left"> + <div class="level-item"> + <ul> + <li><Text id="text.merchant" /></li> + <li><Text id="text.instances" /></li> + </ul> + </div> + </div> + </div> + </section> + + <section class={isLoading ? "hero is-hero-bar" : "hero is-hero-bar is-loading"}> + <div class="hero-body"> + <div class="level"> + <div class="level-left"> + <div class="level-item"> + <h1 class="title"> + <Text id="text.create_new_instances" /> + </h1> + </div> + </div> + <div class="level-right" style="display: none;"> + <div class="level-item" /> + </div> + </div> + </div> + </section> + + <section class="section is-main-section"> + <div class="columns"> + <div class="column" /> + <div class="column is-two-thirds"> + {Object.keys(schema.fields).map(f => YupField(f, f, errors, value, valueHandler, schema.fields[f].describe()))} + <div class="buttons is-right"> + <button class="button" onClick={goBack} ><Text id="cancel" /></button> + <button class="button is-success" onClick={submit} ><Text id="confirm" /></button> + </div> + </div> + <div class="column" /> + </div> + </section> + + </div> +} +\ No newline at end of file diff --git a/src/routes/instances/DeleteModal.tsx b/src/routes/instances/DeleteModal.tsx @@ -14,14 +14,14 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from "preact"; import { MerchantBackend, WidthId } from "../../declaration"; -import ConfirmModal from "../../components/modal"; +import { ConfirmModal } from "../../components/modal"; interface Props { element: MerchantBackend.Instances.QueryInstancesResponse & WidthId; @@ -29,7 +29,7 @@ interface Props { onConfirm: (i: MerchantBackend.Instances.QueryInstancesResponse & WidthId) => void; } -export default function DeleteModal({ element, onCancel, onConfirm }: Props): VNode { +export function DeleteModal({ element, onCancel, onConfirm }: Props): VNode { return <ConfirmModal description="delete_instance" danger active onCancel={onCancel} onConfirm={() => onConfirm(element)}> <p>This will permanently delete instance "{element.name}" with id <b>{element.id}</b></p> <p>Please confirm this action</p> diff --git a/src/routes/instances/EmptyTable.tsx b/src/routes/instances/EmptyTable.tsx @@ -22,7 +22,7 @@ import { h, VNode } from "preact"; import { Text } from "preact-i18n"; -export default function EmptyTable(): VNode { +export function EmptyTable(): VNode { return <div class="content has-text-grey has-text-centered"> <p> <span class="icon is-large"><i class="mdi mdi-emoticon-sad mdi-48px" /></span> diff --git a/src/routes/instances/Table.tsx b/src/routes/instances/Table.tsx @@ -35,7 +35,7 @@ function toggleSelected<T>(id: T): (prev: T[]) => T[] { return (prev: T[]): T[] => prev.indexOf(id) == -1 ? [...prev, id] : prev.filter(e => e != id) } -export default function Table({ rowSelection, rowSelectionHandler, instances, onSelect }: Props): VNode { +export function Table({ rowSelection, rowSelectionHandler, instances, onSelect }: Props): VNode { return ( <table class="table is-fullwidth is-striped is-hoverable is-fullwidth"> <thead> diff --git a/src/routes/instances/Update.tsx b/src/routes/instances/Update.tsx @@ -1,117 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { MerchantBackend, WidthId } from "../../declaration"; -import * as yup from 'yup'; -import YupField from "../../components/yup/YupField" -import { InstanceUpdateSchema as schema } from '../../schemas' -import { Text } from "preact-i18n"; - -interface Props { - onUpdate: (id: string, d: MerchantBackend.Instances.InstanceReconfigurationMessage) => void; - selected: MerchantBackend.Instances.QueryInstancesResponse & WidthId; - isLoading: boolean; - goBack: () => void; -} - -interface KeyValue { - [key: string]: string; -} - -function convert(from: MerchantBackend.Instances.QueryInstancesResponse): MerchantBackend.Instances.InstanceReconfigurationMessage { - const { accounts, ...rest} = from - const payto_uris = accounts.filter(a => a.active).map(a => a.payto_uri) - const defaults = { - default_wire_fee_amortization: 1, - default_pay_delay: { d_ms: 1000*60*60 }, //one hour - default_wire_transfer_delay: { d_ms: 1000*60*60*2 }, //two hours - } - return { ...defaults, ...rest, payto_uris }; -} - -export default function UpdateModal({ onUpdate, isLoading, selected, goBack }: Props): VNode { - const [value, valueHandler] = useState(convert(selected)) - const [errors, setErrors] = useState<KeyValue>({}) - - const submit = (): void => { - try { - schema.validateSync(value, { abortEarly: false }) - onUpdate(selected.id, schema.cast(value)); - goBack() - } catch (err) { - const errors = err.inner as yup.ValidationError[] - const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message } }), {}) - setErrors(pathMessages) - } - } - - return <div> - <section class="section is-title-bar"> - - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <ul> - <li><Text id="text.merchant" /></li> - <li><Text id="text.instances" /></li> - </ul> - </div> - </div> - </div> - </section> - - <section class={isLoading ? "hero is-hero-bar" : "hero is-hero-bar is-loading"}> - <div class="hero-body"> - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <h1 class="title"> - <Text id="text.create_new_instances" /> - </h1> - </div> - </div> - <div class="level-right" style="display: none;"> - <div class="level-item" /> - </div> - </div> - </div> - </section> - - <section class="section is-main-section"> - <div class="columns"> - <div class="column" /> - <div class="column is-two-thirds"> - {Object.keys(schema.fields).map(f => YupField(f, f, errors, value, valueHandler, schema.fields[f].describe()))} - <div class="buttons is-right"> - <button class="button" onClick={goBack} ><Text id="cancel" /></button> - <button class="button is-success" onClick={submit} ><Text id="confirm" /></button> - </div> - </div> - <div class="column" /> - </div> - </section> - - </div> - - // </ConfirmModal> -} -\ No newline at end of file diff --git a/src/routes/instances/UpdateModal.stories.tsx b/src/routes/instances/UpdateModal.stories.tsx @@ -1,45 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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) - */ - -/* eslint-disable @typescript-eslint/camelcase */ -import { h, VNode } from 'preact'; -import UpdateModal from './UpdateModal' - - -export default { - title: 'Instances/UpdateModal', - component: UpdateModal, - argTypes: { - element: { control: 'object' }, - onCancel: { action: 'onCancel' }, - onConfirm: { action: 'onConfirm' }, - } -}; - -export const WithDefaultInstance = (a: any): VNode => <UpdateModal {...a} />; -WithDefaultInstance.args = { - element: { - id: 'default', - name: 'update', - merchant_pub: 'abcdef', - payment_targets: ['qwe','asd'] - } -} diff --git a/src/routes/instances/UpdateModal.tsx b/src/routes/instances/UpdateModal.tsx @@ -1,57 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 { KeyValue, MerchantBackend } from "../../declaration"; -import * as yup from 'yup'; -import ConfirmModal from '../../components/modal' -import YupField from "../../components/yup/YupField"; -import { InstanceUpdateSchema as schema } from '../../schemas' - -interface Props { - element: MerchantBackend.Instances.QueryInstancesResponse | null; - onCancel: () => void; - onConfirm: (i: MerchantBackend.Instances.InstanceReconfigurationMessage) => void; -} - -export default function UpdateModal({ element, onCancel, onConfirm }: Props): VNode { - const copy: any = !element ? {} : Object.keys(schema.fields).reduce((prev, cur) => ({ ...prev, [cur]: (element as any)[cur] }), {}) - - const [value, valueHandler] = useState(copy) - const [errors, setErrors] = useState<KeyValue>({}) - - const submit = (): void => { - try { - schema.validateSync(value, { abortEarly: false }) - - onConfirm(schema.cast(value) as MerchantBackend.Instances.InstanceReconfigurationMessage); - } catch (err) { - const errors = err.inner as yup.ValidationError[] - const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message } }), {}) - setErrors(pathMessages) - } - } - - return <ConfirmModal description="update_instance" active={element != null} onConfirm={submit} onCancel={onCancel}> - {Object.keys(schema.fields).map(f => YupField(f, f, errors, value, valueHandler, schema.fields[f].describe()))} - </ConfirmModal> -} -\ No newline at end of file diff --git a/src/routes/instances/UpdatePage.tsx b/src/routes/instances/UpdatePage.tsx @@ -0,0 +1,117 @@ +/* + This file is part of GNU Taler + (C) 2021 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 { MerchantBackend, WidthId } from "../../declaration"; +import * as yup from 'yup'; +import { YupField } from "../../components/yup/YupField" +import { InstanceUpdateSchema as schema } from '../../schemas' +import { Text } from "preact-i18n"; + +interface Props { + onUpdate: (id: string, d: MerchantBackend.Instances.InstanceReconfigurationMessage) => void; + selected: MerchantBackend.Instances.QueryInstancesResponse & WidthId; + isLoading: boolean; + goBack: () => void; +} + +interface KeyValue { + [key: string]: string; +} + +function convert(from: MerchantBackend.Instances.QueryInstancesResponse): MerchantBackend.Instances.InstanceReconfigurationMessage { + const { accounts, ...rest } = from + const payto_uris = accounts.filter(a => a.active).map(a => a.payto_uri) + const defaults = { + default_wire_fee_amortization: 1, + default_pay_delay: { d_ms: 1000 * 60 * 60 }, //one hour + default_wire_transfer_delay: { d_ms: 1000 * 60 * 60 * 2 }, //two hours + } + return { ...defaults, ...rest, payto_uris }; +} + +export function UpdatePage({ onUpdate, isLoading, selected, goBack }: Props): VNode { + const [value, valueHandler] = useState(convert(selected)) + const [errors, setErrors] = useState<KeyValue>({}) + + const submit = (): void => { + try { + schema.validateSync(value, { abortEarly: false }) + onUpdate(selected.id, schema.cast(value)); + goBack() + } catch (err) { + const errors = err.inner as yup.ValidationError[] + const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message } }), {}) + setErrors(pathMessages) + } + } + + return <div> + <section class="section is-title-bar"> + + <div class="level"> + <div class="level-left"> + <div class="level-item"> + <ul> + <li><Text id="text.merchant" /></li> + <li><Text id="text.instances" /></li> + </ul> + </div> + </div> + </div> + </section> + + <section class={isLoading ? "hero is-hero-bar" : "hero is-hero-bar is-loading"}> + <div class="hero-body"> + <div class="level"> + <div class="level-left"> + <div class="level-item"> + <h1 class="title"> + <Text id="text.create_new_instances" /> + </h1> + </div> + </div> + <div class="level-right" style="display: none;"> + <div class="level-item" /> + </div> + </div> + </div> + </section> + + <section class="section is-main-section"> + <div class="columns"> + <div class="column" /> + <div class="column is-two-thirds"> + {Object.keys(schema.fields).map(f => YupField(f, f, errors, value, valueHandler, schema.fields[f].describe()))} + <div class="buttons is-right"> + <button class="button" onClick={goBack} ><Text id="cancel" /></button> + <button class="button is-success" onClick={submit} ><Text id="confirm" /></button> + </div> + </div> + <div class="column" /> + </div> + </section> + + </div> + + // </ConfirmModal> +} +\ No newline at end of file diff --git a/src/routes/instances/View.stories.tsx b/src/routes/instances/View.stories.tsx @@ -14,14 +14,14 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ /* eslint-disable @typescript-eslint/camelcase */ import { h } from 'preact'; -import View from './View' +import { View } from './View' export default { @@ -54,30 +54,30 @@ WithFiveInstance.args = { name: 'the first instance', merchant_pub: 'abcdefgh', payment_targets: ['asd'] - },{ + }, { id: 'second', name: 'the second instance', merchant_pub: 'zxczxcz', payment_targets: ['asd'] - },{ + }, { id: 'third', name: 'the third instance', merchant_pub: 'QWEQWEWQE', payment_targets: ['asd'] - },{ + }, { id: 'other', name: 'the other instance', merchant_pub: 'FHJHGJGHJ', payment_targets: ['asd'] - },{ + }, { id: 'another', name: 'the another instance', merchant_pub: 'abcd3423423efgh', payment_targets: ['asd'] - },{ + }, { id: 'last', name: 'last instance', merchant_pub: 'zxcvvbnm', - payment_targets: ['pay-to','asd'] + payment_targets: ['pay-to', 'asd'] }] } diff --git a/src/routes/instances/View.tsx b/src/routes/instances/View.tsx @@ -14,16 +14,16 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { MerchantBackend, WidthId } from "../../declaration"; -import Table from './CardTable'; -import DeleteModal from './DeleteModal' +import { CardTable } from './CardTable'; +import { DeleteModal } from './DeleteModal' import { Text } from "preact-i18n"; interface Props { @@ -36,7 +36,7 @@ interface Props { isLoading: boolean; } -export default function View({ instances, isLoading, onCreate, onDelete, onSelect, onUpdate, selected }: Props): VNode { +export function View({ instances, isLoading, onCreate, onDelete, onSelect, onUpdate, selected }: Props): VNode { const [action, setAction] = useState<'UPDATE' | 'DELETE' | null>(null) const onSelectAction = (id: string | null, action?: 'UPDATE' | 'DELETE'): void => { @@ -77,7 +77,7 @@ export default function View({ instances, isLoading, onCreate, onDelete, onSelec </div> </section> <section class="section is-main-section"> - <Table instances={instances} onSelect={onSelectAction} selected={selected} onCreate={(): void => onCreate(true)} /> + <CardTable instances={instances} onSelect={onSelectAction} selected={selected} onCreate={(): void => onCreate(true)} /> </section> {selected && action === 'DELETE' ? diff --git a/src/routes/instances/index.tsx b/src/routes/instances/index.tsx @@ -14,19 +14,19 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h, VNode } from 'preact'; -import View from './View'; -import LoginPage from '../../components/auth/LoginPage'; +import { View } from './View'; +import { LoginPage } from '../../components/auth'; import { useBackendInstance, useBackendInstances } from '../../components/hooks/backend'; import { useEffect, useState } from 'preact/hooks'; import { Notification } from '../../declaration'; -import CreatePage from './Create'; -import UpdatePage from './Update'; +import { CreatePage } from './CreatePage'; +import { UpdatePage } from './UpdatePage'; interface Props { pushNotification: (n: Notification) => void; @@ -50,7 +50,7 @@ export default function Instances({ pushNotification }: Props): VNode { if (requiresToken) { pushNotification({ messageId: 'unauthorized', type: 'ERROR' }) } else if (genericError) { - pushNotification({messageId: 'error', params: genericError, type: 'ERROR'}) + pushNotification({ messageId: 'error', params: genericError, type: 'ERROR' }) } }, [requiresToken, genericError]) @@ -60,8 +60,8 @@ export default function Instances({ pushNotification }: Props): VNode { } if (create) { - return <CreatePage - goBack={() => setCreate(false)} + return <CreatePage + goBack={() => setCreate(false)} isLoading={false} onCreate={(d): Promise<void> => list.create(d) @@ -72,8 +72,8 @@ export default function Instances({ pushNotification }: Props): VNode { } if (update && details.data && selectedId) { - return <UpdatePage - goBack={() => setUpdate(false)} + return <UpdatePage + goBack={() => setUpdate(false)} isLoading={false} selected={{ ...details.data, id: selectedId }} onUpdate={(id, d): Promise<void> => details.update(id, d) diff --git a/src/routes/notfound/index.tsx b/src/routes/notfound/index.tsx @@ -19,10 +19,10 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { FunctionalComponent, h } from 'preact'; +import { h, VNode } from 'preact'; import { Link } from 'preact-router/match'; -const Notfound: FunctionalComponent = () => { +export default function NotFoundPage(): VNode { return ( <div> <h1>Error 404</h1> @@ -32,6 +32,5 @@ const Notfound: FunctionalComponent = () => { </Link> </div> ); -}; +} -export default Notfound; diff --git a/src/routes/profile/index.tsx b/src/routes/profile/index.tsx @@ -1,239 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 default function BulmaProfile({}): VNode { - return <div id="app"> - <section class="section is-title-bar"> - <div class="level"> - <div class="level-left"> - <div class="level-item"> - <ul> - <li>Admin</li> - <li>Profile</li> - </ul> - </div> - </div> - </div> - </section> - <section class="hero is-hero-bar"> - <div class="hero-body"> - <div class="level"> - <div class="level-left"> - <div class="level-item"><h1 class="title"> - Profile - </h1></div> - </div> - <div class="level-right" style="display: none;"> - <div class="level-item" /> - </div> - </div> - </div> - </section> - <section class="section is-main-section"> - <div class="tile is-ancestor"> - <div class="tile is-parent"> - <div class="card tile is-child"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-account-circle default" /></span> - Edit Profile - </p> - </header> - <div class="card-content"> - <form> - <div class="field is-horizontal"> - <div class="field-label is-normal"><label class="label">Avatar</label></div> - <div class="field-body"> - <div class="field"> - <div class="field file"> - <label class="upload control"> - <a class="button is-primary"> - <span class="icon"><i class="mdi mdi-upload default" /></span> - <span>Pick a file</span> - </a> - <input type="file" /> - </label> - </div> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Name</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input type="text" autocomplete="on" name="name" value="John Doe" class="input" required /> - </div> - <p class="help">Required. Your name</p> - </div> - </div> - </div> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">E-mail</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input type="email" autocomplete="on" name="email" value="user@example.com" class="input" required /> - </div> - <p class="help">Required. Your e-mail</p> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label is-normal" /> - <div class="field-body"> - <div class="field"> - <div class="control"> - <button type="submit" class="button is-primary"> - Submit - </button> - </div> - </div> - </div> - </div> - </form> - </div> - </div> - </div> - <div class="tile is-parent"> - <div class="card tile is-child"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-account default" /></span> - Profile - </p> - </header> - <div class="card-content"> - <div class="is-user-avatar image has-max-width is-aligned-center"> - <img src="https://avatars.dicebear.com/4.5/api/male/john-doe.svg" alt="John Doe" /> - </div> - <hr /> - <div class="field"> - <label class="label">Name</label> - <div class="control is-clearfix"> - <input type="text" readonly value="John Doe" class="input is-static" /> - </div> - </div> - <hr /> - <div class="field"> - <label class="label">E-mail</label> - <div class="control is-clearfix"> - <input type="text" readonly value="user@example.com" class="input is-static" /> - </div> - </div> - </div> - </div> - </div> - </div> - <div class="card"> - <header class="card-header"> - <p class="card-header-title"> - <span class="icon"><i class="mdi mdi-lock default" /></span> - Change Password - </p> - </header> - <div class="card-content"> - <form> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Current password</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input type="password" name="password_current" autocomplete="current-password" class="input" required /> - </div> - <p class="help">Required. Your current password</p></div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">New password</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input type="password" autocomplete="new-password" name="password" class="input" required /> - </div> - <p class="help">Required. New password</p> - </div> - </div> - </div> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label">Confirm password</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input type="password" autocomplete="new-password" name="password_confirmation" class="input" required /> - </div> - <p class="help">Required. New password one more time</p> - </div> - </div> - </div> - <hr /> - <div class="field is-horizontal"> - <div class="field-label is-normal" /> - <div class="field-body"> - <div class="field"> - <div class="control"> - <button type="submit" class="button is-primary"> - Submit - </button> - </div> - </div> - </div> - </div> - </form> - </div> - </div> - </section> - - <div id="sample-modal" class="modal"> - <div class="modal-background jb-modal-close" /> - <div class="modal-card"> - <header class="modal-card-head"> - <p class="modal-card-title">Confirm action</p> - <button class="delete jb-modal-close" aria-label="close" /> - </header> - <section class="modal-card-body"> - <p>This will permanently delete <b>Some Object</b></p> - <p>This is sample modal</p> - </section> - <footer class="modal-card-foot"> - <button class="button jb-modal-close">Cancel</button> - <button class="button is-danger jb-modal-close">Delete</button> - </footer> - </div> - <button class="modal-close is-large jb-modal-close" aria-label="close" /> - </div> -</div> -} diff --git a/tests/header.test.tsx b/tests/header.test.tsx @@ -14,13 +14,13 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * - * @author Sebastian Javier Marchano (sebasjm) - */ +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ import { h } from 'preact'; -import Footer from '../src/components/footer'; +import { Footer } from '../src/components/footer'; // See: https://github.com/preactjs/enzyme-adapter-preact-pure import { shallow } from 'enzyme'; diff --git a/tsconfig.json b/tsconfig.json @@ -1,24 +1,3 @@ -/* - This file is part of GNU Taler - (C) 2021 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) - */ - { "compilerOptions": { /* Basic Options */