wallet-core/packages/anastasis-webui/src/utils/index.tsx
2022-12-06 11:21:12 -03:00

337 lines
8.6 KiB
TypeScript

/*
This file is part of GNU Anastasis
(C) 2021-2022 Anastasis SARL
GNU Anastasis is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Anastasis 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with
GNU Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import {
AuthenticationProviderStatusError,
AuthenticationProviderStatusOk,
BackupStates,
RecoveryStates,
ReducerState,
ReducerStateRecovery,
} from "@gnu-taler/anastasis-core";
import { ComponentChildren, FunctionalComponent, h, VNode } from "preact";
import { AnastasisProvider } from "../context/anastasis.js";
const noop = async (): Promise<void> => {
return;
};
export function createExampleWithoutAnastasis<Props>(
Component: FunctionalComponent<Props>,
props: Partial<Props> | (() => Partial<Props>),
): ComponentChildren {
//FIXME: props are evaluated on build time
// in some cases we want to evaluated the props on render time so we can get some relative timestamp
// check how we can build evaluatedProps in render time
const evaluatedProps = typeof props === "function" ? props() : props;
const Render = (args: any): VNode => h(Component, args);
return {
component: Render,
props: evaluatedProps,
};
}
export function createExample<Props>(
Component: FunctionalComponent<Props>,
currentReducerState?: ReducerState,
props?: Partial<Props>,
): ComponentChildren {
const Render = (args: Props): VNode => {
return (
<AnastasisProvider
value={{
currentReducerState,
discoverMore: noop,
discoverStart: noop,
discoveryState: {
state: "finished",
},
currentError: undefined,
back: noop,
dismissError: noop,
reset: noop,
runTransaction: noop,
startBackup: noop,
startRecover: noop,
transition: noop,
exportState: () => {
return "{}";
},
importState: noop,
}}
>
<Component {...(args as any)} />
</AnastasisProvider>
);
};
return {
component: Render,
props: props,
};
}
const base = {
continents: [
{
name: "Europe",
},
{
name: "India",
},
{
name: "Asia",
},
{
name: "North America",
},
{
name: "Testcontinent",
},
],
countries: [
{
code: "xx",
name: "Testland",
continent: "Testcontinent",
continent_i18n: {
de_DE: "Testkontinent",
},
name_i18n: {
de_DE: "Testlandt",
de_CH: "Testlandi",
fr_FR: "Testpais",
en_UK: "Testland",
},
currency: "TESTKUDOS",
call_code: "+00",
},
{
code: "xy",
name: "Demoland",
continent: "Testcontinent",
continent_i18n: {
de_DE: "Testkontinent",
},
name_i18n: {
de_DE: "Demolandt",
de_CH: "Demolandi",
fr_FR: "Demopais",
en_UK: "Demoland",
},
currency: "KUDOS",
call_code: "+01",
},
],
authentication_providers: {
"http://localhost:8086/": {
status: "ok",
http_status: 200,
annual_fee: "COL:0",
business_name: "Anastasis Local",
currency: "COL",
liability_limit: "COL:10",
methods: [
{
type: "question",
usage_fee: "COL:0",
},
{
type: "sms",
usage_fee: "COL:0",
},
{
type: "email",
usage_fee: "COL:0",
},
],
provider_salt: "WBMDD76BR1E90YQ5AHBMKPH7GW",
storage_limit_in_megabytes: 16,
truth_upload_fee: "COL:0",
} as AuthenticationProviderStatusOk,
"https://kudos.demo.anastasis.lu/": {
status: "ok",
http_status: 200,
annual_fee: "COL:0",
business_name: "Anastasis Kudo",
currency: "COL",
liability_limit: "COL:10",
methods: [
{
type: "question",
usage_fee: "COL:0",
},
{
type: "email",
usage_fee: "COL:0",
},
],
provider_salt: "WBMDD76BR1E90YQ5AHBMKPH7GW",
storage_limit_in_megabytes: 16,
truth_upload_fee: "COL:0",
} as AuthenticationProviderStatusOk,
"https://anastasis.demo.taler.net/": {
status: "ok",
http_status: 200,
annual_fee: "COL:0",
business_name: "Anastasis Demo",
currency: "COL",
liability_limit: "COL:10",
methods: [
{
type: "question",
usage_fee: "COL:0",
},
{
type: "sms",
usage_fee: "COL:0",
},
{
type: "totp",
usage_fee: "COL:0",
},
],
provider_salt: "WBMDD76BR1E90YQ5AHBMKPH7GW",
storage_limit_in_megabytes: 16,
truth_upload_fee: "COL:0",
} as AuthenticationProviderStatusOk,
"http://localhost:8087/": {
status: "error",
code: 8414,
hint: "request to provider failed",
} as AuthenticationProviderStatusError,
"http://localhost:8088/": {
status: "error",
code: 8414,
hint: "request to provider failed",
} as AuthenticationProviderStatusError,
"http://localhost:8089/": {
status: "error",
code: 8414,
hint: "request to provider failed",
} as AuthenticationProviderStatusError,
},
} as Partial<ReducerState>;
export const reducerStatesExample = {
initial: undefined,
recoverySelectCountry: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.CountrySelecting,
} as ReducerState,
recoverySelectContinent: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.ContinentSelecting,
} as ReducerState,
secretSelection: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.SecretSelecting,
} as ReducerState,
recoveryFinished: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.RecoveryFinished,
} as ReducerState,
challengeSelecting: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.ChallengeSelecting,
} as ReducerState,
challengeSolving: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.ChallengeSolving,
} as ReducerStateRecovery,
challengePaying: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.ChallengePaying,
} as ReducerState,
recoveryAttributeEditing: {
...base,
reducer_type: "recovery",
recovery_state: RecoveryStates.UserAttributesCollecting,
} as ReducerState,
backupSelectCountry: {
...base,
reducer_type: "backup",
backup_state: BackupStates.CountrySelecting,
} as ReducerState,
backupSelectContinent: {
...base,
reducer_type: "backup",
backup_state: BackupStates.ContinentSelecting,
} as ReducerState,
secretEdition: {
...base,
reducer_type: "backup",
backup_state: BackupStates.SecretEditing,
} as ReducerState,
policyReview: {
...base,
reducer_type: "backup",
backup_state: BackupStates.PoliciesReviewing,
} as ReducerState,
policyPay: {
...base,
reducer_type: "backup",
backup_state: BackupStates.PoliciesPaying,
} as ReducerState,
backupFinished: {
...base,
reducer_type: "backup",
backup_state: BackupStates.BackupFinished,
} as ReducerState,
authEditing: {
...base,
backup_state: BackupStates.AuthenticationsEditing,
reducer_type: "backup",
} as ReducerState,
backupAttributeEditing: {
...base,
reducer_type: "backup",
backup_state: BackupStates.UserAttributesCollecting,
} as ReducerState,
truthsPaying: {
...base,
reducer_type: "backup",
backup_state: BackupStates.TruthsPaying,
} as ReducerState,
};
export type StateFunc<S> = (p: S) => VNode;
export type StateViewMap<StateType extends { status: string }> = {
[S in StateType as S["status"]]: StateFunc<S>;
};
export function compose<SType extends { status: string }, PType>(
name: string,
hook: (p: PType) => SType,
vs: StateViewMap<SType>,
): (p: PType) => VNode {
const Component = (p: PType): VNode => {
const state = hook(p);
const s = state.status as unknown as SType["status"];
const c = vs[s] as unknown as StateFunc<SType>;
return c(state);
};
// Component.name = `${name}`;
return Component;
}