feat: add notification log creation and retrieval functionality

This commit is contained in:
2025-12-22 14:34:14 +07:00
parent d19f555c7c
commit bee196e299
2 changed files with 141 additions and 48 deletions

View File

@@ -27,4 +27,29 @@ const getNotificationDetail = async (id) => {
return response.data;
};
export { getAllNotification, getNotificationById, getNotificationDetail };
// Create new notification log
const createNotificationLog = async (data) => {
const response = await SendRequest({
method: 'post',
prefix: 'notification-log',
params: data,
});
return response.data;
};
// Get notification logs by notification_error_id
const getNotificationLogByNotificationId = async (notificationId) => {
const response = await SendRequest({
method: 'get',
prefix: `notification-log/notification_error/${notificationId}`,
});
return response.data;
};
export {
getAllNotification,
getNotificationById,
getNotificationDetail,
createNotificationLog,
getNotificationLogByNotificationId
};

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Layout, Card, Row, Col, Typography, Space, Button, Spin, Result, Input } from 'antd';
import { Layout, Card, Row, Col, Typography, Space, Button, Spin, Result, Input, message } from 'antd';
import {
ArrowLeftOutlined,
CloseCircleFilled,
@@ -14,8 +14,9 @@ import {
FilePdfOutlined,
PlusOutlined,
UserOutlined,
LoadingOutlined,
} from '@ant-design/icons';
import { getNotificationDetail } from '../../api/notification';
import { getNotificationDetail, createNotificationLog, getNotificationLogByNotificationId } from '../../api/notification';
import UserHistoryModal from '../notification/component/UserHistoryModal';
import LogHistoryCard from '../notification/component/LogHistoryCard';
@@ -38,12 +39,12 @@ const transformNotificationData = (apiData) => {
description: apiData.message_error_issue || 'No details available',
timestamp: apiData.created_at
? new Date(apiData.created_at).toLocaleString('id-ID', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
}) + ' WIB'
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
}) + ' WIB'
: 'N/A',
location: apiData.plant_sub_section_name || 'Location not specified',
details: apiData.message_error_issue || 'No details available',
@@ -61,9 +62,9 @@ const transformNotificationData = (apiData) => {
...activeSolution,
path_document: activeSolution.path_document
? activeSolution.path_document.replace(
'/detail-notification/pdf/',
'/notification-detail/pdf/'
)
'/detail-notification/pdf/',
'/notification-detail/pdf/'
)
: activeSolution.path_document,
}, // Include the active solution data with fixed URL
error_code: errorCodeData,
@@ -98,35 +99,77 @@ const NotificationDetailTab = () => {
const [modalContent, setModalContent] = useState(null); // 'user', atau null
const [isAddingLog, setIsAddingLog] = useState(false);
const logHistoryData = [
{
id: 1,
timestamp: '04-11-2025 11:55 WIB',
addedBy: {
name: 'Budi Santoso',
phone: '081122334455',
},
description: 'Suhu sudah coba diturunkan, namun masih belum mencapai treshold aman.',
},
{
id: 2,
timestamp: '04-11-2025 11:45 WIB',
addedBy: {
name: 'John Doe',
phone: '081234567890',
},
description: 'Suhu sudah coba diturunkan, namun masih belum mencapai treshold aman.',
},
{
id: 3,
timestamp: '04-11-2025 11:40 WIB',
addedBy: {
name: 'Jane Smith',
phone: '087654321098',
},
description: 'Suhu sudah coba diturunkan, namun masih belum mencapai treshold aman.',
},
];
// Log history states
const [logHistoryData, setLogHistoryData] = useState([]);
const [logLoading, setLogLoading] = useState(false);
const [newLogDescription, setNewLogDescription] = useState('');
const [submitLoading, setSubmitLoading] = useState(false);
// Fetch log history from API
const fetchLogHistory = async (notifId) => {
try {
setLogLoading(true);
const response = await getNotificationLogByNotificationId(notifId);
if (response && response.data) {
// Transform API data to component format
const transformedLogs = response.data.map((log) => ({
id: log.notification_error_log_id,
timestamp: log.created_at
? new Date(log.created_at).toLocaleString('id-ID', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
}) + ' WIB'
: 'N/A',
addedBy: {
name: log.contact_name || 'Unknown',
phone: log.contact_phone || '',
},
description: log.notification_error_log_description || '',
}));
setLogHistoryData(transformedLogs);
}
} catch (err) {
console.error('Error fetching log history:', err);
} finally {
setLogLoading(false);
}
};
// Handle submit new log
const handleSubmitLog = async () => {
if (!newLogDescription.trim()) {
message.warning('Mohon isi deskripsi log terlebih dahulu');
return;
}
try {
setSubmitLoading(true);
const payload = {
notification_error_id: parseInt(notificationId),
notification_error_log_description: newLogDescription.trim(),
};
const response = await createNotificationLog(payload);
if (response && response.statusCode === 200) {
message.success('Log berhasil ditambahkan');
setNewLogDescription('');
setIsAddingLog(false);
// Refresh log history
fetchLogHistory(notificationId);
} else {
throw new Error(response?.message || 'Gagal menambahkan log');
}
} catch (err) {
console.error('Error submitting log:', err);
message.error(err.message || 'Gagal menambahkan log');
} finally {
setSubmitLoading(false);
}
};
useEffect(() => {
const fetchDetail = async () => {
@@ -139,6 +182,9 @@ const NotificationDetailTab = () => {
if (response && response.data) {
const transformedData = transformNotificationData(response.data);
setNotification(transformedData);
// Fetch log history
fetchLogHistory(notificationId);
} else {
throw new Error('Notification not found');
}
@@ -343,7 +389,11 @@ const NotificationDetailTab = () => {
{/* Kolom Kanan: Log History */}
<Col xs={24} lg={8}>
<LogHistoryCard notificationData={notification} />
<LogHistoryCard
notificationData={notification}
logData={logHistoryData}
loading={logLoading}
/>
</Col>
</Row>
@@ -408,7 +458,7 @@ const NotificationDetailTab = () => {
style={{ width: '100%' }}
>
{notification.error_code?.solution &&
notification.error_code.solution.length > 0 ? (
notification.error_code.solution.length > 0 ? (
<>
{notification.error_code.solution
.filter((sol) => sol.is_active) // Hanya tampilkan solusi yang aktif
@@ -482,7 +532,7 @@ const NotificationDetailTab = () => {
</Card>
) : null}
{sol.type_solution === 'text' &&
sol.text_solution ? (
sol.text_solution ? (
<Card
size="small"
bodyStyle={{
@@ -543,7 +593,7 @@ const NotificationDetailTab = () => {
style={{ width: '100%' }}
>
{notification.spareparts &&
notification.spareparts.length > 0 ? (
notification.spareparts.length > 0 ? (
notification.spareparts.map((sparepart, index) => (
<Card
size="small"
@@ -581,7 +631,7 @@ const NotificationDetailTab = () => {
color:
sparepart.sparepart_stok ===
'Available' ||
sparepart.sparepart_stok ===
sparepart.sparepart_stok ===
'available'
? '#52c41a'
: '#ff4d4f',
@@ -671,6 +721,9 @@ const NotificationDetailTab = () => {
<Input.TextArea
rows={2}
placeholder="Tuliskan update penanganan di sini..."
value={newLogDescription}
onChange={(e) => setNewLogDescription(e.target.value)}
disabled={submitLoading}
/>
</>
)}
@@ -678,11 +731,26 @@ const NotificationDetailTab = () => {
type={isAddingLog ? 'primary' : 'dashed'}
size="small"
block
icon={!isAddingLog && <PlusOutlined />}
onClick={() => setIsAddingLog(!isAddingLog)}
icon={submitLoading ? <LoadingOutlined /> : (!isAddingLog && <PlusOutlined />)}
onClick={isAddingLog ? handleSubmitLog : () => setIsAddingLog(true)}
loading={submitLoading}
disabled={submitLoading}
>
{isAddingLog ? 'Submit Log' : 'Add Log'}
</Button>
{isAddingLog && (
<Button
size="small"
block
onClick={() => {
setIsAddingLog(false);
setNewLogDescription('');
}}
disabled={submitLoading}
>
Cancel
</Button>
)}
</Space>
</Card>
{logHistoryData.map((log) => (