aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-11-08 16:51:23 +0100
committerFlorian Dold <florian@dold.me>2021-11-08 16:51:23 +0100
commit6a0c5263bba435b3ab3a8cda335ceadf7cdd4664 (patch)
treed043fb1ceef7cbba9f28151a9117460f25706ab4
parent16662b194d214fad6ccc244261ed1c02e197a390 (diff)
anastasis-webui: ui tweaks
-rw-r--r--packages/anastasis-core/src/index.ts41
-rw-r--r--packages/anastasis-webui/src/components/menu/NavigationBar.tsx78
-rw-r--r--packages/anastasis-webui/src/components/menu/SideBar.tsx4
-rw-r--r--packages/anastasis-webui/src/components/menu/index.tsx132
-rw-r--r--packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx30
5 files changed, 194 insertions, 91 deletions
diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts
index 3be0d7b76..f88e6e8bc 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -109,13 +109,23 @@ export * from "./challenge-feedback-types.js";
const logger = new Logger("anastasis-core:index.ts");
-function getContinents(): ContinentInfo[] {
+function getContinents(
+ opts: { requireProvider?: boolean } = {},
+): ContinentInfo[] {
+ const currenciesWithProvider = new Set<string>();
+ anastasisData.providersList.anastasis_provider.forEach((x) => {
+ currenciesWithProvider.add(x.currency);
+ });
const continentSet = new Set<string>();
const continents: ContinentInfo[] = [];
for (const country of anastasisData.countriesList.countries) {
if (continentSet.has(country.continent)) {
continue;
}
+ if (opts.requireProvider && !currenciesWithProvider.has(country.currency)) {
+ // Country's currency doesn't have any providers => skip
+ continue;
+ }
continentSet.add(country.continent);
continents.push({
...{ name_i18n: country.continent_i18n },
@@ -148,9 +158,18 @@ export class ReducerError extends Error {
* Get countries for a continent, abort with ReducerError
* exception when continent doesn't exist.
*/
-function getCountries(continent: string): CountryInfo[] {
+function getCountries(
+ continent: string,
+ opts: { requireProvider?: boolean } = {},
+): CountryInfo[] {
+ const currenciesWithProvider = new Set<string>();
+ anastasisData.providersList.anastasis_provider.forEach((x) => {
+ currenciesWithProvider.add(x.currency);
+ });
const countries = anastasisData.countriesList.countries.filter(
- (x) => x.continent === continent,
+ (x) =>
+ x.continent === continent &&
+ (!opts.requireProvider || currenciesWithProvider.has(x.currency)),
);
if (countries.length <= 0) {
throw new ReducerError({
@@ -164,14 +183,18 @@ function getCountries(continent: string): CountryInfo[] {
export async function getBackupStartState(): Promise<ReducerStateBackup> {
return {
backup_state: BackupStates.ContinentSelecting,
- continents: getContinents(),
+ continents: getContinents({
+ requireProvider: true,
+ }),
};
}
export async function getRecoveryStartState(): Promise<ReducerStateRecovery> {
return {
recovery_state: RecoveryStates.ContinentSelecting,
- continents: getContinents(),
+ continents: getContinents({
+ requireProvider: true,
+ }),
};
}
@@ -1073,7 +1096,9 @@ async function backupSelectContinent(
state: ReducerStateBackup,
args: ActionArgsSelectContinent,
): Promise<ReducerStateBackup | ReducerStateError> {
- const countries = getCountries(args.continent);
+ const countries = getCountries(args.continent, {
+ requireProvider: true,
+ });
if (countries.length <= 0) {
return {
code: TalerErrorCode.ANASTASIS_REDUCER_INPUT_INVALID,
@@ -1092,7 +1117,9 @@ async function recoverySelectContinent(
state: ReducerStateRecovery,
args: ActionArgsSelectContinent,
): Promise<ReducerStateRecovery | ReducerStateError> {
- const countries = getCountries(args.continent);
+ const countries = getCountries(args.continent, {
+ requireProvider: true,
+ });
return {
...state,
recovery_state: RecoveryStates.CountrySelecting,
diff --git a/packages/anastasis-webui/src/components/menu/NavigationBar.tsx b/packages/anastasis-webui/src/components/menu/NavigationBar.tsx
index c07f04ab6..02004c105 100644
--- a/packages/anastasis-webui/src/components/menu/NavigationBar.tsx
+++ b/packages/anastasis-webui/src/components/menu/NavigationBar.tsx
@@ -15,13 +15,13 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
-import { h, VNode } from 'preact';
-import logo from '../../assets/logo.jpeg';
-import { LangSelector } from './LangSelector';
+import { h, VNode } from "preact";
+import logo from "../../assets/logo.jpeg";
+import { LangSelector } from "./LangSelector";
interface Props {
onMobileMenu: () => void;
@@ -29,27 +29,51 @@ interface Props {
}
export function NavigationBar({ onMobileMenu, title }: Props): VNode {
- return (<nav class="navbar is-fixed-top" role="navigation" aria-label="main navigation">
- <div class="navbar-brand">
- <span class="navbar-item" style={{ fontSize: 24, fontWeight: 900 }}>{title}</span>
-
- <a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" onClick={(e) => {
- onMobileMenu()
- e.stopPropagation()
- }}>
- <span aria-hidden="true" />
- <span aria-hidden="true" />
- <span aria-hidden="true" />
- </a>
- </div>
-
- <div class="navbar-menu ">
- <div class="navbar-end">
- <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}>
- {/* <LangSelector /> */}
+ return (
+ <nav
+ class="navbar is-fixed-top"
+ role="navigation"
+ aria-label="main navigation"
+ >
+ <div class="navbar-brand">
+ <span class="navbar-item" style={{ fontSize: 24, fontWeight: 900 }}>
+ {title}
+ </span>
+ <a
+ href="mailto:contact@anastasis.lu"
+ style={{ alignSelf: "center", padding: "0.5em" }}
+ >
+ Contact us
+ </a>
+ <a
+ href="https://bugs.anastasis.li/"
+ style={{ alignSelf: "center", padding: "0.5em" }}
+ >
+ Report a bug
+ </a>
+ <a
+ role="button"
+ class="navbar-burger"
+ aria-label="menu"
+ aria-expanded="false"
+ onClick={(e) => {
+ onMobileMenu();
+ e.stopPropagation();
+ }}
+ >
+ <span aria-hidden="true" />
+ <span aria-hidden="true" />
+ <span aria-hidden="true" />
+ </a>
+ </div>
+
+ <div class="navbar-menu ">
+ <div class="navbar-end">
+ <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}>
+ {/* <LangSelector /> */}
+ </div>
</div>
</div>
- </div>
- </nav>
+ </nav>
);
-} \ No newline at end of file
+}
diff --git a/packages/anastasis-webui/src/components/menu/SideBar.tsx b/packages/anastasis-webui/src/components/menu/SideBar.tsx
index 72655662f..a40f4be09 100644
--- a/packages/anastasis-webui/src/components/menu/SideBar.tsx
+++ b/packages/anastasis-webui/src/components/menu/SideBar.tsx
@@ -44,9 +44,9 @@ export function Sidebar({ mobile }: Props): VNode {
</div>} */}
<div class="aside-tools">
<div class="aside-tools-label">
- <div><b>Anastasis</b> Reducer</div>
+ <div><b>Anastasis</b></div>
<div class="is-size-7 has-text-right" style={{ lineHeight: 0, marginTop: -10 }}>
- {process.env.__VERSION__} ({config.version})
+ Version {process.env.__VERSION__} ({config.version})
</div>
</div>
</div>
diff --git a/packages/anastasis-webui/src/components/menu/index.tsx b/packages/anastasis-webui/src/components/menu/index.tsx
index febcd79c8..89add9603 100644
--- a/packages/anastasis-webui/src/components/menu/index.tsx
+++ b/packages/anastasis-webui/src/components/menu/index.tsx
@@ -15,41 +15,53 @@
*/
import { ComponentChildren, Fragment, h, VNode } from "preact";
-import Match from 'preact-router/match';
+import Match from "preact-router/match";
import { useEffect, useState } from "preact/hooks";
import { NavigationBar } from "./NavigationBar";
import { Sidebar } from "./SideBar";
-
-
-
interface MenuProps {
title: string;
}
-function WithTitle({ title, children }: { title: string; children: ComponentChildren }): VNode {
+function WithTitle({
+ title,
+ children,
+}: {
+ title: string;
+ children: ComponentChildren;
+}): VNode {
useEffect(() => {
- document.title = `Taler Backoffice: ${title}`
- }, [title])
- return <Fragment>{children}</Fragment>
+ document.title = `${title}`;
+ }, [title]);
+ return <Fragment>{children}</Fragment>;
}
export function Menu({ title }: MenuProps): VNode {
- const [mobileOpen, setMobileOpen] = useState(false)
-
- return <Match>{({ path }: { path: string }) => {
- const titleWithSubtitle = title // title ? title : (!admin ? getInstanceTitle(path, instance) : getAdminTitle(path, instance))
- return (<WithTitle title={titleWithSubtitle}>
- <div class={mobileOpen ? "has-aside-mobile-expanded" : ""} onClick={() => setMobileOpen(false)}>
- <NavigationBar onMobileMenu={() => setMobileOpen(!mobileOpen)} title={titleWithSubtitle} />
-
- <Sidebar mobile={mobileOpen} />
-
- </div>
- </WithTitle>
- )
- }}</Match>
-
+ const [mobileOpen, setMobileOpen] = useState(false);
+
+ return (
+ <Match>
+ {({ path }: { path: string }) => {
+ const titleWithSubtitle = title; // title ? title : (!admin ? getInstanceTitle(path, instance) : getAdminTitle(path, instance))
+ return (
+ <WithTitle title={titleWithSubtitle}>
+ <div
+ class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+ onClick={() => setMobileOpen(false)}
+ >
+ <NavigationBar
+ onMobileMenu={() => setMobileOpen(!mobileOpen)}
+ title={titleWithSubtitle}
+ />
+
+ <Sidebar mobile={mobileOpen} />
+ </div>
+ </WithTitle>
+ );
+ }}
+ </Match>
+ );
}
interface NotYetReadyAppMenuProps {
@@ -60,37 +72,56 @@ interface NotYetReadyAppMenuProps {
interface NotifProps {
notification?: Notification;
}
-export function NotificationCard({ notification: n }: NotifProps): VNode | null {
- if (!n) return null
- return <div class="notification">
- <div class="columns is-vcentered">
- <div class="column is-12">
- <article class={n.type === 'ERROR' ? "message is-danger" : (n.type === 'WARN' ? "message is-warning" : "message is-info")}>
- <div class="message-header">
- <p>{n.message}</p>
- </div>
- {n.description &&
- <div class="message-body">
- {n.description}
- </div>}
- </article>
+export function NotificationCard({
+ notification: n,
+}: NotifProps): VNode | null {
+ if (!n) return null;
+ return (
+ <div class="notification">
+ <div class="columns is-vcentered">
+ <div class="column is-12">
+ <article
+ class={
+ n.type === "ERROR"
+ ? "message is-danger"
+ : n.type === "WARN"
+ ? "message is-warning"
+ : "message is-info"
+ }
+ >
+ <div class="message-header">
+ <p>{n.message}</p>
+ </div>
+ {n.description && <div class="message-body">{n.description}</div>}
+ </article>
+ </div>
</div>
</div>
- </div>
+ );
}
-export function NotYetReadyAppMenu({ onLogout, title }: NotYetReadyAppMenuProps): VNode {
- const [mobileOpen, setMobileOpen] = useState(false)
+export function NotYetReadyAppMenu({
+ onLogout,
+ title,
+}: NotYetReadyAppMenuProps): VNode {
+ const [mobileOpen, setMobileOpen] = useState(false);
useEffect(() => {
- document.title = `Taler Backoffice: ${title}`
- }, [title])
-
- return <div class={mobileOpen ? "has-aside-mobile-expanded" : ""} onClick={() => setMobileOpen(false)}>
- <NavigationBar onMobileMenu={() => setMobileOpen(!mobileOpen)} title={title} />
- {onLogout && <Sidebar mobile={mobileOpen} />}
- </div>
-
+ document.title = `Taler Backoffice: ${title}`;
+ }, [title]);
+
+ return (
+ <div
+ class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+ onClick={() => setMobileOpen(false)}
+ >
+ <NavigationBar
+ onMobileMenu={() => setMobileOpen(!mobileOpen)}
+ title={title}
+ />
+ {onLogout && <Sidebar mobile={mobileOpen} />}
+ </div>
+ );
}
export interface Notification {
@@ -99,6 +130,5 @@ export interface Notification {
type: MessageType;
}
-export type ValueOrFunction<T> = T | ((p: T) => T)
-export type MessageType = 'INFO' | 'WARN' | 'ERROR' | 'SUCCESS'
-
+export type ValueOrFunction<T> = T | ((p: T) => T);
+export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS";
diff --git a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
index 464950b60..f7731ba00 100644
--- a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
@@ -123,13 +123,35 @@ export function ContinentSelectionScreen(): VNode {
</div>
<div class="column is-two-third">
<p>
- Your location will help us to determine which personal information
- to ask you for the next step.
+ Your choice will help us with asking the right information to unique
+ identify you when you want to recover your backed up secrets.
</p>
<p>
- You should choose the country that issued most of your long-term
- legal documents or personal identifiers.
+ Choose the country that issued most of your long-term legal
+ documents or personal identifiers.
</p>
+ <div
+ style={{
+ border: "1px solid gray",
+ borderRadius: "0.5em",
+ backgroundColor: "#fbfcbd",
+ padding: "0.5em",
+ }}
+ >
+ <p>
+ If you just want to try out Anastasis, we recomment that you
+ choose <b>Testcontinent</b> with <b>Demoland</b>. For this special
+ country, you will be asked for a simple number and not real,
+ personal identifiable information.
+ </p>
+ {/*
+ <p>
+ Because of the diversity of personally identifying information in
+ different countries and cultures, we do not support all countries
+ yet. If you want to improve the supported countries,{" "}
+ <a href="mailto:contact@anastasis.lu">contact us</a>.
+ </p> */}
+ </div>
</div>
</div>
</AnastasisClientFrame>