aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src')
-rw-r--r--packages/taler-wallet-webextension/src/components/Banner.stories.tsx10
-rw-r--r--packages/taler-wallet-webextension/src/components/PendingTransactions.tsx10
-rw-r--r--packages/taler-wallet-webextension/src/mui/Alert.stories.tsx86
-rw-r--r--packages/taler-wallet-webextension/src/mui/Alert.tsx160
-rw-r--r--packages/taler-wallet-webextension/src/mui/Button.tsx129
-rw-r--r--packages/taler-wallet-webextension/src/mui/Paper.tsx4
-rw-r--r--packages/taler-wallet-webextension/src/mui/Typography.tsx29
-rw-r--r--packages/taler-wallet-webextension/src/mui/index.stories.tsx3
-rw-r--r--packages/taler-wallet-webextension/src/mui/style.tsx4
-rw-r--r--packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx38
-rw-r--r--packages/taler-wallet-webextension/src/stories.tsx9
-rw-r--r--packages/taler-wallet-webextension/src/svg/close_24px.svg4
-rw-r--r--packages/taler-wallet-webextension/src/svg/delete_24px.svg5
-rw-r--r--packages/taler-wallet-webextension/src/svg/error_outline_outlined_24px.svg3
-rw-r--r--packages/taler-wallet-webextension/src/svg/info_outlined_24px.svg4
-rw-r--r--packages/taler-wallet-webextension/src/svg/report_problem_outlined_24px.svg4
-rw-r--r--packages/taler-wallet-webextension/src/svg/send_24px.svg5
-rw-r--r--packages/taler-wallet-webextension/src/svg/success_outlined_24px.svg4
-rw-r--r--packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx2
19 files changed, 447 insertions, 66 deletions
diff --git a/packages/taler-wallet-webextension/src/components/Banner.stories.tsx b/packages/taler-wallet-webextension/src/components/Banner.stories.tsx
index 4d328a723..f91d94d0f 100644
--- a/packages/taler-wallet-webextension/src/components/Banner.stories.tsx
+++ b/packages/taler-wallet-webextension/src/components/Banner.stories.tsx
@@ -106,9 +106,13 @@ export const PendingOperation = (): VNode => (
</Avatar>
),
description: (
- <Typography>
- <b>EUR 37.95</b> - 5 feb 2022
- </Typography>
+ <Fragment>
+ <Typography inline bold>
+ EUR 37.95
+ </Typography>
+ &nbsp;
+ <Typography inline>- 5 feb 2022</Typography>
+ </Fragment>
),
},
]}
diff --git a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
index 2d8a776cd..f37a212f7 100644
--- a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
+++ b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
@@ -70,16 +70,16 @@ export function PendingTransactionsView({
),
action: () => goToTransaction(t.transactionId),
description: (
- <Typography>
- <b>
+ <Fragment>
+ <Typography inline bold>
{amount.currency} {Amounts.stringifyValue(amount)}
- </b>{" "}
- -{" "}
+ </Typography>
+ &nbsp;-&nbsp;
<Time
timestamp={AbsoluteTime.fromTimestamp(t.timestamp)}
format="dd MMMM yyyy"
/>
- </Typography>
+ </Fragment>
),
};
})}
diff --git a/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx b/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx
new file mode 100644
index 000000000..12b2a8625
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx
@@ -0,0 +1,86 @@
+/*
+ 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 { css } from "@linaria/core";
+import { ComponentChildren, Fragment, h, VNode } from "preact";
+import { Alert } from "./Alert.jsx";
+
+export default {
+ title: "mui/alert",
+ component: Alert,
+};
+
+function Wrapper({ children }: { children: ComponentChildren }): VNode {
+ return (
+ <div
+ class={css`
+ & > * {
+ margin: 2em;
+ }
+ `}
+ >
+ {children}
+ </div>
+ );
+}
+
+export const BasicExample = (): VNode => (
+ <Wrapper>
+ <Alert severity="warning">this is an warning</Alert>
+ <Alert severity="error">this is an error</Alert>
+ <Alert severity="success">this is an success</Alert>
+ <Alert severity="info">this is an info</Alert>
+ </Wrapper>
+);
+
+export const WithTitle = (): VNode => (
+ <Wrapper>
+ <Alert title="Warning" severity="warning">
+ this is an warning
+ </Alert>
+ <Alert title="Error" severity="error">
+ this is an error
+ </Alert>
+ <Alert title="Success" severity="success">
+ this is an success
+ </Alert>
+ <Alert title="Info" severity="info">
+ this is an info
+ </Alert>
+ </Wrapper>
+);
+
+export const WithAction = (): VNode => (
+ <Wrapper>
+ <Alert title="Warning" severity="warning" onClose={() => alert("closed")}>
+ this is an warning
+ </Alert>
+ <Alert title="Error" severity="error" onClose={() => alert("closed")}>
+ this is an error
+ </Alert>
+ <Alert title="Success" severity="success" onClose={() => alert("closed")}>
+ this is an success
+ </Alert>
+ <Alert title="Info" severity="info" onClose={() => alert("closed")}>
+ this is an info
+ </Alert>
+ </Wrapper>
+);
diff --git a/packages/taler-wallet-webextension/src/mui/Alert.tsx b/packages/taler-wallet-webextension/src/mui/Alert.tsx
new file mode 100644
index 000000000..7d0ce55d0
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/mui/Alert.tsx
@@ -0,0 +1,160 @@
+import { css } from "@linaria/core";
+import { ComponentChildren, h, VNode } from "preact";
+// eslint-disable-next-line import/extensions
+import CloseIcon from "../svg/close_24px.svg";
+import ErrorOutlineIcon from "../svg/error_outline_outlined_24px.svg";
+import InfoOutlinedIcon from "../svg/info_outlined_24px.svg";
+import ReportProblemOutlinedIcon from "../svg/report_problem_outlined_24px.svg";
+import SuccessOutlinedIcon from "../svg/success_outlined_24px.svg";
+import { IconButton } from "./Button.js";
+// eslint-disable-next-line import/extensions
+import { darken, lighten } from "./colors/manipulation";
+import { Paper } from "./Paper.js";
+// eslint-disable-next-line import/extensions
+import { theme } from "./style";
+import { Typography } from "./Typography.js";
+
+const defaultIconMapping = {
+ success: SuccessOutlinedIcon,
+ warning: ReportProblemOutlinedIcon,
+ error: ErrorOutlineIcon,
+ info: InfoOutlinedIcon,
+};
+
+const baseStyle = css`
+ background-color: transparent;
+ display: flex;
+ padding: 6px 16px;
+`;
+
+const colorVariant = {
+ standard: css`
+ color: var(--color-light-06);
+ background-color: var(--color-background-light-09);
+ `,
+ outlined: css`
+ color: var(--color-light-06);
+ border-width: 1px;
+ border-style: solid;
+ border-color: var(--color-light);
+ `,
+ filled: css`
+ color: "#fff";
+ font-weight: ${theme.typography.fontWeightMedium};
+ background-color: var(--color-main);
+ `,
+};
+
+interface Props {
+ title?: string;
+ variant?: "filled" | "outlined" | "standard";
+ role?: string;
+ onClose?: () => void;
+ // icon: VNode;
+ severity?: "info" | "warning" | "success" | "error";
+ children: ComponentChildren;
+ icon?: boolean;
+}
+
+const getColor = theme.palette.mode === "light" ? darken : lighten;
+const getBackgroundColor = theme.palette.mode === "light" ? lighten : darken;
+
+function Icon({ svg }: { svg: VNode }): VNode {
+ return (
+ <div
+ class={css`
+ margin-right: 12px;
+ padding: 7px 0px;
+ display: flex;
+ font-size: 22px;
+ opacity: 0.9;
+ fill: currentColor;
+ `}
+ dangerouslySetInnerHTML={{ __html: svg as any }}
+ ></div>
+ );
+}
+
+function Action({ children }: { children: ComponentChildren }): VNode {
+ return (
+ <div
+ class={css`
+ display: flex;
+ align-items: flex-start;
+ padding: 4px 0px 0px 16px;
+ margin-left: auto;
+ margin-right: -8px;
+ `}
+ >
+ {children}
+ </div>
+ );
+}
+
+function Message({
+ title,
+ children,
+}: {
+ title?: string;
+ children: ComponentChildren;
+}): VNode {
+ return (
+ <div
+ class={css`
+ padding: 8px 0px;
+ width: 100%;
+ `}
+ >
+ {title && (
+ <Typography
+ class={css`
+ font-weight: ${theme.typography.fontWeightMedium};
+ `}
+ gutterBottom
+ >
+ {title}
+ </Typography>
+ )}
+ {children}
+ </div>
+ );
+}
+
+export function Alert({
+ variant = "standard",
+ severity = "success",
+ title,
+ children,
+ icon,
+ onClose,
+ ...rest
+}: Props): VNode {
+ return (
+ <Paper
+ class={[
+ theme.typography.body2,
+ baseStyle,
+ severity && colorVariant[variant],
+ ].join(" ")}
+ style={{
+ "--color-light-06": getColor(theme.palette[severity].light, 0.6),
+ "--color-background-light-09": getBackgroundColor(
+ theme.palette[severity].light,
+ 0.9,
+ ),
+ "--color-main": theme.palette[severity].main,
+ "--color-light": theme.palette[severity].light,
+ // ...(style as any),
+ }}
+ elevation={1}
+ >
+ {icon != false ? <Icon svg={defaultIconMapping[severity]} /> : null}
+ <Message title={title}>{children}</Message>
+ {onClose && (
+ <Action>
+ <IconButton svg={CloseIcon} onClick={onClose} />
+ </Action>
+ )}
+ </Paper>
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/mui/Button.tsx b/packages/taler-wallet-webextension/src/mui/Button.tsx
index 083bbea0d..451b1d48d 100644
--- a/packages/taler-wallet-webextension/src/mui/Button.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Button.tsx
@@ -1,26 +1,11 @@
-import { ComponentChildren, h, VNode } from "preact";
+import { ComponentChildren, h, VNode, JSX } from "preact";
import { css } from "@linaria/core";
// eslint-disable-next-line import/extensions
import { theme, ripple, Colors } from "./style";
// eslint-disable-next-line import/extensions
import { alpha } from "./colors/manipulation";
-interface Props {
- children?: ComponentChildren;
- disabled?: boolean;
- disableElevation?: boolean;
- disableFocusRipple?: boolean;
- endIcon?: VNode;
- fullWidth?: boolean;
- href?: string;
- size?: "small" | "medium" | "large";
- startIcon?: VNode | string;
- variant?: "contained" | "outlined" | "text";
- color?: Colors;
- onClick?: () => void;
-}
-
-const baseStyle = css`
+const buttonBaseStyle = css`
display: inline-flex;
align-items: center;
justify-content: center;
@@ -30,7 +15,7 @@ const baseStyle = css`
outline: 0;
border: 0;
margin: 0;
- /* border-radius: 0; */
+ border-radius: 0;
padding: 0;
cursor: pointer;
user-select: none;
@@ -39,6 +24,21 @@ const baseStyle = css`
color: inherit;
`;
+interface Props {
+ children?: ComponentChildren;
+ disabled?: boolean;
+ disableElevation?: boolean;
+ disableFocusRipple?: boolean;
+ endIcon?: string | VNode;
+ fullWidth?: boolean;
+ href?: string;
+ size?: "small" | "medium" | "large";
+ startIcon?: VNode | string;
+ variant?: "contained" | "outlined" | "text";
+ color?: Colors;
+ onClick?: () => void;
+}
+
const button = css`
min-width: 64px;
&:hover {
@@ -54,13 +54,13 @@ const button = css`
`;
const colorIconVariant = {
outlined: css`
- background-color: var(--color-main);
+ fill: var(--color-main);
`,
contained: css`
- background-color: var(--color-contrastText);
+ fill: var(--color-contrastText);
`,
text: css`
- background-color: var(--color-main);
+ fill: var(--color-main);
`,
};
@@ -68,6 +68,7 @@ const colorVariant = {
outlined: css`
color: var(--color-main);
border: 1px solid var(--color-main-alpha-half);
+ background-color: var(--color-contrastText);
&:hover {
border: 1px solid var(--color-main);
background-color: var(--color-main-alpha-opacity);
@@ -81,7 +82,7 @@ const colorVariant = {
background-color: var(--color-main);
box-shadow: ${theme.shadows[2]};
&:hover {
- background-color: var(--color-dark);
+ background-color: var(--color-grey-or-dark);
}
&:active {
box-shadow: ${theme.shadows[8]};
@@ -186,11 +187,16 @@ const sizeVariant = {
},
};
+const fullWidthStyle = css`
+ width: 100%;
+`;
+
export function Button({
children,
disabled,
startIcon: sip,
endIcon: eip,
+ fullWidth,
variant = "text",
size = "medium",
color = "primary",
@@ -198,8 +204,8 @@ export function Button({
}: Props): VNode {
const style = css`
user-select: none;
- width: 1em;
- height: 1em;
+ width: 24px;
+ height: 24px;
display: inline-block;
fill: currentColor;
flex-shrink: 0;
@@ -222,8 +228,9 @@ export function Button({
sizeIconVariant[variant][size],
style,
].join(" ")}
+ //FIXME: check when sip can be a vnode
+ dangerouslySetInnerHTML={{ __html: sip as string }}
style={{
- "--image": `url("${sip}")`,
"--color-main": theme.palette[color].main,
"--color-contrastText": theme.palette[color].contrastText,
}}
@@ -241,8 +248,8 @@ export function Button({
sizeIconVariant[variant][size],
style,
].join(" ")}
+ dangerouslySetInnerHTML={{ __html: eip as string }}
style={{
- "--image": `url("${eip}")`,
"--color-main": theme.palette[color].main,
"--color-contrastText": theme.palette[color].contrastText,
"--color-dark": theme.palette[color].dark,
@@ -250,17 +257,17 @@ export function Button({
/>
);
return (
- <button
+ <ButtonBase
disabled={disabled}
class={[
theme.typography.button,
theme.shape.roundBorder,
- ripple,
- baseStyle,
button,
+ fullWidth && fullWidthStyle,
colorVariant[variant],
sizeVariant[variant][size],
].join(" ")}
+ onClick={onClick}
style={{
"--color-main": theme.palette[color].main,
"--color-contrastText": theme.palette[color].contrastText,
@@ -274,11 +281,75 @@ export function Button({
theme.palette.text.primary,
theme.palette.action.hoverOpacity,
),
+ "--color-grey-or-dark": !color
+ ? theme.palette.grey.A100
+ : theme.palette[color].dark,
}}
>
{startIcon}
{children}
{endIcon}
+ </ButtonBase>
+ );
+}
+
+interface BaseProps extends JSX.HTMLAttributes<HTMLButtonElement> {
+ class: string;
+ onClick?: () => void;
+ children?: ComponentChildren;
+}
+
+function ButtonBase({
+ class: _class,
+ children,
+ onClick,
+ dangerouslySetInnerHTML,
+ ...rest
+}: BaseProps): VNode {
+ function doClick(): void {
+ if (onClick) onClick();
+ }
+ const classNames = [buttonBaseStyle, _class, ripple].join(" ");
+ if (dangerouslySetInnerHTML) {
+ return (
+ <button
+ onClick={doClick}
+ class={classNames}
+ dangerouslySetInnerHTML={dangerouslySetInnerHTML}
+ {...rest}
+ />
+ );
+ }
+ return (
+ <button onClick={doClick} class={classNames} {...rest}>
+ {children}
</button>
);
}
+
+export function IconButton({
+ svg,
+ onClick,
+}: {
+ svg: any;
+ onClick?: () => void;
+}): VNode {
+ return (
+ <ButtonBase
+ onClick={onClick}
+ class={[
+ css`
+ text-align: center;
+ flex: 0 0 auto;
+ font-size: ${theme.typography.pxToRem(24)};
+ padding: 8px;
+ border-radius: 50%;
+ overflow: visible;
+ color: "inherit";
+ fill: currentColor;
+ `,
+ ].join(" ")}
+ dangerouslySetInnerHTML={{ __html: svg }}
+ />
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/mui/Paper.tsx b/packages/taler-wallet-webextension/src/mui/Paper.tsx
index eeb4083d4..7d36c32d1 100644
--- a/packages/taler-wallet-webextension/src/mui/Paper.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Paper.tsx
@@ -34,11 +34,14 @@ export function Paper({
square,
variant = "elevation",
children,
+ class: _class,
+ style,
...rest
}: Props): VNode {
return (
<div
class={[
+ _class,
baseStyle,
!square && theme.shape.roundBorder,
borderVariant[variant],
@@ -49,6 +52,7 @@ export function Paper({
"#fff",
getOverlayAlpha(elevation),
)}, ${alpha("#fff", getOverlayAlpha(elevation))})`,
+ ...(style as any),
}}
{...rest}
>
diff --git a/packages/taler-wallet-webextension/src/mui/Typography.tsx b/packages/taler-wallet-webextension/src/mui/Typography.tsx
index ecd2b8ec3..1610a1c66 100644
--- a/packages/taler-wallet-webextension/src/mui/Typography.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Typography.tsx
@@ -1,5 +1,6 @@
import { css } from "@linaria/core";
import { ComponentChildren, h, VNode } from "preact";
+import { useTranslationContext } from "../context/translation.js";
// eslint-disable-next-line import/extensions
import { theme } from "./style";
@@ -22,10 +23,13 @@ type VariantEnum =
interface Props {
align?: "center" | "inherit" | "justify" | "left" | "right";
gutterBottom?: boolean;
+ bold?: boolean;
+ inline?: boolean;
noWrap?: boolean;
paragraph?: boolean;
variant?: VariantEnum;
- children?: ComponentChildren;
+ children: string[] | string;
+ class?: string;
}
const defaultVariantMapping = {
@@ -57,6 +61,9 @@ const gutterBottomStyle = css`
const paragraphStyle = css`
margin-bottom: 16px;
`;
+const boldStyle = css`
+ font-weight: bold;
+`;
export function Typography({
align,
@@ -64,9 +71,16 @@ export function Typography({
noWrap = false,
paragraph = false,
variant = "body1",
+ bold,
+ inline,
children,
+ class: _class,
}: Props): VNode {
- const cmp = paragraph
+ const { i18n } = useTranslationContext();
+
+ const Component = inline
+ ? "span"
+ : paragraph === true
? "p"
: defaultVariantMapping[variant as "h1"] || "span";
@@ -76,20 +90,21 @@ export function Typography({
: {
textAlign: align,
};
+
return h(
- cmp,
+ Component,
{
class: [
+ _class,
root,
noWrap && noWrapStyle,
gutterBottom && gutterBottomStyle,
paragraph && paragraphStyle,
+ bold && boldStyle,
theme.typography[variant as "button"], //FIXME: implement the rest of the typography and remove the casting
].join(" "),
- style: {
- ...alignStyle,
- },
+ style: alignStyle,
},
- children,
+ <i18n.Translate>{children}</i18n.Translate>,
);
}
diff --git a/packages/taler-wallet-webextension/src/mui/index.stories.tsx b/packages/taler-wallet-webextension/src/mui/index.stories.tsx
index 302114ed5..41b3a7bd9 100644
--- a/packages/taler-wallet-webextension/src/mui/index.stories.tsx
+++ b/packages/taler-wallet-webextension/src/mui/index.stories.tsx
@@ -23,5 +23,6 @@ import * as a1 from "./Button.stories.js";
import * as a3 from "./Grid.stories.js";
import * as a4 from "./Paper.stories.js";
import * as a5 from "./TextField.stories.js";
+import * as a6 from "./Alert.stories.js";
-export default [a1, a3, a4, a5];
+export default [a1, a3, a4, a5, a6];
diff --git a/packages/taler-wallet-webextension/src/mui/style.tsx b/packages/taler-wallet-webextension/src/mui/style.tsx
index 5be978794..652a71d46 100644
--- a/packages/taler-wallet-webextension/src/mui/style.tsx
+++ b/packages/taler-wallet-webextension/src/mui/style.tsx
@@ -48,11 +48,11 @@ export const ripple = css`
transition: background 0.5s;
&:hover {
- background: #47a7f5 radial-gradient(circle, transparent 1%, #47a7f5 1%)
+ background: #eeeeee radial-gradient(circle, transparent 1%, #eeeeee 1%)
center/15000%;
}
&:active {
- background-color: #6eb9f7;
+ background-color: currentColor;
background-size: 100%;
transition: background 0s;
}
diff --git a/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx b/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx
index 3ec7b314c..ddce93cd8 100644
--- a/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx
+++ b/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx
@@ -1,24 +1,32 @@
-import { h, VNode } from "preact";
-import { ButtonBoxWarning, WarningBox } from "../components/styled/index.js";
-import { useTranslationContext } from "../context/translation.js";
+import { css } from "@linaria/core";
+import { Fragment, h, VNode } from "preact";
+import { Alert } from "../mui/Alert.js";
+import { Button } from "../mui/Button.js";
+import { Paper } from "../mui/Paper.js";
+import { Typography } from "../mui/Typography.js";
export function NoBalanceHelp({
goToWalletManualWithdraw,
}: {
goToWalletManualWithdraw: () => void;
}): VNode {
- const { i18n } = useTranslationContext();
return (
- <WarningBox>
- <p>
- <b>
- <i18n.Translate>You have no balance.</i18n.Translate>
- </b>{" "}
- <i18n.Translate>Withdraw some funds into your wallet.</i18n.Translate>
- </p>
- <ButtonBoxWarning onClick={() => goToWalletManualWithdraw()}>
- <i18n.Translate>Withdraw</i18n.Translate>
- </ButtonBoxWarning>
- </WarningBox>
+ <Paper
+ class={css`
+ margin: 1em;
+ `}
+ >
+ <Alert title="You have no balance." severity="warning">
+ <Typography>Withdraw some funds into your wallet.</Typography>
+ <Button
+ fullWidth
+ color="warning"
+ variant="outlined"
+ onClick={goToWalletManualWithdraw}
+ >
+ <Typography>Withdraw</Typography>
+ </Button>
+ </Alert>
+ </Paper>
);
}
diff --git a/packages/taler-wallet-webextension/src/stories.tsx b/packages/taler-wallet-webextension/src/stories.tsx
index 3dcaa7fb9..b7e9b4184 100644
--- a/packages/taler-wallet-webextension/src/stories.tsx
+++ b/packages/taler-wallet-webextension/src/stories.tsx
@@ -286,12 +286,19 @@ function Application(): VNode {
initialSelection,
);
- function updateSelectedFromHashChange({ newURL, oldURL }: any): void {
+ function updateSelectedFromHashChange(): void {
const selected = getSelectionFromLocationHash();
updateSelected(selected);
}
useEffect(() => {
window.addEventListener("hashchange", updateSelectedFromHashChange);
+ if (location.hash) {
+ const hash = location.hash.substring(1);
+ const found = document.getElementById(hash);
+ if (found) {
+ found.scrollIntoView();
+ }
+ }
return () => {
window.removeEventListener("hashchange", updateSelectedFromHashChange);
};
diff --git a/packages/taler-wallet-webextension/src/svg/close_24px.svg b/packages/taler-wallet-webextension/src/svg/close_24px.svg
new file mode 100644
index 000000000..8b7eb6e84
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/svg/close_24px.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
+ <path d="M0 0h24v24H0z" fill="none" />
+ <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/svg/delete_24px.svg b/packages/taler-wallet-webextension/src/svg/delete_24px.svg
index 0d0b74d16..ead7caa9f 100644
--- a/packages/taler-wallet-webextension/src/svg/delete_24px.svg
+++ b/packages/taler-wallet-webextension/src/svg/delete_24px.svg
@@ -1 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <path d="M0 0h24v24H0z" fill="none" />
+ <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/svg/error_outline_outlined_24px.svg b/packages/taler-wallet-webextension/src/svg/error_outline_outlined_24px.svg
new file mode 100644
index 000000000..4a0daa1e9
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/svg/error_outline_outlined_24px.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
+ <path d="M11 15h2v2h-2v-2zm0-8h2v6h-2V7zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/svg/info_outlined_24px.svg b/packages/taler-wallet-webextension/src/svg/info_outlined_24px.svg
new file mode 100644
index 000000000..80dad95cc
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/svg/info_outlined_24px.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
+ <path d="M0 0h24v24H0V0z" fill="none" />
+ <path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/svg/report_problem_outlined_24px.svg b/packages/taler-wallet-webextension/src/svg/report_problem_outlined_24px.svg
new file mode 100644
index 000000000..ed32f6f28
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/svg/report_problem_outlined_24px.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
+ <path d="M0 0h24v24H0V0z" fill="none" />
+ <path d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/svg/send_24px.svg b/packages/taler-wallet-webextension/src/svg/send_24px.svg
index 95fe7a4c6..6e41d1c9e 100644
--- a/packages/taler-wallet-webextension/src/svg/send_24px.svg
+++ b/packages/taler-wallet-webextension/src/svg/send_24px.svg
@@ -1 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <path d="M0 0h24v24H0z" fill="none" />
+ <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/svg/success_outlined_24px.svg b/packages/taler-wallet-webextension/src/svg/success_outlined_24px.svg
new file mode 100644
index 000000000..c6130b495
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/svg/success_outlined_24px.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
+ <path d="M0 0h24v24H0V0z" fill="none" />
+ <path d="M20,12A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4C12.76,4 13.5,4.11 14.2, 4.31L15.77,2.74C14.61,2.26 13.34,2 12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0, 0 22,12M7.91,10.08L6.5,11.5L11,16L21,6L19.59,4.58L11,13.17L7.91,10.08Z" />
+</svg> \ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
index 9d7a692a2..215aa4378 100644
--- a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
@@ -166,7 +166,7 @@ export function CreateManualWithdraw({
);
if (state.noExchangeFound) {
- if (initialCurrency !== undefined) {
+ if (initialCurrency) {
return (
<section>
<SubTitle>