From 5883d42d800c7b444c59d626bcaa5abca7dc83d0 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 19 Oct 2021 10:56:52 -0300 Subject: add template from merchant backoffice --- packages/anastasis-webui/src/pages/home/index.tsx | 248 ++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 packages/anastasis-webui/src/pages/home/index.tsx (limited to 'packages/anastasis-webui/src/pages/home/index.tsx') diff --git a/packages/anastasis-webui/src/pages/home/index.tsx b/packages/anastasis-webui/src/pages/home/index.tsx new file mode 100644 index 000000000..ab63553c1 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/index.tsx @@ -0,0 +1,248 @@ +import { + ComponentChildren, createContext, + Fragment, FunctionalComponent, h, VNode +} from "preact"; +import { useContext, useLayoutEffect, useRef } from "preact/hooks"; +import { Menu } from "../../components/menu"; +import { + BackupStates, RecoveryStates, + ReducerStateBackup, + ReducerStateRecovery, +} from "anastasis-core"; +import { + AnastasisReducerApi, + useAnastasisReducer +} from "../../hooks/use-anastasis-reducer"; +import { AttributeEntryScreen } from "./AttributeEntryScreen"; +import { AuthenticationEditorScreen } from "./AuthenticationEditorScreen"; +import { BackupFinishedScreen } from "./BackupFinishedScreen"; +import { ChallengeOverviewScreen } from "./ChallengeOverviewScreen"; +import { ContinentSelectionScreen } from "./ContinentSelectionScreen"; +import { CountrySelectionScreen } from "./CountrySelectionScreen"; +import { PoliciesPayingScreen } from "./PoliciesPayingScreen"; +import { RecoveryFinishedScreen } from "./RecoveryFinishedScreen"; +import { ReviewPoliciesScreen } from "./ReviewPoliciesScreen"; +import { SecretEditorScreen } from "./SecretEditorScreen"; +import { SecretSelectionScreen } from "./SecretSelectionScreen"; +import { SolveScreen } from "./SolveScreen"; +import { StartScreen } from "./StartScreen"; +import { TruthsPayingScreen } from "./TruthsPayingScreen"; + +const WithReducer = createContext(undefined); + +function isBackup(reducer: AnastasisReducerApi): boolean { + return !!reducer.currentReducerState?.backup_state; +} + +export interface CommonReducerProps { + reducer: AnastasisReducerApi; + reducerState: ReducerStateBackup | ReducerStateRecovery; +} + +export function withProcessLabel(reducer: AnastasisReducerApi, text: string): string { + if (isBackup(reducer)) { + return `Backup: ${text}`; + } + return `Recovery: ${text}`; +} + +export interface BackupReducerProps { + reducer: AnastasisReducerApi; + backupState: ReducerStateBackup; +} + +export interface RecoveryReducerProps { + reducer: AnastasisReducerApi; + recoveryState: ReducerStateRecovery; +} + +interface AnastasisClientFrameProps { + onNext?(): void; + title: string; + children: ComponentChildren; + /** + * Should back/next buttons be provided? + */ + hideNav?: boolean; + /** + * Hide only the "next" button. + */ + hideNext?: boolean; +} + +export function AnastasisClientFrame(props: AnastasisClientFrameProps): VNode { + const reducer = useContext(WithReducer); + if (!reducer) { + return

Fatal: Reducer must be in context.

; + } + const next = (): void => { + if (props.onNext) { + props.onNext(); + } else { + reducer.transition("next", {}); + } + }; + const handleKeyPress = (e: h.JSX.TargetedKeyboardEvent): void => { + console.log("Got key press", e.key); + // FIXME: By default, "next" action should be executed here + }; + return ( + +
+
handleKeyPress(e)}> {/* class={style.home} */} + +

{props.title}

+ + {props.children} + {!props.hideNav ? ( +
+ + {!props.hideNext ? ( + + ) : null} +
+ ) : null} +
+
+ + ); +} + +const AnastasisClient: FunctionalComponent = () => { + const reducer = useAnastasisReducer(); + return ( + + + + ); +}; + +const AnastasisClientImpl: FunctionalComponent = () => { + const reducer = useContext(WithReducer)!; + const reducerState = reducer.currentReducerState; + if (!reducerState) { + return ; + } + console.log("state", reducer.currentReducerState); + + if ( + reducerState.backup_state === BackupStates.ContinentSelecting || + reducerState.recovery_state === RecoveryStates.ContinentSelecting + ) { + return ; + } + if ( + reducerState.backup_state === BackupStates.CountrySelecting || + reducerState.recovery_state === RecoveryStates.CountrySelecting + ) { + return ; + } + if ( + reducerState.backup_state === BackupStates.UserAttributesCollecting || + reducerState.recovery_state === RecoveryStates.UserAttributesCollecting + ) { + return ; + } + if (reducerState.backup_state === BackupStates.AuthenticationsEditing) { + return ( + + ); + } + if (reducerState.backup_state === BackupStates.PoliciesReviewing) { + return ; + } + if (reducerState.backup_state === BackupStates.SecretEditing) { + return ; + } + + if (reducerState.backup_state === BackupStates.BackupFinished) { + const backupState: ReducerStateBackup = reducerState; + return ; + } + + if (reducerState.backup_state === BackupStates.TruthsPaying) { + return + + } + + if (reducerState.backup_state === BackupStates.PoliciesPaying) { + const backupState: ReducerStateBackup = reducerState; + return + } + + if (reducerState.recovery_state === RecoveryStates.SecretSelecting) { + return ; + } + + if (reducerState.recovery_state === RecoveryStates.ChallengeSelecting) { + return ; + } + + if (reducerState.recovery_state === RecoveryStates.ChallengeSolving) { + return + } + + if (reducerState.recovery_state === RecoveryStates.RecoveryFinished) { + return + } + + console.log("unknown state", reducer.currentReducerState); + return ( + +

Bug: Unknown state.

+ +
+ ); +}; + + +interface LabeledInputProps { + label: string; + grabFocus?: boolean; + bind: [string, (x: string) => void]; +} + +export function LabeledInput(props: LabeledInputProps): VNode { + const inputRef = useRef(null); + useLayoutEffect(() => { + if (props.grabFocus) { + inputRef.current?.focus(); + } + }, [props.grabFocus]); + return ( + + ); +} + + +interface ErrorBannerProps { + reducer: AnastasisReducerApi; +} + +/** + * Show a dismissable error banner if there is a current error. + */ +function ErrorBanner(props: ErrorBannerProps): VNode | null { + const currentError = props.reducer.currentError; + if (currentError) { + return ( +
{/* style.error */} +

Error: {JSON.stringify(currentError)}

+ +
+ ); + } + return null; +} + +export default AnastasisClient; -- cgit v1.2.3