anastasis-webui: hotfix behavior of back button on country selection screen
This commit is contained in:
parent
8da58bd494
commit
16662b194d
@ -1,58 +1,81 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { BackupStates, RecoveryStates } from "anastasis-core";
|
||||
import { h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
import { AnastasisClientFrame, withProcessLabel } from "./index";
|
||||
|
||||
export function ContinentSelectionScreen(): VNode {
|
||||
const reducer = useAnastasisContext()
|
||||
const reducer = useAnastasisContext();
|
||||
|
||||
//FIXME: remove this when #7056 is fixed
|
||||
const countryFromReducer = (reducer?.currentReducerState as any).selected_country || ""
|
||||
const [countryCode, setCountryCode] = useState( countryFromReducer )
|
||||
// FIXME: remove this when #7056 is fixed
|
||||
const countryFromReducer =
|
||||
(reducer?.currentReducerState as any).selected_country || "";
|
||||
const [countryCode, setCountryCode] = useState(countryFromReducer);
|
||||
|
||||
if (!reducer || !reducer.currentReducerState || !("continents" in reducer.currentReducerState)) {
|
||||
return <div />
|
||||
if (
|
||||
!reducer ||
|
||||
!reducer.currentReducerState ||
|
||||
!("continents" in reducer.currentReducerState)
|
||||
) {
|
||||
return <div />;
|
||||
}
|
||||
const selectContinent = (continent: string): void => {
|
||||
reducer.transition("select_continent", { continent })
|
||||
reducer.transition("select_continent", { continent });
|
||||
};
|
||||
const selectCountry = (country: string): void => {
|
||||
setCountryCode(country)
|
||||
setCountryCode(country);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const continentList = reducer.currentReducerState.continents || [];
|
||||
const countryList = reducer.currentReducerState.countries || [];
|
||||
const theContinent = reducer.currentReducerState.selected_continent || ""
|
||||
const theContinent = reducer.currentReducerState.selected_continent || "";
|
||||
// const cc = reducer.currentReducerState.selected_country || "";
|
||||
const theCountry = countryList.find(c => c.code === countryCode)
|
||||
const theCountry = countryList.find((c) => c.code === countryCode);
|
||||
const selectCountryAction = () => {
|
||||
//selection should be when the select box changes it value
|
||||
if (!theCountry) return;
|
||||
reducer.transition("select_country", {
|
||||
country_code: countryCode,
|
||||
currencies: [theCountry.currency],
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// const step1 = reducer.currentReducerState.backup_state === BackupStates.ContinentSelecting ||
|
||||
// reducer.currentReducerState.recovery_state === RecoveryStates.ContinentSelecting;
|
||||
|
||||
const errors = !theCountry ? "Select a country" : undefined
|
||||
const errors = !theCountry ? "Select a country" : undefined;
|
||||
|
||||
const handleBack = async () => {
|
||||
// We want to go to the start, even if we already selected
|
||||
// a country.
|
||||
// FIXME: What if we don't want to lose all information here?
|
||||
// Can we do some kind of soft reset?
|
||||
reducer.reset();
|
||||
};
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame hideNext={errors} title={withProcessLabel(reducer, "Where do you live?")} onNext={selectCountryAction}>
|
||||
|
||||
<div class="columns" >
|
||||
<AnastasisClientFrame
|
||||
hideNext={errors}
|
||||
title={withProcessLabel(reducer, "Where do you live?")}
|
||||
onNext={selectCountryAction}
|
||||
onBack={handleBack}
|
||||
>
|
||||
<div class="columns">
|
||||
<div class="column is-one-third">
|
||||
<div class="field">
|
||||
<label class="label">Continent</label>
|
||||
<div class="control is-expanded has-icons-left">
|
||||
<div class="select is-fullwidth" >
|
||||
<select onChange={(e) => selectContinent(e.currentTarget.value)} value={theContinent} >
|
||||
<option key="none" disabled selected value=""> Choose a continent </option>
|
||||
{continentList.map(prov => (
|
||||
<div class="select is-fullwidth">
|
||||
<select
|
||||
onChange={(e) => selectContinent(e.currentTarget.value)}
|
||||
value={theContinent}
|
||||
>
|
||||
<option key="none" disabled selected value="">
|
||||
{" "}
|
||||
Choose a continent{" "}
|
||||
</option>
|
||||
{continentList.map((prov) => (
|
||||
<option key={prov.name} value={prov.name}>
|
||||
{prov.name}
|
||||
</option>
|
||||
@ -68,10 +91,17 @@ export function ContinentSelectionScreen(): VNode {
|
||||
<div class="field">
|
||||
<label class="label">Country</label>
|
||||
<div class="control is-expanded has-icons-left">
|
||||
<div class="select is-fullwidth" >
|
||||
<select onChange={(e) => selectCountry((e.target as any).value)} disabled={!theContinent} value={theCountry?.code || ""}>
|
||||
<option key="none" disabled selected value=""> Choose a country </option>
|
||||
{countryList.map(prov => (
|
||||
<div class="select is-fullwidth">
|
||||
<select
|
||||
onChange={(e) => selectCountry((e.target as any).value)}
|
||||
disabled={!theContinent}
|
||||
value={theCountry?.code || ""}
|
||||
>
|
||||
<option key="none" disabled selected value="">
|
||||
{" "}
|
||||
Choose a country{" "}
|
||||
</option>
|
||||
{countryList.map((prov) => (
|
||||
<option key={prov.name} value={prov.code}>
|
||||
{prov.name}
|
||||
</option>
|
||||
@ -93,12 +123,15 @@ export function ContinentSelectionScreen(): VNode {
|
||||
</div>
|
||||
<div class="column is-two-third">
|
||||
<p>
|
||||
Your location will help us to determine which personal information
|
||||
ask you for the next step.
|
||||
Your location will help us to determine which personal information
|
||||
to ask you for the next step.
|
||||
</p>
|
||||
<p>
|
||||
You should choose the country that issued most of your long-term
|
||||
legal documents or personal identifiers.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { BackupStates, RecoveryStates } from "anastasis-core";
|
||||
import {
|
||||
BackupStates,
|
||||
RecoveryStates
|
||||
} from "anastasis-core";
|
||||
import {
|
||||
ComponentChildren, Fragment,
|
||||
ComponentChildren,
|
||||
Fragment,
|
||||
FunctionalComponent,
|
||||
h,
|
||||
VNode
|
||||
VNode,
|
||||
} from "preact";
|
||||
import {
|
||||
useErrorBoundary
|
||||
} from "preact/hooks";
|
||||
import { useErrorBoundary } from "preact/hooks";
|
||||
import { AsyncButton } from "../../components/AsyncButton";
|
||||
import { Menu } from "../../components/menu";
|
||||
import { Notifications } from "../../components/Notifications";
|
||||
import { AnastasisProvider, useAnastasisContext } from "../../context/anastasis";
|
||||
import {
|
||||
AnastasisProvider,
|
||||
useAnastasisContext,
|
||||
} from "../../context/anastasis";
|
||||
import {
|
||||
AnastasisReducerApi,
|
||||
useAnastasisReducer
|
||||
useAnastasisReducer,
|
||||
} from "../../hooks/use-anastasis-reducer";
|
||||
import { AttributeEntryScreen } from "./AttributeEntryScreen";
|
||||
import { AuthenticationEditorScreen } from "./AuthenticationEditorScreen";
|
||||
@ -50,6 +49,10 @@ export function withProcessLabel(
|
||||
|
||||
interface AnastasisClientFrameProps {
|
||||
onNext?(): void;
|
||||
/**
|
||||
* Override for the "back" functionality.
|
||||
*/
|
||||
onBack?(): Promise<void>;
|
||||
title: string;
|
||||
children: ComponentChildren;
|
||||
/**
|
||||
@ -116,9 +119,27 @@ export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode {
|
||||
<section class="section is-main-section">
|
||||
{props.children}
|
||||
{!props.hideNav ? (
|
||||
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button class="button" onClick={() => reducer.back()}>Back</button>
|
||||
<AsyncButton class="button is-info" data-tooltip={props.hideNext} onClick={next} disabled={props.hideNext !== undefined}>Next</AsyncButton>
|
||||
<div
|
||||
style={{
|
||||
marginTop: "2em",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<button
|
||||
class="button"
|
||||
onClick={() => (props.onBack ?? reducer.back)()}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<AsyncButton
|
||||
class="button is-info"
|
||||
data-tooltip={props.hideNext}
|
||||
onClick={next}
|
||||
disabled={props.hideNext !== undefined}
|
||||
>
|
||||
Next
|
||||
</AsyncButton>
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
@ -139,7 +160,7 @@ const AnastasisClient: FunctionalComponent = () => {
|
||||
};
|
||||
|
||||
function AnastasisClientImpl(): VNode {
|
||||
const reducer = useAnastasisContext()
|
||||
const reducer = useAnastasisContext();
|
||||
if (!reducer) {
|
||||
return <p>Fatal: Reducer must be in context.</p>;
|
||||
}
|
||||
@ -155,27 +176,19 @@ function AnastasisClientImpl(): VNode {
|
||||
state.backup_state === BackupStates.CountrySelecting ||
|
||||
state.recovery_state === RecoveryStates.CountrySelecting
|
||||
) {
|
||||
return (
|
||||
<ContinentSelectionScreen />
|
||||
);
|
||||
return <ContinentSelectionScreen />;
|
||||
}
|
||||
if (
|
||||
state.backup_state === BackupStates.UserAttributesCollecting ||
|
||||
state.recovery_state === RecoveryStates.UserAttributesCollecting
|
||||
) {
|
||||
return (
|
||||
<AttributeEntryScreen />
|
||||
);
|
||||
return <AttributeEntryScreen />;
|
||||
}
|
||||
if (state.backup_state === BackupStates.AuthenticationsEditing) {
|
||||
return (
|
||||
<AuthenticationEditorScreen />
|
||||
);
|
||||
return <AuthenticationEditorScreen />;
|
||||
}
|
||||
if (state.backup_state === BackupStates.PoliciesReviewing) {
|
||||
return (
|
||||
<ReviewPoliciesScreen />
|
||||
);
|
||||
return <ReviewPoliciesScreen />;
|
||||
}
|
||||
if (state.backup_state === BackupStates.SecretEditing) {
|
||||
return <SecretEditorScreen />;
|
||||
@ -194,15 +207,11 @@ function AnastasisClientImpl(): VNode {
|
||||
}
|
||||
|
||||
if (state.recovery_state === RecoveryStates.SecretSelecting) {
|
||||
return (
|
||||
<SecretSelectionScreen />
|
||||
);
|
||||
return <SecretSelectionScreen />;
|
||||
}
|
||||
|
||||
if (state.recovery_state === RecoveryStates.ChallengeSelecting) {
|
||||
return (
|
||||
<ChallengeOverviewScreen />
|
||||
);
|
||||
return <ChallengeOverviewScreen />;
|
||||
}
|
||||
|
||||
if (state.recovery_state === RecoveryStates.ChallengeSolving) {
|
||||
@ -210,9 +219,7 @@ function AnastasisClientImpl(): VNode {
|
||||
}
|
||||
|
||||
if (state.recovery_state === RecoveryStates.RecoveryFinished) {
|
||||
return (
|
||||
<RecoveryFinishedScreen />
|
||||
);
|
||||
return <RecoveryFinishedScreen />;
|
||||
}
|
||||
if (state.recovery_state === RecoveryStates.ChallengePaying) {
|
||||
return <ChallengePayingScreen />;
|
||||
@ -222,7 +229,9 @@ function AnastasisClientImpl(): VNode {
|
||||
<AnastasisClientFrame hideNav title="Bug">
|
||||
<p>Bug: Unknown state.</p>
|
||||
<div class="buttons is-right">
|
||||
<button class="button" onClick={() => reducer.reset()}>Reset</button>
|
||||
<button class="button" onClick={() => reducer.reset()}>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
@ -234,11 +243,17 @@ function AnastasisClientImpl(): VNode {
|
||||
function ErrorBanner(): VNode | null {
|
||||
const reducer = useAnastasisContext();
|
||||
if (!reducer || !reducer.currentError) return null;
|
||||
return (<Notifications removeNotification={reducer.dismissError} notifications={[{
|
||||
type: "ERROR",
|
||||
message: `Error code: ${reducer.currentError.code}`,
|
||||
description: reducer.currentError.hint
|
||||
}]} />
|
||||
return (
|
||||
<Notifications
|
||||
removeNotification={reducer.dismissError}
|
||||
notifications={[
|
||||
{
|
||||
type: "ERROR",
|
||||
message: `Error code: ${reducer.currentError.code}`,
|
||||
description: reducer.currentError.hint,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user