diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/components')
10 files changed, 169 insertions, 136 deletions
diff --git a/packages/taler-wallet-webextension/src/components/Checkbox.tsx b/packages/taler-wallet-webextension/src/components/Checkbox.tsx index 276ac9ff0..59e84f4b0 100644 --- a/packages/taler-wallet-webextension/src/components/Checkbox.tsx +++ b/packages/taler-wallet-webextension/src/components/Checkbox.tsx @@ -14,8 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { JSX } from "preact/jsx-runtime"; -import { h } from "preact"; +import { h, VNode } from "preact"; interface Props { enabled: boolean; @@ -30,7 +29,7 @@ export function Checkbox({ onToggle, label, description, -}: Props): JSX.Element { +}: Props): VNode { return ( <div> <input diff --git a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx index 2fc8316f5..3b9519f39 100644 --- a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx +++ b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx @@ -14,9 +14,8 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { JSX } from "preact/jsx-runtime"; import { Outlined, StyledCheckboxLabel } from "./styled/index"; -import { h } from "preact"; +import { h, VNode } from "preact"; interface Props { enabled: boolean; @@ -47,7 +46,7 @@ export function CheckboxOutlined({ enabled, onToggle, label, -}: Props): JSX.Element { +}: Props): VNode { return ( <Outlined> <StyledCheckboxLabel onClick={onToggle}> diff --git a/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx b/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx index 952df15ae..b57075805 100644 --- a/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx +++ b/packages/taler-wallet-webextension/src/components/DebugCheckbox.tsx @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { JSX, h } from "preact"; +import { h, VNode } from "preact"; export function DebugCheckbox({ enabled, @@ -22,7 +22,7 @@ export function DebugCheckbox({ }: { enabled: boolean; onToggle: () => void; -}): JSX.Element { +}): VNode { return ( <div> <input diff --git a/packages/taler-wallet-webextension/src/components/Diagnostics.tsx b/packages/taler-wallet-webextension/src/components/Diagnostics.tsx index 0f8afd525..d368a10bf 100644 --- a/packages/taler-wallet-webextension/src/components/Diagnostics.tsx +++ b/packages/taler-wallet-webextension/src/components/Diagnostics.tsx @@ -15,8 +15,7 @@ */ import { WalletDiagnostics } from "@gnu-taler/taler-util"; -import { h } from "preact"; -import { JSX } from "preact/jsx-runtime"; +import { Fragment, h, VNode } from "preact"; import { PageLink } from "../renderHtml"; interface Props { @@ -24,51 +23,47 @@ interface Props { diagnostics: WalletDiagnostics | undefined; } -export function Diagnostics({ - timedOut, - diagnostics, -}: Props): JSX.Element | null { +export function Diagnostics({ timedOut, diagnostics }: Props): VNode { if (timedOut) { return <p>Diagnostics timed out. Could not talk to the wallet backend.</p>; } if (diagnostics) { if (diagnostics.errors.length === 0) { - return null; - } else { - return ( - <div - style={{ - borderLeft: "0.5em solid red", - paddingLeft: "1em", - paddingTop: "0.2em", - paddingBottom: "0.2em", - }} - > - <p>Problems detected:</p> - <ol> - {diagnostics.errors.map((errMsg) => ( - <li key={errMsg}>{errMsg}</li> - ))} - </ol> - {diagnostics.firefoxIdbProblem ? ( - <p> - Please check in your <code>about:config</code> settings that you - have IndexedDB enabled (check the preference name{" "} - <code>dom.indexedDB.enabled</code>). - </p> - ) : null} - {diagnostics.dbOutdated ? ( - <p> - Your wallet database is outdated. Currently automatic migration is - not supported. Please go{" "} - <PageLink pageName="/reset-required">here</PageLink> to reset the - wallet database. - </p> - ) : null} - </div> - ); + return <Fragment />; } + return ( + <div + style={{ + borderLeft: "0.5em solid red", + paddingLeft: "1em", + paddingTop: "0.2em", + paddingBottom: "0.2em", + }} + > + <p>Problems detected:</p> + <ol> + {diagnostics.errors.map((errMsg) => ( + <li key={errMsg}>{errMsg}</li> + ))} + </ol> + {diagnostics.firefoxIdbProblem ? ( + <p> + Please check in your <code>about:config</code> settings that you + have IndexedDB enabled (check the preference name{" "} + <code>dom.indexedDB.enabled</code>). + </p> + ) : null} + {diagnostics.dbOutdated ? ( + <p> + Your wallet database is outdated. Currently automatic migration is + not supported. Please go{" "} + <PageLink pageName="/reset-required">here</PageLink> to reset the + wallet database. + </p> + ) : null} + </div> + ); } return <p>Running diagnostics ...</p>; diff --git a/packages/taler-wallet-webextension/src/components/EditableText.tsx b/packages/taler-wallet-webextension/src/components/EditableText.tsx index 8b3e6d375..72bfbe809 100644 --- a/packages/taler-wallet-webextension/src/components/EditableText.tsx +++ b/packages/taler-wallet-webextension/src/components/EditableText.tsx @@ -14,9 +14,8 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { h } from "preact"; +import { h, VNode } from "preact"; import { useRef, useState } from "preact/hooks"; -import { JSX } from "preact/jsx-runtime"; interface Props { value: string; @@ -31,31 +30,35 @@ export function EditableText({ onChange, label, description, -}: Props): JSX.Element { +}: Props): VNode { const [editing, setEditing] = useState(false); const ref = useRef<HTMLInputElement>(null); let InputText; if (!editing) { - InputText = () => ( - <div style={{ display: "flex", justifyContent: "space-between" }}> - <p>{value}</p> - <button onClick={() => setEditing(true)}>edit</button> - </div> - ); + InputText = function InputToEdit(): VNode { + return ( + <div style={{ display: "flex", justifyContent: "space-between" }}> + <p>{value}</p> + <button onClick={() => setEditing(true)}>edit</button> + </div> + ); + }; } else { - InputText = () => ( - <div style={{ display: "flex", justifyContent: "space-between" }}> - <input value={value} ref={ref} type="text" id={`text-${name}`} /> - <button - onClick={() => { - if (ref.current) - onChange(ref.current.value).then((r) => setEditing(false)); - }} - > - confirm - </button> - </div> - ); + InputText = function InputEditing(): VNode { + return ( + <div style={{ display: "flex", justifyContent: "space-between" }}> + <input value={value} ref={ref} type="text" id={`text-${name}`} /> + <button + onClick={() => { + if (ref.current) + onChange(ref.current.value).then(() => setEditing(false)); + }} + > + confirm + </button> + </div> + ); + }; } return ( <div> diff --git a/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx b/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx index 6d2731cd8..a71108c50 100644 --- a/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx +++ b/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx @@ -13,12 +13,10 @@ 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 { Fragment, VNode } from "preact"; +import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; -import { JSXInternal } from "preact/src/jsx"; -import { h } from "preact"; -export function ExchangeXmlTos({ doc }: { doc: Document }) { +export function ExchangeXmlTos({ doc }: { doc: Document }): VNode { const termsNode = doc.querySelector("[ids=terms-of-service]"); if (!termsNode) { return ( @@ -70,7 +68,7 @@ function renderChild(child: Element): VNode { default: return ( <div style={{ color: "red", display: "hidden" }}> - unknown tag {child.nodeName} <a></a> + unknown tag {child.nodeName} </div> ); } @@ -81,10 +79,10 @@ function renderChild(child: Element): VNode { * @returns */ function AnchorWithOpenState( - props: JSXInternal.HTMLAttributes<HTMLAnchorElement>, -) { + props: h.JSX.HTMLAttributes<HTMLAnchorElement>, +): VNode { const [open, setOpen] = useState<boolean>(false); - function doClick(e: JSXInternal.TargetedMouseEvent<HTMLAnchorElement>) { + function doClick(e: h.JSX.TargetedMouseEvent<HTMLAnchorElement>): void { setOpen(!open); e.preventDefault(); } diff --git a/packages/taler-wallet-webextension/src/components/SelectList.tsx b/packages/taler-wallet-webextension/src/components/SelectList.tsx index f89ba19b2..78dd2feb4 100644 --- a/packages/taler-wallet-webextension/src/components/SelectList.tsx +++ b/packages/taler-wallet-webextension/src/components/SelectList.tsx @@ -14,9 +14,8 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { JSX } from "preact/jsx-runtime"; +import { Fragment, h, VNode } from "preact"; import { NiceSelect } from "./styled/index"; -import { h } from "preact"; interface Props { value?: string; @@ -34,13 +33,12 @@ export function SelectList({ name, value, list, - canBeNull, onChange, label, description, -}: Props): JSX.Element { +}: Props): VNode { return ( - <div> + <Fragment> <label htmlFor={`text-${name}`} style={{ marginLeft: "0.5em", fontWeight: "bold" }} @@ -84,6 +82,6 @@ export function SelectList({ {description} </span> )} - </div> + </Fragment> ); } diff --git a/packages/taler-wallet-webextension/src/components/Time.tsx b/packages/taler-wallet-webextension/src/components/Time.tsx new file mode 100644 index 000000000..452b08334 --- /dev/null +++ b/packages/taler-wallet-webextension/src/components/Time.tsx @@ -0,0 +1,41 @@ +/* + This file is part of TALER + (C) 2016 GNUnet e.V. + + 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. + + 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 + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { Timestamp } from "@gnu-taler/taler-util"; +import { formatISO, format } from "date-fns"; +import { h, VNode } from "preact"; + +export function Time({ + timestamp, + format: formatString, +}: { + timestamp: Timestamp | undefined; + format: string; +}): VNode { + return ( + <time + dateTime={ + !timestamp || timestamp.t_ms === "never" + ? undefined + : formatISO(timestamp.t_ms) + } + > + {!timestamp || timestamp.t_ms === "never" + ? "never" + : format(timestamp.t_ms, formatString)} + </time> + ); +} diff --git a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx index 1917d5627..99ca86385 100644 --- a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx +++ b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx @@ -20,8 +20,7 @@ import { Transaction, TransactionType, } from "@gnu-taler/taler-util"; -import { format, formatDistance } from "date-fns"; -import { h } from "preact"; +import { h, VNode } from "preact"; import imageBank from "../../static/img/ri-bank-line.svg"; import imageHandHeart from "../../static/img/ri-hand-heart-line.svg"; import imageRefresh from "../../static/img/ri-refresh-line.svg"; @@ -36,11 +35,12 @@ import { LargeText, LightText, } from "./styled/index"; +import { Time } from "./Time"; export function TransactionItem(props: { tx: Transaction; multiCurrency: boolean; -}): JSX.Element { +}): VNode { const tx = props.tx; switch (tx.type) { case TransactionType.Withdrawal: @@ -125,10 +125,7 @@ export function TransactionItem(props: { } } -function TransactionLayout(props: TransactionLayoutProps): JSX.Element { - const date = new Date(props.timestamp.t_ms); - const dateStr = format(date, "dd MMM, hh:mm"); - +function TransactionLayout(props: TransactionLayoutProps): VNode { return ( <HistoryRow href={Pages.transaction.replace(":tid", props.id)}> <img src={props.iconPath} /> @@ -146,7 +143,9 @@ function TransactionLayout(props: TransactionLayoutProps): JSX.Element { Waiting for confirmation </LightText> )} - <SmallLightText style={{ marginTop: 5 }}>{dateStr}</SmallLightText> + <SmallLightText style={{ marginTop: 5 }}> + <Time timestamp={props.timestamp} format="dd MMM, hh:mm" /> + </SmallLightText> </Column> <TransactionAmount pending={props.pending} @@ -177,7 +176,7 @@ interface TransactionAmountProps { multiCurrency: boolean; } -function TransactionAmount(props: TransactionAmountProps): JSX.Element { +function TransactionAmount(props: TransactionAmountProps): VNode { const [currency, amount] = props.amount.split(":"); let sign: string; switch (props.debitCreditIndicator) { diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx index 8b36dbd31..2db7c61f8 100644 --- a/packages/taler-wallet-webextension/src/components/styled/index.tsx +++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx @@ -85,7 +85,7 @@ export const WalletBox = styled.div<{ noPadding?: boolean }>` overflow: auto; table td { - padding: 5px 10px; + padding: 5px 5px; } table tr { border-bottom: 1px solid black; @@ -328,7 +328,8 @@ const ButtonVariant = styled(Button)` text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); `; -export const ButtonPrimary = styled(ButtonVariant)` +export const ButtonPrimary = styled(ButtonVariant)<{ small?: boolean }>` + font-size: ${({ small }) => (small ? "small" : "inherit")}; background-color: rgb(66, 184, 221); `; export const ButtonBoxPrimary = styled(ButtonBox)` @@ -501,29 +502,40 @@ export const Input = styled.div<{ invalid?: boolean }>` `; export const InputWithLabel = styled.div<{ invalid?: boolean }>` + /* display: flex; */ + & label { display: block; + font-weight: bold; + margin-left: 0.5em; padding: 5px; color: ${({ invalid }) => (!invalid ? "inherit" : "red")}; } - & > div { - position: relative; - display: flex; - top: 0px; - bottom: 0px; - - & > div { - position: absolute; - background-color: lightgray; - padding: 5px; - margin: 2px; - } - & > input { - flex: 1; - padding: 5px; - border-color: ${({ invalid }) => (!invalid ? "inherit" : "red")}; - } + & div { + line-height: 24px; + display: flex; + } + & div > span { + background-color: lightgray; + box-sizing: border-box; + border-bottom-left-radius: 0.25em; + border-top-left-radius: 0.25em; + height: 2em; + display: inline-block; + padding-left: 0.5em; + padding-right: 0.5em; + align-items: center; + display: flex; + } + & input { + border-width: 1px; + box-sizing: border-box; + height: 2em; + /* border-color: lightgray; */ + border-bottom-right-radius: 0.25em; + border-top-right-radius: 0.25em; + border-color: ${({ invalid }) => (!invalid ? "lightgray" : "red")}; } `; @@ -535,6 +547,7 @@ export const ErrorBox = styled.div` flex-direction: column; /* margin: 0.5em; */ padding: 1em; + margin: 1em; /* width: 100%; */ color: #721c24; background: #f8d7da; @@ -592,6 +605,8 @@ export const PopupNavigation = styled.div<{ devMode?: boolean }>` } `; +const image = `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`; + export const NiceSelect = styled.div` & > select { -webkit-appearance: none; @@ -600,11 +615,18 @@ export const NiceSelect = styled.div` appearance: none; outline: 0; box-shadow: none; - background-image: none; + + background-image: ${image}; + background-position: right 0.5rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + padding-right: 2.5rem; + background-color: white; - flex: 1; - padding: 0.5em 1em; + border-radius: 0.25rem; + font-size: 1em; + padding: 0.5em 3em 0.5em 1em; cursor: pointer; } @@ -613,27 +635,6 @@ export const NiceSelect = styled.div` /* width: 10em; */ overflow: hidden; border-radius: 0.25em; - - &::after { - content: "\u25BC"; - position: absolute; - top: 0; - right: 0; - padding: 0.5em 1em; - cursor: pointer; - pointer-events: none; - -webkit-transition: 0.25s all ease; - -o-transition: 0.25s all ease; - transition: 0.25s all ease; - } - - &:hover::after { - /* color: #f39c12; */ - } - - &::-ms-expand { - display: none; - } `; export const Outlined = styled.div` |