feat: integrate error handling across various components

- Added `useErrorHandler` hook to centralize error handling logic.
- Updated components in the backoffice and portal applications to utilize the new error handling mechanism, replacing direct notify calls with `handleError` for improved error messaging.
- Enhanced localization files to include generic error messages for better user feedback.
- Refactored error handling in forms and API interactions to ensure consistent user experience across the application.
This commit is contained in:
estifanos
2026-07-24 09:08:41 +00:00
parent 4ccf27c044
commit 8f7c163b9e
28 changed files with 229 additions and 121 deletions

View File

@@ -22,7 +22,7 @@ import {
useUpdateLocationTypeMutation,
useDeleteLocationTypeMutation,
} from '../api/location-api';
import { notify } from '@ema-platform/ui';
import { notify, useErrorHandler } from '@ema-platform/ui';
interface LocationTypeFormValues {
code: string;
@@ -34,6 +34,7 @@ interface LocationTypeFormValues {
export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
const { t, i18n } = useTranslation();
const locale = i18n.language as 'en' | 'am';
const { handleError } = useErrorHandler();
const { data: locationTypes, isLoading } = useGetLocationTypesQuery();
const [createType] = useCreateLocationTypeMutation();
const [updateType] = useUpdateLocationTypeMutation();
@@ -84,8 +85,8 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
try {
await deleteType(id).unwrap();
notify.success(t('location.typeDeleted'));
} catch {
notify.error(t('location.deleteError'));
} catch (e) {
handleError(e);
}
};
@@ -99,8 +100,8 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
notify.success(t('location.typeCreated'));
}
resetForm();
} catch {
notify.error(t('location.typeError'));
} catch (e) {
handleError(e);
}
});

View File

@@ -17,7 +17,7 @@ import {
import { useDisclosure } from '@mantine/hooks';
import { IconSettings, IconMap, IconInfoCircle, IconPlus } from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { notify } from '@ema-platform/ui';
import { notify, useErrorHandler } from '@ema-platform/ui';
import { LocationTree } from '../components/LocationTree';
import { LocationDetail } from '../components/LocationDetail';
import { LocationForm } from '../components/LocationForm';
@@ -33,6 +33,7 @@ import type { Location } from '../types/location';
export function LocationPage() {
const { t, i18n } = useTranslation();
const locale = i18n.language as 'en' | 'am';
const { handleError } = useErrorHandler();
const { data: locationTypesRes, isLoading: typesLoading } = useGetLocationTypesQuery();
const [createLocation, { isLoading: isCreating }] = useCreateLocationMutation();
const [updateLocation, { isLoading: isUpdating }] = useUpdateLocationMutation();
@@ -82,11 +83,11 @@ export function LocationPage() {
closeFormModal();
setEditingLocation(null);
setParentLocation(null);
} catch {
notify.error(t('location.error'));
} catch (e) {
handleError(e);
}
},
[editingLocation, createLocation, updateLocation, closeFormModal, t],
[editingLocation, createLocation, updateLocation, closeFormModal, handleError],
);
const handleDeleteConfirm = useCallback(async () => {
@@ -96,10 +97,10 @@ export function LocationPage() {
notify.success(t('location.deleted'));
setSelectedLocation(null);
closeDeleteModal();
} catch {
notify.error(t('location.deleteError'));
} catch (e) {
handleError(e);
}
}, [selectedLocation, deleteLocation, closeDeleteModal, t]);
}, [selectedLocation, deleteLocation, closeDeleteModal, handleError]);
if (typesLoading) {
return (