diff options
-rw-r--r-- | packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx | 91 | ||||
-rw-r--r-- | packages/anastasis-webui/src/pages/home/index.tsx | 99 |
2 files changed, 119 insertions, 71 deletions
diff --git a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx index 0e43f982d..464950b60 100644 --- a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx @@ -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; - return ( - <AnastasisClientFrame hideNext={errors} title={withProcessLabel(reducer, "Where do you live?")} onNext={selectCountryAction}> + 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(); + }; - <div class="columns" > + return ( + <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> ); } diff --git a/packages/anastasis-webui/src/pages/home/index.tsx b/packages/anastasis-webui/src/pages/home/index.tsx index cd8d6c842..74320b6b5 100644 --- a/packages/anastasis-webui/src/pages/home/index.tsx +++ b/packages/anastasis-webui/src/pages/home/index.tsx @@ -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, + }, + ]} + /> ); } |