Improve error managment

This commit is contained in:
Arnaud 2024-09-23 18:41:13 +02:00
parent 78c344d9db
commit aabe30c370
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
8 changed files with 63 additions and 34 deletions

View File

@ -1,6 +1,5 @@
import {
Stepper,
Toast,
useStepperReducer,
Button,
Modal,
@ -14,18 +13,18 @@ import { WebStorage } from "../../utils/web-storage";
import { UIAvailability } from "./types";
import { STEPPER_DURATION } from "../../utils/constants";
import { useAvailabilityMutation } from "./useAvailabilityMutation";
import { AvailabilityDone } from "./AvailabilityDone";
import { AvailabilitySuccess } from "./AvailabilitySuccess";
import { AvailabilityError } from "./AvailabilityError";
type Props = {
space: CodexNodeSpace;
};
const CONFIRM_STATE = 2;
const STEPS = 3;
export function AvailabilityCreate({ space }: Props) {
const components = [AvailabilityForm, AvailabilityConfirm, AvailabilityDone];
const steps = useRef(["Availability", "Confirmation", "Success"]);
const { state, dispatch } = useStepperReducer(components.length);
const [availability, setAvailability] = useState<UIAvailability>({
totalSize: 1,
duration: 1,
@ -34,6 +33,13 @@ export function AvailabilityCreate({ space }: Props) {
totalSizeUnit: "gb",
durationUnit: "days",
});
const { state, dispatch } = useStepperReducer(STEPS);
const { mutateAsync, error } = useAvailabilityMutation(dispatch, state);
const components = [
AvailabilityForm,
AvailabilityConfirm,
error ? () => <AvailabilityError error={error} /> : AvailabilitySuccess,
];
useEffect(() => {
Promise.all([
@ -58,8 +64,6 @@ export function AvailabilityCreate({ space }: Props) {
});
}, [dispatch]);
const { mutateAsync, toast } = useAvailabilityMutation(dispatch, state);
const onNextStep = async (step: number) => {
WebStorage.set("availability-step", step);
@ -130,8 +134,6 @@ export function AvailabilityCreate({ space }: Props) {
/>
</Stepper>
</Modal>
<Toast message={toast.message} time={toast.time} variant="error" />
</>
);
}

View File

@ -1,7 +0,0 @@
.availabilityDone {
margin: auto;
}
.availabilityDone-icon {
color: var(--codex-color-primary);
}

View File

@ -0,0 +1,16 @@
import { Placeholder } from "@codex-storage/marketplace-ui-components";
import { ErrorIcon } from "../ErrorIcon/ErrorIcon";
type Props = {
error: Error;
};
export function AvailabilityError({ error }: Props) {
return (
<Placeholder
Icon={<ErrorIcon />}
title="Error"
subtitle={"Got an error when trying to create the availability."}
message={error.message}></Placeholder>
);
}

View File

@ -33,7 +33,7 @@ export function AvailabilityForm({
const unit = availability.totalSizeUnit === "gb" ? GB : TB;
return value * unit > space.quotaMaxBytes - space.quotaReservedBytes;
},
[space]
[space, availability]
);
useEffect(() => {
@ -41,12 +41,13 @@ export function AvailabilityForm({
setTotalSizeError(
"You cannot allocate more space than the remaining space."
);
} else {
setTotalSizeError("");
}
}, [availability]);
}, [availability, isAvailabilityInvalid]);
const onTotalSizeUnitChange = async (e: ChangeEvent<HTMLSelectElement>) => {
const element = e.currentTarget;
const valid = element.value === "tb" || element.value === "gb";
dispatch({
type: "toggle-next",
@ -98,7 +99,6 @@ export function AvailabilityForm({
const onInputChange = async (e: ChangeEvent<HTMLInputElement>) => {
const element = e.currentTarget;
const valid = element.checkValidity();
onAvailabilityChange({
[element.name]: parseFloat(element.value),

View File

@ -2,15 +2,14 @@ import {
Placeholder,
StepperAction,
} from "@codex-storage/marketplace-ui-components";
import { CircleCheck } from "lucide-react";
import { Dispatch, useEffect } from "react";
import "./AvailabilityDone.css";
import { SuccessIcon } from "../SuccessIcon/SuccessIcon";
type Props = {
dispatch: Dispatch<StepperAction>;
};
export function AvailabilityDone({ dispatch }: Props) {
export function AvailabilitySuccess({ dispatch }: Props) {
useEffect(() => {
dispatch({
isNextEnable: true,
@ -20,9 +19,8 @@ export function AvailabilityDone({ dispatch }: Props) {
return (
<Placeholder
Icon={<CircleCheck size="4rem" className="availabilityDone-icon" />}
className="availabilityDone"
title="Your availability is created."
Icon={<SuccessIcon />}
title="Success"
message="The new availability will appear in your availability list. You can safely close this dialog."></Placeholder>
);
}

View File

@ -1,5 +1,4 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { CodexSdk } from "../../proxy";
import { GB, TB } from "../../utils/constants";
import { Promises } from "../../utils/promises";
import { WebStorage } from "../../utils/web-storage";
@ -12,16 +11,14 @@ import {
import * as Sentry from "@sentry/browser";
import { SafeValue } from "@codex-storage/sdk-js/async";
import { Times } from "../../utils/times";
import { CodexSdk } from "../../sdk/codex";
export function useAvailabilityMutation(
dispatch: Dispatch<StepperAction>,
state: StepperState
) {
const queryClient = useQueryClient();
const [toast, setToast] = useState({
time: 0,
message: "",
});
const [error, setError] = useState<Error | null>(null);
const { mutateAsync } = useMutation({
mutationKey: ["debug"],
@ -66,12 +63,15 @@ export function useAvailabilityMutation(
Sentry.captureException(error);
}
setToast({
message: "Error when trying to update: " + error.message,
time: Date.now(),
setError(error);
dispatch({
type: "next",
step: state.step,
isBackEnable: true,
});
},
});
return { mutateAsync, toast };
return { mutateAsync, error };
}

View File

@ -0,0 +1,10 @@
import { CircleX } from "lucide-react";
import { SimpleText } from "@codex-storage/marketplace-ui-components";
export function ErrorIcon() {
return (
<SimpleText variant="error">
<CircleX size="4rem" />
</SimpleText>
);
}

View File

@ -0,0 +1,10 @@
import { SimpleText } from "@codex-storage/marketplace-ui-components";
import { CircleCheck } from "lucide-react";
export function SuccessIcon() {
return (
<SimpleText variant="primary">
<CircleCheck size="4rem" className="successIcon" />
</SimpleText>
);
}