diff --git a/frontend/src/components/categories/CategoryDialog.tsx b/frontend/src/components/categories/CategoryDialog.tsx index 9aa81e3..053a28a 100644 --- a/frontend/src/components/categories/CategoryDialog.tsx +++ b/frontend/src/components/categories/CategoryDialog.tsx @@ -35,8 +35,9 @@ export const CategoryDialog: FC = ({ const { t } = useTranslation(); const { toast } = useToast(); const { mutateAsync: createCategory } = useCreate(EntityType.CATEGORY, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + console.log(error); + toast.error(error); }, onSuccess: () => { closeDialog(); diff --git a/frontend/src/components/content-types/ContentTypeDialog.tsx b/frontend/src/components/content-types/ContentTypeDialog.tsx index bf914cd..41902c0 100644 --- a/frontend/src/components/content-types/ContentTypeDialog.tsx +++ b/frontend/src/components/content-types/ContentTypeDialog.tsx @@ -50,8 +50,8 @@ export const ContentTypeDialog: FC = ({ const { mutateAsync: createContentType } = useCreate( EntityType.CONTENT_TYPE, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + toast.error(error); }, onSuccess: () => { closeDialog(); diff --git a/frontend/src/components/contents/ContentDialog.tsx b/frontend/src/components/contents/ContentDialog.tsx index 3bf6f08..6cfd303 100644 --- a/frontend/src/components/contents/ContentDialog.tsx +++ b/frontend/src/components/contents/ContentDialog.tsx @@ -178,8 +178,8 @@ export const ContentDialog: FC = ({ createContent( { ...params, entity: contentType.id }, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + toast.error(error); }, onSuccess: () => { closeDialog(); diff --git a/frontend/src/components/context-vars/ContextVarDialog.tsx b/frontend/src/components/context-vars/ContextVarDialog.tsx index 5a39618..5d6499e 100644 --- a/frontend/src/components/context-vars/ContextVarDialog.tsx +++ b/frontend/src/components/context-vars/ContextVarDialog.tsx @@ -35,8 +35,8 @@ export const ContextVarDialog: FC = ({ const { t } = useTranslation(); const { toast } = useToast(); const { mutateAsync: createContextVar } = useCreate(EntityType.CONTEXT_VAR, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + toast.error(error); }, onSuccess() { closeDialog(); diff --git a/frontend/src/components/roles/RoleDialog.tsx b/frontend/src/components/roles/RoleDialog.tsx index 95ea303..86f154f 100644 --- a/frontend/src/components/roles/RoleDialog.tsx +++ b/frontend/src/components/roles/RoleDialog.tsx @@ -34,8 +34,8 @@ export const RoleDialog: FC = ({ const { t } = useTranslation(); const { toast } = useToast(); const { mutateAsync: createRole } = useCreate(EntityType.ROLE, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + toast.error(error); }, onSuccess() { closeDialog(); diff --git a/frontend/src/components/roles/index.tsx b/frontend/src/components/roles/index.tsx index 380728f..c9225c6 100644 --- a/frontend/src/components/roles/index.tsx +++ b/frontend/src/components/roles/index.tsx @@ -57,8 +57,8 @@ export const Roles = () => { }, ); const { mutateAsync: deleteRole } = useDelete(EntityType.ROLE, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + toast.error(error); }, onSuccess() { deleteDialogCtl.closeDialog(); diff --git a/frontend/src/components/translations/index.tsx b/frontend/src/components/translations/index.tsx index 7f44a62..f1651c2 100644 --- a/frontend/src/components/translations/index.tsx +++ b/frontend/src/components/translations/index.tsx @@ -56,8 +56,8 @@ export const Translations = () => { }, ); const { mutateAsync: deleteTranslation } = useDelete(EntityType.TRANSLATION, { - onError: () => { - toast.error(t("message.internal_server_error")); + onError: (error) => { + toast.error(error); }, onSuccess() { deleteDialogCtl.closeDialog(); diff --git a/frontend/src/hooks/useToast.ts b/frontend/src/hooks/useToast.ts index 6e0201b..64bd304 100644 --- a/frontend/src/hooks/useToast.ts +++ b/frontend/src/hooks/useToast.ts @@ -1,18 +1,11 @@ -/* - * Copyright © 2024 Hexastack. All rights reserved. - * - * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: - * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. - * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). - * 3. SaaS Restriction: This software, or any derivative of it, may not be used to offer a competing product or service (SaaS) without prior written consent from Hexastack. Offering the software as a service or using it in a commercial cloud environment without express permission is strictly prohibited. - */ - import { OptionsObject, enqueueSnackbar, SnackbarProvider as ToastProvider, } from "notistack"; +import { useTranslation } from "react-i18next"; + export { ToastProvider }; const TOAST_COMMON_STYLE = { @@ -39,25 +32,39 @@ const TOAST_WARNING_STYLE = { backgroundColor: "#fdf6ec", }; -export const useToast = () => ({ - toast: { - error: (message: string, options?: OptionsObject<"error">) => - enqueueSnackbar(message, { - variant: "error", - ...options, - style: { ...TOAST_ERROR_STYLE, ...options?.style }, - }), - success: (message: string, options?: OptionsObject<"success">) => - enqueueSnackbar(message, { - variant: "success", - ...options, - style: { ...TOAST_SUCCESS_STYLE, ...options?.style }, - }), - warning: (message: string, options?: OptionsObject<"warning">) => - enqueueSnackbar(message, { - variant: "warning", - ...options, - style: { ...TOAST_WARNING_STYLE, ...options?.style }, - }), - }, -}); +export const useToast = () => { + const { t } = useTranslation(); + + const extractErrorMessage = (error: any) => { + if (error?.statusCode == 409) { + return t("message.duplicate_error"); + } + + return error?.message || t("message.internal_server_error"); + }; + + return { + toast: { + error: (error: any, options?: OptionsObject<"error">) => { + const errorMessage = extractErrorMessage(error); + enqueueSnackbar(errorMessage, { + variant: "error", + ...options, + style: { ...TOAST_ERROR_STYLE, ...options?.style }, + }); + }, + success: (message: string, options?: OptionsObject<"success">) => + enqueueSnackbar(message, { + variant: "success", + ...options, + style: { ...TOAST_SUCCESS_STYLE, ...options?.style }, + }), + warning: (message: string, options?: OptionsObject<"warning">) => + enqueueSnackbar(message, { + variant: "warning", + ...options, + style: { ...TOAST_WARNING_STYLE, ...options?.style }, + }), + }, + }; +}; diff --git a/frontend/src/i18n/en/translation.json b/frontend/src/i18n/en/translation.json index fc34769..b1d356f 100644 --- a/frontend/src/i18n/en/translation.json +++ b/frontend/src/i18n/en/translation.json @@ -1,5 +1,6 @@ { "message": { + "duplicate_error": "Duplicate entry. Please choose a unique value.", "bad_request": "400 BAD REQUEST", "unable_to_process_request": "Unable to process request", "not_found": "404 NOT FOUND", diff --git a/frontend/src/i18n/fr/translation.json b/frontend/src/i18n/fr/translation.json index d61fc43..583099c 100644 --- a/frontend/src/i18n/fr/translation.json +++ b/frontend/src/i18n/fr/translation.json @@ -1,5 +1,6 @@ { "message": { + "duplicate_error" : "Entrée en double. Veuillez choisir une valeur unique.", "bad_request": "400 MAUVAISE REQUÊTE", "unable_to_process_request": "Impossible de traiter la requête", "not_found": "404 RESSOURCE INTROUVABLE",