lavoce #27
@@ -27,4 +27,29 @@ const getNotificationDetail = async (id) => {
|
|||||||
return response.data;
|
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
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
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 {
|
import {
|
||||||
ArrowLeftOutlined,
|
ArrowLeftOutlined,
|
||||||
CloseCircleFilled,
|
CloseCircleFilled,
|
||||||
@@ -14,8 +14,9 @@ import {
|
|||||||
FilePdfOutlined,
|
FilePdfOutlined,
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
|
LoadingOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { getNotificationDetail } from '../../api/notification';
|
import { getNotificationDetail, createNotificationLog, getNotificationLogByNotificationId } from '../../api/notification';
|
||||||
import UserHistoryModal from '../notification/component/UserHistoryModal';
|
import UserHistoryModal from '../notification/component/UserHistoryModal';
|
||||||
import LogHistoryCard from '../notification/component/LogHistoryCard';
|
import LogHistoryCard from '../notification/component/LogHistoryCard';
|
||||||
|
|
||||||
@@ -98,35 +99,77 @@ const NotificationDetailTab = () => {
|
|||||||
const [modalContent, setModalContent] = useState(null); // 'user', atau null
|
const [modalContent, setModalContent] = useState(null); // 'user', atau null
|
||||||
const [isAddingLog, setIsAddingLog] = useState(false);
|
const [isAddingLog, setIsAddingLog] = useState(false);
|
||||||
|
|
||||||
const logHistoryData = [
|
// Log history states
|
||||||
{
|
const [logHistoryData, setLogHistoryData] = useState([]);
|
||||||
id: 1,
|
const [logLoading, setLogLoading] = useState(false);
|
||||||
timestamp: '04-11-2025 11:55 WIB',
|
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: {
|
addedBy: {
|
||||||
name: 'Budi Santoso',
|
name: log.contact_name || 'Unknown',
|
||||||
phone: '081122334455',
|
phone: log.contact_phone || '',
|
||||||
},
|
},
|
||||||
description: 'Suhu sudah coba diturunkan, namun masih belum mencapai treshold aman.',
|
description: log.notification_error_log_description || '',
|
||||||
},
|
}));
|
||||||
{
|
setLogHistoryData(transformedLogs);
|
||||||
id: 2,
|
}
|
||||||
timestamp: '04-11-2025 11:45 WIB',
|
} catch (err) {
|
||||||
addedBy: {
|
console.error('Error fetching log history:', err);
|
||||||
name: 'John Doe',
|
} finally {
|
||||||
phone: '081234567890',
|
setLogLoading(false);
|
||||||
},
|
}
|
||||||
description: 'Suhu sudah coba diturunkan, namun masih belum mencapai treshold aman.',
|
};
|
||||||
},
|
|
||||||
{
|
// Handle submit new log
|
||||||
id: 3,
|
const handleSubmitLog = async () => {
|
||||||
timestamp: '04-11-2025 11:40 WIB',
|
if (!newLogDescription.trim()) {
|
||||||
addedBy: {
|
message.warning('Mohon isi deskripsi log terlebih dahulu');
|
||||||
name: 'Jane Smith',
|
return;
|
||||||
phone: '087654321098',
|
}
|
||||||
},
|
|
||||||
description: 'Suhu sudah coba diturunkan, namun masih belum mencapai treshold aman.',
|
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(() => {
|
useEffect(() => {
|
||||||
const fetchDetail = async () => {
|
const fetchDetail = async () => {
|
||||||
@@ -139,6 +182,9 @@ const NotificationDetailTab = () => {
|
|||||||
if (response && response.data) {
|
if (response && response.data) {
|
||||||
const transformedData = transformNotificationData(response.data);
|
const transformedData = transformNotificationData(response.data);
|
||||||
setNotification(transformedData);
|
setNotification(transformedData);
|
||||||
|
|
||||||
|
// Fetch log history
|
||||||
|
fetchLogHistory(notificationId);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Notification not found');
|
throw new Error('Notification not found');
|
||||||
}
|
}
|
||||||
@@ -343,7 +389,11 @@ const NotificationDetailTab = () => {
|
|||||||
|
|
||||||
{/* Kolom Kanan: Log History */}
|
{/* Kolom Kanan: Log History */}
|
||||||
<Col xs={24} lg={8}>
|
<Col xs={24} lg={8}>
|
||||||
<LogHistoryCard notificationData={notification} />
|
<LogHistoryCard
|
||||||
|
notificationData={notification}
|
||||||
|
logData={logHistoryData}
|
||||||
|
loading={logLoading}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
@@ -671,6 +721,9 @@ const NotificationDetailTab = () => {
|
|||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
rows={2}
|
rows={2}
|
||||||
placeholder="Tuliskan update penanganan di sini..."
|
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'}
|
type={isAddingLog ? 'primary' : 'dashed'}
|
||||||
size="small"
|
size="small"
|
||||||
block
|
block
|
||||||
icon={!isAddingLog && <PlusOutlined />}
|
icon={submitLoading ? <LoadingOutlined /> : (!isAddingLog && <PlusOutlined />)}
|
||||||
onClick={() => setIsAddingLog(!isAddingLog)}
|
onClick={isAddingLog ? handleSubmitLog : () => setIsAddingLog(true)}
|
||||||
|
loading={submitLoading}
|
||||||
|
disabled={submitLoading}
|
||||||
>
|
>
|
||||||
{isAddingLog ? 'Submit Log' : 'Add Log'}
|
{isAddingLog ? 'Submit Log' : 'Add Log'}
|
||||||
</Button>
|
</Button>
|
||||||
|
{isAddingLog && (
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
block
|
||||||
|
onClick={() => {
|
||||||
|
setIsAddingLog(false);
|
||||||
|
setNewLogDescription('');
|
||||||
|
}}
|
||||||
|
disabled={submitLoading}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
{logHistoryData.map((log) => (
|
{logHistoryData.map((log) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user