Compare commits

..

3 Commits

Author SHA1 Message Date
zain94rif
0ffcf4c3c0 fix(color): change design & color for icon notification 2026-01-12 15:35:41 +07:00
zain94rif
c2163cec5e Merge branch 'lavoce' of https://gitea.idetama.id/yogiedigital/cod-fe into lavoce 2026-01-08 17:25:23 +07:00
zain94rif
d5866ceae4 fix(api): search use api 2026-01-08 17:25:17 +07:00
4 changed files with 62 additions and 12 deletions

1
.gitignore vendored
View File

@@ -6,7 +6,6 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
*.config
node_modules node_modules
dist dist

View File

@@ -3,7 +3,7 @@
<system.webServer> <system.webServer>
<rewrite> <rewrite>
<rules> <rules>
<rule name="CallOfDuty"> <rule name="reactViteSypiu">
<match url=".*" /> <match url=".*" />
<conditions logicalGrouping="MatchAll"> <conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />

View File

@@ -82,6 +82,15 @@ const resendChatAllUser = async (notificationId) => {
return response.data; return response.data;
}; };
// Searching
const searchData = async (queryParams) => {
const response = await SendRequest({
method: 'get',
prefix: `notification?criteria=${queryParams}`,
});
return response.data;
};
export { export {
getAllNotification, getAllNotification,
getNotificationById, getNotificationById,
@@ -92,4 +101,5 @@ export {
resendNotificationToUser, resendNotificationToUser,
resendChatByUser, resendChatByUser,
resendChatAllUser, resendChatAllUser,
searchData,
}; };

View File

@@ -36,6 +36,7 @@ import {
PlusOutlined, PlusOutlined,
ExclamationCircleOutlined, ExclamationCircleOutlined,
SearchOutlined, SearchOutlined,
MailFilled,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useNavigate, Link as RouterLink } from 'react-router-dom'; import { useNavigate, Link as RouterLink } from 'react-router-dom';
import { import {
@@ -44,6 +45,7 @@ import {
getNotificationDetail, getNotificationDetail,
resendChatByUser, resendChatByUser,
resendChatAllUser, resendChatAllUser,
searchData,
} from '../../../api/notification'; } from '../../../api/notification';
const { Text, Paragraph, Link: AntdLink } = Typography; const { Text, Paragraph, Link: AntdLink } = Typography;
@@ -54,6 +56,7 @@ const transformNotificationData = (apiData) => {
id: `notification-${item.notification_error_id}-${index}`, // Unique key prefix with array index id: `notification-${item.notification_error_id}-${index}`, // Unique key prefix with array index
type: item.is_read ? 'resolved' : item.is_delivered ? 'warning' : 'critical', type: item.is_read ? 'resolved' : item.is_delivered ? 'warning' : 'critical',
title: item.error_code_name || 'Unknown Error', title: item.error_code_name || 'Unknown Error',
color: item.error_code_color || 'Black',
issue: item.error_code || item.error_code_name || 'Unknown Error', issue: item.error_code || item.error_code_name || 'Unknown Error',
description: `${item.error_code} - ${item.error_code_name || ''}`, description: `${item.error_code} - ${item.error_code_name || ''}`,
timestamp: item.created_at timestamp: item.created_at
@@ -181,13 +184,13 @@ const ListNotification = memo(function ListNotification(props) {
const getIconAndColor = (type) => { const getIconAndColor = (type) => {
switch (type) { switch (type) {
case 'critical': case 'critical':
return { IconComponent: CloseCircleFilled, color: '#ff4d4f', bgColor: '#fff1f0' }; return { IconComponent: MailFilled, color: '#faad14', bgColor: '#fff1f0' };
case 'warning': case 'warning':
return { IconComponent: WarningFilled, color: '#faad14', bgColor: '#fffbe6' }; return { IconComponent: MailFilled, color: '#1890ff', bgColor: '#fffbe6' };
case 'resolved': case 'resolved':
return { IconComponent: CheckCircleFilled, color: '#52c41a', bgColor: '#f6ffed' }; return { IconComponent: MailFilled, color: '#52c41a', bgColor: '#f6ffed' };
default: default:
return { IconComponent: InfoCircleFilled, color: '#1890ff', bgColor: '#e6f7ff' }; return { IconComponent: MailFilled, color: '#1890ff', bgColor: '#e6f7ff' };
} }
}; };
@@ -219,13 +222,49 @@ const ListNotification = memo(function ListNotification(props) {
); );
}; };
const fetchSearch = async (data) => {
setLoading(true);
try {
const response = await searchData(data);
if (response && response.data) {
const transformedData = transformNotificationData(response.data);
setNotifications(transformedData);
// Update pagination with API response or calculate from data
if (response.paging) {
setPagination({
current_page: response.paging.current_page || page,
current_limit: response.paging.current_limit || limit,
total_limit: response.paging.total_limit || transformedData.length,
total_page:
response.paging.total_page || Math.ceil(transformedData.length / limit),
});
} else {
// Fallback: calculate pagination from data
const totalItems = transformedData.length;
setPagination((prev) => ({
...prev,
current_page: page,
current_limit: limit,
total_limit: totalItems,
total_page: Math.ceil(totalItems / limit),
}));
}
}
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
const handleSearch = () => { const handleSearch = () => {
setSearchTerm(searchValue); fetchSearch(searchValue);
}; };
const handleSearchClear = () => { const handleSearchClear = () => {
setSearchValue(''); setSearchValue('');
setSearchTerm(''); fetchSearch('');
}; };
const getUnreadCount = () => notifications.filter((n) => !n.isRead).length; const getUnreadCount = () => notifications.filter((n) => !n.isRead).length;
@@ -383,7 +422,11 @@ const ListNotification = memo(function ListNotification(props) {
<div> <div>
<Text strong>{notification.title}</Text> <Text strong>{notification.title}</Text>
<div style={{ marginTop: '4px' }}> <div style={{ marginTop: '4px' }}>
<Text style={{ color }}> <Text
style={{
color: notification.color,
}}
>
Error Code {notification.issue} Error Code {notification.issue}
</Text> </Text>
</div> </div>
@@ -711,9 +754,7 @@ const ListNotification = memo(function ListNotification(props) {
</Space> </Space>
<div> <div>
<Text strong> <Text strong>{log.addedBy.name}</Text>
{log.addedBy.name}
</Text>
</div> </div>
<div> <div>