feedback state rendering
This commit is contained in:
parent
d43ab6af87
commit
a9d2a4654b
@ -46,10 +46,10 @@ function messageStyle(type: MessageType): string {
|
||||
|
||||
export function Notifications({ notifications, removeNotification }: Props): VNode {
|
||||
return <div class="block">
|
||||
{notifications.map((n,i) => <article key={i} class={messageStyle(n.type)}>
|
||||
{notifications.map((n, i) => <article key={i} class={messageStyle(n.type)}>
|
||||
<div class="message-header">
|
||||
<p>{n.message}</p>
|
||||
<button class="delete" onClick={() => removeNotification && removeNotification(n)} />
|
||||
{removeNotification && <button class="delete" onClick={() => removeNotification && removeNotification(n)} />}
|
||||
</div>
|
||||
{n.description && <div class="message-body">
|
||||
{n.description}
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2021 Taler Systems S.A.
|
||||
@ -20,7 +19,7 @@
|
||||
* @author Sebastian Javier Marchano (sebasjm)
|
||||
*/
|
||||
|
||||
import { RecoveryStates, ReducerState } from "anastasis-core";
|
||||
import { ChallengeFeedbackStatus, RecoveryStates, ReducerState } from "anastasis-core";
|
||||
import { createExample, reducerStatesExample } from "../../utils";
|
||||
import { ChallengeOverviewScreen as TestedComponent } from "./ChallengeOverviewScreen";
|
||||
|
||||
@ -176,16 +175,15 @@ export const OnePolicyWithAllTheChallengesInDifferentState = createExample(
|
||||
recovery_information: {
|
||||
policies: [
|
||||
[
|
||||
{ uuid: "1" },
|
||||
{ uuid: "2" },
|
||||
{ uuid: "3" },
|
||||
{ uuid: "4" },
|
||||
{ uuid: "5" },
|
||||
{ uuid: "6" },
|
||||
{ uuid: "7" },
|
||||
{ uuid: "8" },
|
||||
{ uuid: "9" },
|
||||
{ uuid: "10" },
|
||||
{ uuid: "uuid-1" },
|
||||
{ uuid: "uuid-2" },
|
||||
{ uuid: "uuid-3" },
|
||||
{ uuid: "uuid-4" },
|
||||
{ uuid: "uuid-5" },
|
||||
{ uuid: "uuid-6" },
|
||||
{ uuid: "uuid-7" },
|
||||
{ uuid: "uuid-8" },
|
||||
{ uuid: "uuid-9" },
|
||||
],
|
||||
],
|
||||
challenges: [
|
||||
@ -193,20 +191,96 @@ export const OnePolicyWithAllTheChallengesInDifferentState = createExample(
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "solved"',
|
||||
type: "question",
|
||||
uuid: "1",
|
||||
uuid: "uuid-1",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "message"',
|
||||
type: "question",
|
||||
uuid: "2",
|
||||
uuid: "uuid-2",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "auth iban"',
|
||||
type: "question",
|
||||
uuid: "uuid-3",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "payment "',
|
||||
type: "question",
|
||||
uuid: "uuid-4",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "rate limit"',
|
||||
type: "question",
|
||||
uuid: "uuid-5",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "redirect"',
|
||||
type: "question",
|
||||
uuid: "uuid-6",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "server failure"',
|
||||
type: "question",
|
||||
uuid: "uuid-7",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "truth unknown"',
|
||||
type: "question",
|
||||
uuid: "uuid-8",
|
||||
},
|
||||
{
|
||||
cost: "USD:1",
|
||||
instructions: 'in state "unsupported"',
|
||||
type: "question",
|
||||
uuid: "uuid-9",
|
||||
},
|
||||
],
|
||||
},
|
||||
challenge_feedback: {
|
||||
1: { state: "solved" },
|
||||
2: { state: "message", message: "Security question was not solved correctly" },
|
||||
// FIXME: add missing feedback states here!
|
||||
"uuid-1": { state: ChallengeFeedbackStatus.Solved.toString() },
|
||||
"uuid-2": {
|
||||
state: ChallengeFeedbackStatus.Message.toString(),
|
||||
message: 'Challenge should be solved'
|
||||
},
|
||||
"uuid-3": {
|
||||
state: ChallengeFeedbackStatus.AuthIban.toString(),
|
||||
challenge_amount: "EUR:1",
|
||||
credit_iban: "DE12345789000",
|
||||
business_name: "Data Loss Incorporated",
|
||||
wire_transfer_subject: "Anastasis 987654321"
|
||||
},
|
||||
"uuid-4": {
|
||||
state: ChallengeFeedbackStatus.Payment.toString(),
|
||||
taler_pay_uri: "taler://pay/...",
|
||||
provider: "https://localhost:8080/",
|
||||
payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
|
||||
},
|
||||
"uuid-5": {
|
||||
state: ChallengeFeedbackStatus.RateLimitExceeded.toString(),
|
||||
// "error_code": 8121
|
||||
},
|
||||
"uuid-6": {
|
||||
state: ChallengeFeedbackStatus.Redirect.toString(),
|
||||
redirect_url: "https://videoconf.example.com/",
|
||||
http_status: 303
|
||||
},
|
||||
"uuid-7": {
|
||||
state: ChallengeFeedbackStatus.ServerFailure.toString(),
|
||||
http_status: 500,
|
||||
error_response: "some error message or error object",
|
||||
},
|
||||
"uuid-8": {
|
||||
state: ChallengeFeedbackStatus.TruthUnknown.toString(),
|
||||
// "error_code": 8108
|
||||
},
|
||||
"uuid-9": { state: ChallengeFeedbackStatus.Unsupported.toString() },
|
||||
},
|
||||
} as ReducerState,
|
||||
);
|
||||
|
@ -12,27 +12,24 @@ function OverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) {
|
||||
switch (feedback.state) {
|
||||
case ChallengeFeedbackStatus.Message:
|
||||
return (
|
||||
<div>
|
||||
<p>{feedback.message}</p>
|
||||
</div>
|
||||
<div class="block has-text-danger">{feedback.message}</div>
|
||||
);
|
||||
case ChallengeFeedbackStatus.Solved:
|
||||
return <div />
|
||||
case ChallengeFeedbackStatus.Pending:
|
||||
case ChallengeFeedbackStatus.AuthIban:
|
||||
return null;
|
||||
case ChallengeFeedbackStatus.ServerFailure:
|
||||
return <div class="block has-text-danger">Server error.</div>;
|
||||
case ChallengeFeedbackStatus.RateLimitExceeded:
|
||||
return <div>Rate limit exceeded.</div>;
|
||||
case ChallengeFeedbackStatus.Redirect:
|
||||
return <div>Redirect (FIXME: not supported)</div>;
|
||||
return <div class="block has-text-danger">There were to many failed attempts.</div>;
|
||||
case ChallengeFeedbackStatus.Unsupported:
|
||||
return <div>Challenge not supported by client.</div>;
|
||||
return <div class="block has-text-danger">This client doesn't support solving this type of challenge. Use another version or contact the provider.</div>;
|
||||
case ChallengeFeedbackStatus.TruthUnknown:
|
||||
return <div>Truth unknown</div>;
|
||||
return <div class="block has-text-danger">Provider doesn't recognize the challenge of the policy. Contact the provider for further information.</div>;
|
||||
case ChallengeFeedbackStatus.Redirect:
|
||||
default:
|
||||
return (
|
||||
<div>
|
||||
<pre>{JSON.stringify(feedback)}</pre>
|
||||
</div>
|
||||
);
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,6 +110,77 @@ export function ChallengeOverviewScreen(): VNode {
|
||||
const tableBody = policy.challenges.map(({ info, uuid }) => {
|
||||
const isFree = !info.cost || info.cost.endsWith(":0");
|
||||
const method = authMethods[info.type as KnownAuthMethods];
|
||||
|
||||
if (!method) {
|
||||
return <div
|
||||
key={uuid}
|
||||
class="block"
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
>
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<span>unknown challenge</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
function ChallengeButton({ id, feedback }: { id: string; feedback?: ChallengeFeedback }): VNode {
|
||||
function selectChallenge(): void {
|
||||
if (reducer) reducer.transition("select_challenge", { uuid: id })
|
||||
}
|
||||
if (!feedback) {
|
||||
return <div>
|
||||
<button class="button" onClick={selectChallenge}>
|
||||
Solve
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
switch (feedback.state) {
|
||||
case ChallengeFeedbackStatus.ServerFailure:
|
||||
case ChallengeFeedbackStatus.Unsupported:
|
||||
case ChallengeFeedbackStatus.TruthUnknown:
|
||||
case ChallengeFeedbackStatus.RateLimitExceeded: return <div />
|
||||
case ChallengeFeedbackStatus.AuthIban:
|
||||
case ChallengeFeedbackStatus.Payment: return <div>
|
||||
<button class="button" onClick={selectChallenge}>
|
||||
Pay
|
||||
</button>
|
||||
</div>
|
||||
case ChallengeFeedbackStatus.Redirect: return <div>
|
||||
<button class="button" onClick={selectChallenge}>
|
||||
Go to {feedback.redirect_url}
|
||||
</button>
|
||||
</div>
|
||||
case ChallengeFeedbackStatus.Solved: return <div>
|
||||
<div class="tag is-success is-large">
|
||||
Solved
|
||||
</div>
|
||||
</div>
|
||||
default: return <div>
|
||||
<button class="button" onClick={selectChallenge}>
|
||||
Solve
|
||||
</button>
|
||||
</div>
|
||||
|
||||
}
|
||||
// return <div>
|
||||
// {feedback.state !== "solved" ? (
|
||||
// <a
|
||||
// class="button"
|
||||
// onClick={() =>
|
||||
|
||||
// }
|
||||
// >
|
||||
// {isFree ? "Solve" : `Pay and Solve`}
|
||||
// </a>
|
||||
// ) : null}
|
||||
// {feedback.state === "solved" ? (
|
||||
// // <div class="block is-success" > Solved </div>
|
||||
// <div class="tag is-success is-large">Solved</div>
|
||||
|
||||
// ) : null}
|
||||
// </div>
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={uuid}
|
||||
@ -131,21 +199,9 @@ export function ChallengeOverviewScreen(): VNode {
|
||||
</div>
|
||||
<OverviewFeedbackDisplay feedback={info.feedback} />
|
||||
</div>
|
||||
<div>
|
||||
{method && info.feedback?.state !== "solved" ? (
|
||||
<a
|
||||
class="button"
|
||||
onClick={() =>
|
||||
reducer.transition("select_challenge", { uuid })
|
||||
}
|
||||
>
|
||||
{isFree ? "Solve" : `Pay and Solve`}
|
||||
</a>
|
||||
) : null}
|
||||
{info.feedback?.state === "solved" ? (
|
||||
<a class="button is-success"> Solved </a>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<ChallengeButton id={uuid} feedback={info.feedback} />
|
||||
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@ -156,8 +212,8 @@ export function ChallengeOverviewScreen(): VNode {
|
||||
const opa = !atLeastThereIsOnePolicySolved
|
||||
? undefined
|
||||
: policy.isPolicySolved
|
||||
? undefined
|
||||
: "0.6";
|
||||
? undefined
|
||||
: "0.6";
|
||||
return (
|
||||
<div
|
||||
key={policy_index}
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
|
@ -104,7 +104,7 @@ function ChooseAnotherProviderScreen({ providers, selected, onChange }: { select
|
||||
|
||||
function SelectOtherVersionProviderScreen({ providers, provider, version, onConfirm, onCancel }: { onCancel: () => void; provider: string; version: number; providers: string[]; onConfirm: (prov: string, v: number) => Promise<void>; }): VNode {
|
||||
const [otherProvider, setOtherProvider] = useState<string>(provider);
|
||||
const [otherVersion, setOtherVersion] = useState(`${version}`);
|
||||
const [otherVersion, setOtherVersion] = useState(version > 0 ? String(version) : "");
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame hideNav title="Recovery: Select secret">
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2021 Taler Systems S.A.
|
||||
@ -20,7 +19,7 @@
|
||||
* @author Sebastian Javier Marchano (sebasjm)
|
||||
*/
|
||||
|
||||
import { ReducerState } from 'anastasis-core';
|
||||
import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
|
||||
import { createExample, reducerStatesExample } from '../../utils';
|
||||
import { SolveScreen as TestedComponent } from './SolveScreen';
|
||||
|
||||
@ -50,7 +49,8 @@ export const NotSupportedChallenge = createExample(TestedComponent, {
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1'
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const MismatchedChallengeId = createExample(TestedComponent, {
|
||||
@ -78,7 +78,8 @@ export const SmsChallenge = createExample(TestedComponent, {
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1'
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallenge = createExample(TestedComponent, {
|
||||
@ -92,7 +93,8 @@ export const QuestionChallenge = createExample(TestedComponent, {
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1'
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const EmailChallenge = createExample(TestedComponent, {
|
||||
@ -106,7 +108,8 @@ export const EmailChallenge = createExample(TestedComponent, {
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1'
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const PostChallenge = createExample(TestedComponent, {
|
||||
@ -120,5 +123,181 @@ export const PostChallenge = createExample(TestedComponent, {
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1'
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
|
||||
export const QuestionChallengeMessageFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.Message,
|
||||
message: 'Challenge should be solved'
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengeServerFailureFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.ServerFailure,
|
||||
http_status: 500,
|
||||
error_response: "Couldn't connect to mysql"
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengeRedirectFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.Redirect,
|
||||
http_status: 302,
|
||||
redirect_url: 'http://video.taler.net'
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengeMessageRateLimitExceededFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.RateLimitExceeded,
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengeUnsupportedFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.Unsupported,
|
||||
http_status: 500,
|
||||
unsupported_method: 'Question'
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengeTruthUnknownFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.TruthUnknown,
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengeAuthIbanFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.AuthIban,
|
||||
challenge_amount: "EUR:1",
|
||||
credit_iban: "DE12345789000",
|
||||
business_name: "Data Loss Incorporated",
|
||||
wire_transfer_subject: "Anastasis 987654321"
|
||||
}
|
||||
}
|
||||
|
||||
} as ReducerState);
|
||||
|
||||
export const QuestionChallengePaymentFeedback = createExample(TestedComponent, {
|
||||
...reducerStatesExample.challengeSolving,
|
||||
recovery_information: {
|
||||
challenges: [{
|
||||
cost: 'USD:1',
|
||||
instructions: 'does P equals NP?',
|
||||
type: 'question',
|
||||
uuid: 'ASDASDSAD!1'
|
||||
}],
|
||||
policies: [],
|
||||
},
|
||||
selected_challenge_uuid: 'ASDASDSAD!1',
|
||||
challenge_feedback: {
|
||||
'ASDASDSAD!1': {
|
||||
state: ChallengeFeedbackStatus.Payment,
|
||||
taler_pay_uri : "taler://pay/...",
|
||||
provider : "https://localhost:8080/",
|
||||
payment_secret : "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
|
||||
}
|
||||
}
|
||||
} as ReducerState);
|
||||
|
||||
|
@ -8,31 +8,67 @@ import {
|
||||
} from "../../../../anastasis-core/lib";
|
||||
import { AsyncButton } from "../../components/AsyncButton";
|
||||
import { TextInput } from "../../components/fields/TextInput";
|
||||
import { Notifications } from "../../components/Notifications";
|
||||
import { useAnastasisContext } from "../../context/anastasis";
|
||||
|
||||
function SolveOverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) {
|
||||
function SolveOverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }): VNode {
|
||||
const { feedback } = props;
|
||||
if (!feedback) {
|
||||
return null;
|
||||
return <div />;
|
||||
}
|
||||
switch (feedback.state) {
|
||||
case ChallengeFeedbackStatus.Message:
|
||||
return (
|
||||
<div>
|
||||
<p>{feedback.message}</p>
|
||||
</div>
|
||||
);
|
||||
case ChallengeFeedbackStatus.Pending:
|
||||
return (<Notifications notifications={[{
|
||||
type: "INFO",
|
||||
message: `Message from provider`,
|
||||
description: feedback.message
|
||||
}]} />);
|
||||
case ChallengeFeedbackStatus.Payment:
|
||||
return <Notifications notifications={[{
|
||||
type: "INFO",
|
||||
message: `Message from provider`,
|
||||
description: <span>
|
||||
To pay you can <a href={feedback.taler_pay_uri}>click here</a>
|
||||
</span>
|
||||
}]} />
|
||||
case ChallengeFeedbackStatus.AuthIban:
|
||||
return null;
|
||||
return <Notifications notifications={[{
|
||||
type: "INFO",
|
||||
message: `Message from provider`,
|
||||
description: `Need to send a wire transfer to "${feedback.business_name}"`
|
||||
}]} />;
|
||||
case ChallengeFeedbackStatus.ServerFailure:
|
||||
return (<Notifications notifications={[{
|
||||
type: "ERROR",
|
||||
message: `Server error: Code ${feedback.http_status}`,
|
||||
description: feedback.error_response
|
||||
}]} />);
|
||||
case ChallengeFeedbackStatus.RateLimitExceeded:
|
||||
return <div>Rate limit exceeded.</div>;
|
||||
return (<Notifications notifications={[{
|
||||
type: "ERROR",
|
||||
message: `Message from provider`,
|
||||
description: "There were to many failed attempts."
|
||||
}]} />);
|
||||
case ChallengeFeedbackStatus.Redirect:
|
||||
return <div>Redirect (FIXME: not supported)</div>;
|
||||
return (<Notifications notifications={[{
|
||||
type: "INFO",
|
||||
message: `Message from provider`,
|
||||
description: <span>
|
||||
Please visit this link: <a>{feedback.redirect_url}</a>
|
||||
</span>
|
||||
}]} />);
|
||||
case ChallengeFeedbackStatus.Unsupported:
|
||||
return <div>Challenge not supported by client.</div>;
|
||||
return (<Notifications notifications={[{
|
||||
type: "ERROR",
|
||||
message: `This client doesn't support solving this type of challenge`,
|
||||
description: `Use another version or contact the provider. Type of challenge "${feedback.unsupported_method}"`
|
||||
}]} />);
|
||||
case ChallengeFeedbackStatus.TruthUnknown:
|
||||
return <div>Truth unknown</div>;
|
||||
return (<Notifications notifications={[{
|
||||
type: "ERROR",
|
||||
message: `Provider doesn't recognize the type of challenge`,
|
||||
description: "Contact the provider for further information"
|
||||
}]} />);
|
||||
default:
|
||||
return (
|
||||
<div>
|
||||
@ -79,8 +115,8 @@ export function SolveScreen(): VNode {
|
||||
<AnastasisClientFrame hideNav title="Recovery problem">
|
||||
<div>invalid state</div>
|
||||
<div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button class="button" onClick={() => reducer.back()}>Back</button>
|
||||
</div>
|
||||
<button class="button" onClick={() => reducer.back()}>Back</button>
|
||||
</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
}
|
||||
@ -114,17 +150,23 @@ export function SolveScreen(): VNode {
|
||||
reducer?.back();
|
||||
}
|
||||
|
||||
const feedback = challengeFeedback[selectedUuid]
|
||||
const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded
|
||||
|| feedback?.state === ChallengeFeedbackStatus.Redirect
|
||||
|| feedback?.state === ChallengeFeedbackStatus.Unsupported
|
||||
|| feedback?.state === ChallengeFeedbackStatus.TruthUnknown
|
||||
|
||||
return (
|
||||
<AnastasisClientFrame hideNav title="Recovery: Solve challenge">
|
||||
<SolveOverviewFeedbackDisplay
|
||||
feedback={challengeFeedback[selectedUuid]}
|
||||
feedback={feedback}
|
||||
/>
|
||||
<SolveDialog
|
||||
id={selectedUuid}
|
||||
answer={answer}
|
||||
setAnswer={setAnswer}
|
||||
challenge={selectedChallenge}
|
||||
feedback={challengeFeedback[selectedUuid]}
|
||||
feedback={feedback}
|
||||
/>
|
||||
|
||||
<div
|
||||
@ -137,9 +179,9 @@ export function SolveScreen(): VNode {
|
||||
<button class="button" onClick={onCancel}>
|
||||
Cancel
|
||||
</button>
|
||||
<AsyncButton class="button is-info" onClick={onNext}>
|
||||
{!shouldHideConfirm && <AsyncButton class="button is-info" onClick={onNext}>
|
||||
Confirm
|
||||
</AsyncButton>
|
||||
</AsyncButton>}
|
||||
</div>
|
||||
</AnastasisClientFrame>
|
||||
);
|
||||
@ -160,6 +202,7 @@ function SolveSmsEntry({
|
||||
}: SolveEntryProps): VNode {
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
<p>
|
||||
An sms has been sent to "<b>{challenge.instructions}</b>". Type the code
|
||||
below
|
||||
|
Loading…
Reference in New Issue
Block a user