+
+ {detail ?? problem?.detail ?? defaultDetail(state, session)}
+ {session?.provider === undefined ? null : Provider: {session.provider}
}
+ {problem === undefined ? null : Problem: {problem.code}
}
+ {visibleActions.length === 0 ? null : {visibleActions.map(actionButton)}
}
+
+ );
+}
+
+export function toAstryxAuthStateProps(state: AstryxSessionState): AstryxAuthStateProps {
+ switch (state.kind) {
+ case "loading":
+ return {
+ recoveryActions: state.recoveryActions,
+ state: "loading",
+ };
+ case "authenticated":
+ return {
+ session: state.session,
+ state: "signed-in",
+ };
+ case "unauthenticated":
+ return {
+ problem: state.problem,
+ recoveryActions: state.recoveryActions,
+ state: "signed-out",
+ };
+ case "unavailable":
+ return {
+ problem: state.problem,
+ recoveryActions: state.recoveryActions,
+ state: "unavailable",
+ };
+ }
+}
diff --git a/packages/ui-astryx/src/libs/AstryxProblemView.tsx b/packages/ui-astryx/src/libs/AstryxProblemView.tsx
new file mode 100644
index 000000000..ab368c5e1
--- /dev/null
+++ b/packages/ui-astryx/src/libs/AstryxProblemView.tsx
@@ -0,0 +1,79 @@
+import { Banner } from "@astryxdesign/core/Banner";
+import { Button } from "@astryxdesign/core/Button";
+
+import type { ProblemDetails } from "@croco/problems-core";
+
+import type { AstryxProblemRecoveryAction } from "./crocoUiTypes";
+
+export type AstryxProblemViewProps = {
+ readonly problem: ProblemDetails;
+ readonly recoveryActions?: readonly AstryxProblemRecoveryAction[];
+};
+
+function problemStatus(status: number): "error" | "info" | "warning" {
+ if (status >= 500) {
+ return "error";
+ }
+
+ if (status >= 400) {
+ return "warning";
+ }
+
+ return "info";
+}
+
+function appliesToProblem(action: AstryxProblemRecoveryAction, problem: ProblemDetails): boolean {
+ return action.problemCodes === undefined || action.problemCodes.includes(problem.code);
+}
+
+function recoveryButton(action: AstryxProblemRecoveryAction, problem: ProblemDetails) {
+ const recover = action.onRecover;
+ const clickAction = recover === undefined ? undefined : () => recover(problem);
+
+ return (
+