Commit 2f4c6b6d authored by tom's avatar tom

public tags resource

parent efc37fa9
......@@ -12,6 +12,9 @@ export const RESOURCES = {
watchlist: {
path: '/api/account/v1/user/watchlist/:id?',
},
public_tags: {
path: '/api/account/v1/user/public_tags/:id?',
},
// DEPRECATED
old_api: {
......@@ -27,3 +30,5 @@ export interface ResourceError<T = unknown> {
status: Response['status'];
statusText: Response['statusText'];
}
export type ResourceErrorAccount<T> = ResourceError<{ errors: T }>
import type { UseQueryOptions } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import type { UserInfo, CustomAbis } from 'types/api/account';
import type { UserInfo, CustomAbis, PublicTags } from 'types/api/account';
import type { CsrfData } from 'types/client/account';
import type { RESOURCES, ResourceError } from './resources';
......@@ -27,4 +27,5 @@ export type ResourcePayload<Q extends keyof typeof RESOURCES> =
Q extends 'user_info' ? UserInfo :
Q extends 'csrf' ? CsrfData :
Q extends 'custom_abi' ? CustomAbis :
Q extends 'public_tags' ? PublicTags :
never;
......@@ -13,7 +13,7 @@ import { useForm, Controller } from 'react-hook-form';
import type { CustomAbi, CustomAbis, CustomAbiErrors } from 'types/api/account';
import type { ResourceError } from 'lib/api/resources';
import type { ResourceErrorAccount } from 'lib/api/resources';
import { resourceKey } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import getErrorMessage from 'lib/getErrorMessage';
......@@ -84,7 +84,7 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
onClose();
},
onError: (error: ResourceError<{ errors: CustomAbiErrors}>) => {
onError: (error: ResourceErrorAccount<CustomAbiErrors>) => {
const errorMap = error.payload?.errors;
if (errorMap?.address_hash || errorMap?.name || errorMap?.abi) {
errorMap?.address_hash && setError('contract_address_hash', { type: 'custom', message: getErrorMessage(errorMap, 'address_hash') });
......
......@@ -4,9 +4,9 @@ import React, { useCallback, useState } from 'react';
import type { ChangeEvent } from 'react';
import type { PublicTags, PublicTag } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import useFetch from 'lib/hooks/useFetch';
import { resourceKey } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import DeleteModal from 'ui/shared/DeleteModal';
type Props = {
......@@ -23,17 +23,20 @@ const DeletePublicTagModal: React.FC<Props> = ({ isOpen, onClose, data, onDelete
const tags = data.tags.split(';');
const queryClient = useQueryClient();
const fetch = useFetch();
const apiFetch = useApiFetch();
const formBackgroundColor = useColorModeValue('white', 'gray.900');
const deleteApiKey = useCallback(() => {
const body = { remove_reason: reason };
return fetch(`/node-api/account/public-tags/${ data.id }`, { method: 'DELETE', body });
}, [ data.id, fetch, reason ]);
return apiFetch('public_tags', {
pathParams: { id: String(data.id) },
fetchParams: { method: 'DELETE', body },
});
}, [ data.id, apiFetch, reason ]);
const onSuccess = useCallback(async() => {
onDeleteSuccess();
queryClient.setQueryData([ QueryKeys.publicTags ], (prevData: PublicTags | undefined) => {
queryClient.setQueryData([ resourceKey('public_tags') ], (prevData: PublicTags | undefined) => {
return prevData?.filter((item) => item.id !== data.id);
});
}, [ queryClient, data, onDeleteSuccess ]);
......
import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React, { useCallback, useState } from 'react';
import type { PublicTags, PublicTag } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import type { PublicTag } from 'types/api/account';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import PublicTagListItem from 'ui/publicTags/PublicTagTable/PublicTagListItem';
import AccountPageDescription from 'ui/shared/AccountPageDescription';
......@@ -25,10 +23,8 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
const deleteModalProps = useDisclosure();
const [ deleteModalData, setDeleteModalData ] = useState<PublicTag>();
const isMobile = useIsMobile();
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ QueryKeys.publicTags ], async() =>
await fetch('/node-api/account/public-tags'));
const { data, isLoading, isError } = useApiQuery('public_tags');
const onDeleteModalClose = useCallback(() => {
setDeleteModalData(undefined);
......
......@@ -13,11 +13,11 @@ import type { FieldError, Path, SubmitHandler } from 'react-hook-form';
import { useForm, useFieldArray } from 'react-hook-form';
import type { PublicTags, PublicTag, PublicTagNew, PublicTagErrors } from 'types/api/account';
import { QueryKeys } from 'types/client/accountQueries';
import type { ResourceErrorAccount } from 'lib/api/resources';
import { resourceKey } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import getErrorMessage from 'lib/getErrorMessage';
import type { ErrorType } from 'lib/hooks/useFetch';
import useFetch from 'lib/hooks/useFetch';
import { EMAIL_REGEXP } from 'lib/validations/email';
import FormSubmitAlert from 'ui/shared/FormSubmitAlert';
......@@ -58,7 +58,7 @@ const ADDRESS_INPUT_BUTTONS_WIDTH = 100;
const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
const queryClient = useQueryClient();
const fetch = useFetch();
const apiFetch = useApiFetch();
const inputSize = { base: 'md', lg: 'lg' };
const { control, handleSubmit, formState: { errors, isValid, isDirty }, setError } = useForm<Inputs>({
......@@ -100,17 +100,20 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
};
if (!data?.id) {
return fetch<PublicTag, PublicTagErrors>('/node-api/account/public-tags', { method: 'POST', body });
return apiFetch('public_tags', { fetchParams: { method: 'POST', body } });
}
return fetch<PublicTag, PublicTagErrors>(`/node-api/account/public-tags/${ data.id }`, { method: 'PUT', body });
return apiFetch('public_tags', {
pathParams: { id: String(data.id) },
fetchParams: { method: 'PUT', body },
});
};
const mutation = useMutation(updatePublicTag, {
onSuccess: async(data) => {
const response = data as unknown as PublicTag;
queryClient.setQueryData([ QueryKeys.publicTags ], (prevData: PublicTags | undefined) => {
queryClient.setQueryData([ resourceKey('public_tags') ], (prevData: PublicTags | undefined) => {
const isExisting = prevData && prevData.some((item) => item.id === response.id);
if (isExisting) {
......@@ -128,13 +131,14 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
changeToDataScreen(true);
},
onError: (e: ErrorType<PublicTagErrors>) => {
if (e.error?.full_name || e.error?.email || e.error?.tags || e.error?.addresses || e.error?.additional_comment) {
e.error?.full_name && setError('fullName', { type: 'custom', message: getErrorMessage(e.error, 'full_name') });
e.error?.email && setError('email', { type: 'custom', message: getErrorMessage(e.error, 'email') });
e.error?.tags && setError('tags', { type: 'custom', message: getErrorMessage(e.error, 'tags') });
e.error?.addresses && setError('addresses.0.address', { type: 'custom', message: getErrorMessage(e.error, 'addresses') });
e.error?.additional_comment && setError('comment', { type: 'custom', message: getErrorMessage(e.error, 'additional_comment') });
onError: (error: ResourceErrorAccount<PublicTagErrors>) => {
const errorMap = error.payload?.errors;
if (errorMap?.full_name || errorMap?.email || errorMap?.tags || errorMap?.addresses || errorMap?.additional_comment) {
errorMap?.full_name && setError('fullName', { type: 'custom', message: getErrorMessage(errorMap, 'full_name') });
errorMap?.email && setError('email', { type: 'custom', message: getErrorMessage(errorMap, 'email') });
errorMap?.tags && setError('tags', { type: 'custom', message: getErrorMessage(errorMap, 'tags') });
errorMap?.addresses && setError('addresses.0.address', { type: 'custom', message: getErrorMessage(errorMap, 'addresses') });
errorMap?.additional_comment && setError('comment', { type: 'custom', message: getErrorMessage(errorMap, 'additional_comment') });
} else {
setAlertVisible(true);
}
......
......@@ -12,7 +12,7 @@ import { useForm, Controller } from 'react-hook-form';
import type { WatchlistErrors } from 'types/api/account';
import type { TWatchlistItem } from 'types/client/account';
import type { ResourceError } from 'lib/api/resources';
import type { ResourceErrorAccount } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
import getErrorMessage from 'lib/getErrorMessage';
import { ADDRESS_REGEXP } from 'lib/validations/address';
......@@ -112,7 +112,7 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd
await onSuccess();
setPending(false);
},
onError: (error: ResourceError<{errors: WatchlistErrors}>) => {
onError: (error: ResourceErrorAccount<WatchlistErrors>) => {
setPending(false);
const errorMap = error.payload?.errors;
if (errorMap?.address_hash || errorMap?.name) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment