mirror of
https://github.com/logos-storage/logos-storage-marketplace-ui.git
synced 2026-01-06 23:43:07 +00:00
Improve error managment
This commit is contained in:
parent
78c344d9db
commit
aabe30c370
@ -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" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
.availabilityDone {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.availabilityDone-icon {
|
||||
color: var(--codex-color-primary);
|
||||
}
|
||||
16
src/components/Availability/AvailabilityError.tsx
Normal file
16
src/components/Availability/AvailabilityError.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@ -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),
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
@ -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 };
|
||||
}
|
||||
|
||||
10
src/components/ErrorIcon/ErrorIcon.tsx
Normal file
10
src/components/ErrorIcon/ErrorIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
10
src/components/SuccessIcon/SuccessIcon.tsx
Normal file
10
src/components/SuccessIcon/SuccessIcon.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user