feat: add getNotificationDetail API function and integrate it into DetailNotification component for enhanced notification handling
This commit is contained in:
@@ -18,4 +18,13 @@ const getNotificationById = async (id) => {
|
|||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getAllNotification, getNotificationById };
|
const getNotificationDetail = async (id) => {
|
||||||
|
const response = await SendRequest({
|
||||||
|
method: 'get',
|
||||||
|
prefix: `notification/${id}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getAllNotification, getNotificationById, getNotificationDetail };
|
||||||
|
|||||||
@@ -26,38 +26,46 @@ import {
|
|||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
// Path disesuaikan karena lokasi file berubah
|
import { getNotificationDetail } from '../../api/notification';
|
||||||
// import { getNotificationById } from '../../api/notification'; // Dihapus karena belum ada di file API
|
|
||||||
import UserHistoryModal from '../notification/component/UserHistoryModal';
|
import UserHistoryModal from '../notification/component/UserHistoryModal';
|
||||||
import LogHistoryCard from '../notification/component/LogHistoryCard'; // Ganti LogHistoryModal dengan LogHistoryCard
|
import LogHistoryCard from '../notification/component/LogHistoryCard';
|
||||||
|
|
||||||
const { Content } = Layout;
|
const { Content } = Layout;
|
||||||
const { Text, Paragraph, Link } = Typography;
|
const { Text, Paragraph, Link } = Typography;
|
||||||
|
|
||||||
// Menggunakan kembali fungsi transform dari ListNotification untuk konsistensi data
|
// Transform API response to component format
|
||||||
const transformNotificationData = (item) => ({
|
const transformNotificationData = (apiData) => {
|
||||||
id: `notification-${item.notification_error_id || 'dummy'}-0`,
|
// Extract nested data
|
||||||
type: item.is_read ? 'resolved' : item.is_delivered ? 'warning' : 'critical',
|
const errorCodeData = apiData.error_code;
|
||||||
title: item.device_name || 'Unknown Device',
|
const solutionData = errorCodeData?.solution?.[0] || {};
|
||||||
issue: item.error_code_name || 'Unknown Error',
|
|
||||||
description: `${item.error_code} - ${item.error_code_name}`,
|
|
||||||
timestamp: new Date(item.created_at || Date.now()).toLocaleString('id-ID'),
|
|
||||||
location: item.device_location || 'Location not specified',
|
|
||||||
details: item.message_error_issue || 'No details available',
|
|
||||||
link: '#',
|
|
||||||
subsection: item.solution_name || 'N/A',
|
|
||||||
isRead: item.is_read || false,
|
|
||||||
status: item.is_read ? 'Resolved' : item.is_delivered ? 'Delivered' : 'Pending',
|
|
||||||
tag: item.error_code,
|
|
||||||
plc: item.plc || 'N/A',
|
|
||||||
});
|
|
||||||
|
|
||||||
const getDummyNotificationById = (id) => {
|
return {
|
||||||
console.log("Fetching dummy data for ID:", id);
|
id: `notification-${apiData.notification_error_id}-0`,
|
||||||
// Data mentah dummy, seolah-olah dari API
|
type: apiData.is_read ? 'resolved' : apiData.is_delivered ? 'warning' : 'critical',
|
||||||
const rawDummyData = { device_name: 'Compressor C-101', error_code_name: 'High Temperature', error_code: 'TEMP-H-303', device_location: 'Gudang Produksi A', message_error_issue: 'Suhu kompresor terdeteksi melebihi ambang batas aman.', is_delivered: true, plc: 'PLC-UTL-01' };
|
title: errorCodeData?.error_code_name || 'Unknown Device',
|
||||||
// Mengolah data mentah dummy menggunakan transform function
|
issue: errorCodeData?.error_code || 'Unknown Error',
|
||||||
return transformNotificationData(rawDummyData);
|
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' : 'N/A',
|
||||||
|
location: solutionData?.solution_name || 'Location not specified',
|
||||||
|
details: apiData.message_error_issue || 'No details available',
|
||||||
|
isRead: apiData.is_read || false,
|
||||||
|
isDelivered: apiData.is_delivered || false,
|
||||||
|
isSend: apiData.is_send || false,
|
||||||
|
status: apiData.is_read ? 'Resolved' : apiData.is_delivered ? 'Delivered' : 'Pending',
|
||||||
|
tag: errorCodeData?.error_code,
|
||||||
|
plc: 'N/A', // PLC not available in API response
|
||||||
|
notification_error_id: apiData.notification_error_id,
|
||||||
|
error_code_id: apiData.error_code_id,
|
||||||
|
spareparts: errorCodeData?.spareparts || [],
|
||||||
|
solution: solutionData, // Include the solution data
|
||||||
|
error_code: errorCodeData,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getIconAndColor = (type) => {
|
const getIconAndColor = (type) => {
|
||||||
@@ -116,20 +124,20 @@ const DetailNotificationTab = () => {
|
|||||||
const fetchDetail = async () => {
|
const fetchDetail = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
// Ganti dengan fungsi API asli Anda
|
|
||||||
// const response = await getNotificationById(notificationId);
|
// Fetch using the actual API
|
||||||
// setNotification(response.data);
|
const response = await getNotificationDetail(notificationId);
|
||||||
|
|
||||||
// Menggunakan data dummy untuk sekarang
|
if (response && response.data) {
|
||||||
const dummyData = getDummyNotificationById(notificationId);
|
const transformedData = transformNotificationData(response.data);
|
||||||
if (dummyData) {
|
setNotification(transformedData);
|
||||||
setNotification(dummyData);
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Notification not found');
|
throw new Error('Notification not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
|
console.error('Error fetching notification detail:', err);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -210,9 +218,9 @@ const DetailNotificationTab = () => {
|
|||||||
</Row>
|
</Row>
|
||||||
<div>
|
<div>
|
||||||
<Text strong>Plant Subsection</Text>
|
<Text strong>Plant Subsection</Text>
|
||||||
<div>{notification.subsection}</div>
|
<div>{notification.location}</div>
|
||||||
<Text strong style={{ display: 'block', marginTop: '8px' }}>Time</Text>
|
<Text strong style={{ display: 'block', marginTop: '8px' }}>Time</Text>
|
||||||
<div>{notification.timestamp}</div>
|
<div>{notification.timestamp.split(' ')[1]} WIB</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ border: '1px solid #d4380d', borderRadius: '4px', padding: '8px', background: 'linear-gradient(to right, #ffe7e6, #ffffff)' }}>
|
<div style={{ border: '1px solid #d4380d', borderRadius: '4px', padding: '8px', background: 'linear-gradient(to right, #ffe7e6, #ffffff)' }}>
|
||||||
<Row justify="space-around" align="middle">
|
<Row justify="space-around" align="middle">
|
||||||
@@ -240,7 +248,7 @@ const DetailNotificationTab = () => {
|
|||||||
<LogHistoryCard notificationData={notification} />
|
<LogHistoryCard notificationData={notification} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
<Col xs={24} md={8}><Card hoverable bodyStyle={{ padding: '12px', textAlign: 'center' }}><Space><BookOutlined style={{ fontSize: '16px', color: '#1890ff' }} /><Text strong style={{ fontSize: '16px', color: '#262626' }}>Handling Guideline</Text></Space></Card></Col>
|
<Col xs={24} md={8}><Card hoverable bodyStyle={{ padding: '12px', textAlign: 'center' }}><Space><BookOutlined style={{ fontSize: '16px', color: '#1890ff' }} /><Text strong style={{ fontSize: '16px', color: '#262626' }}>Handling Guideline</Text></Space></Card></Col>
|
||||||
<Col xs={24} md={8}><Card hoverable bodyStyle={{ padding: '12px', textAlign: 'center' }}><Space><ToolOutlined style={{ fontSize: '16px', color: '#1890ff' }} /><Text strong style={{ fontSize: '16px', color: '#262626' }}>Spare Part</Text></Space></Card></Col>
|
<Col xs={24} md={8}><Card hoverable bodyStyle={{ padding: '12px', textAlign: 'center' }}><Space><ToolOutlined style={{ fontSize: '16px', color: '#1890ff' }} /><Text strong style={{ fontSize: '16px', color: '#262626' }}>Spare Part</Text></Space></Card></Col>
|
||||||
@@ -251,34 +259,80 @@ const DetailNotificationTab = () => {
|
|||||||
<Col xs={24} md={8}>
|
<Col xs={24} md={8}>
|
||||||
<Card size="small" title="Guideline Documents" style={{ height: '100%' }}>
|
<Card size="small" title="Guideline Documents" style={{ height: '100%' }}>
|
||||||
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
||||||
<Card size="small" hoverable>
|
{notification.solution && (
|
||||||
<Text><FilePdfOutlined style={{ marginRight: '8px' }} /> Error 303.pdf</Text>
|
<>
|
||||||
<Link href="#" target="_blank" style={{ fontSize: '12px', display: 'block', marginLeft: '24px' }}>lihat disini</Link>
|
{notification.solution.path_document ? (
|
||||||
</Card>
|
<Card size="small" bodyStyle={{ padding: '8px 12px' }} hoverable extra={<Text type="secondary" style={{ fontSize: '10px' }}>PDF</Text>}>
|
||||||
<Card size="small" hoverable>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<Text><FilePdfOutlined style={{ marginRight: '8px' }} /> SOP Kompresor.pdf</Text>
|
<div>
|
||||||
<Link href="#" target="_blank" style={{ fontSize: '12px', display: 'block', marginLeft: '24px' }}>lihat disini</Link>
|
<Text style={{ fontSize: '12px', color: '#262626' }}><FilePdfOutlined style={{ marginRight: '8px' }} /> {notification.solution.file_upload_name || 'Solution Document.pdf'}</Text>
|
||||||
</Card>
|
<Link href={notification.solution.path_document} target="_blank" style={{ fontSize: '12px', display: 'block' }}>lihat disini</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
) : null}
|
||||||
|
{notification.solution.type_solution === 'text' && notification.solution.text_solution ? (
|
||||||
|
<Card size="small" bodyStyle={{ padding: '8px 12px' }} extra={<Text type="secondary" style={{ fontSize: '10px' }}>{notification.solution.type_solution.toUpperCase()}</Text>}>
|
||||||
|
<Paragraph style={{ fontSize: '12px', margin: 0 }}>
|
||||||
|
<Text strong>{notification.issue}:</Text> {notification.solution.text_solution}
|
||||||
|
</Paragraph>
|
||||||
|
</Card>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!notification.solution && (
|
||||||
|
<div style={{ textAlign: 'center', padding: '20px', color: '#8c8c8c' }}>
|
||||||
|
Tidak ada dokumen solusi tersedia
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} md={8}>
|
<Col xs={24} md={8}>
|
||||||
<Card size="small" title="Required Spare Parts" style={{ height: '100%' }}>
|
<Card size="small" title="Required Spare Parts" style={{ height: '100%' }}>
|
||||||
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
||||||
<Card size="small">
|
{notification.spareparts && notification.spareparts.length > 0 ? (
|
||||||
<Row gutter={16} align="top">
|
notification.spareparts.map((sparepart, index) => (
|
||||||
<Col span={7} style={{ textAlign: 'center' }}>
|
<Card size="small" key={index} bodyStyle={{ padding: '12px' }} hoverable>
|
||||||
<div style={{ width: '100%', height: '60px', backgroundColor: '#f0f0f0', display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: '4px', marginBottom: '8px' }}>
|
<Row gutter={16} align="top">
|
||||||
<ToolOutlined style={{ fontSize: '24px', color: '#bfbfbf' }} />
|
<Col span={7} style={{ textAlign: 'center' }}>
|
||||||
</div>
|
<div style={{ width: '100%', height: '60px', backgroundColor: '#f0f0f0', display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: '4px', marginBottom: '8px' }}>
|
||||||
<Text style={{ fontSize: '12px', color: '#52c41a', fontWeight: 500 }}>Available</Text>
|
<ToolOutlined style={{ fontSize: '24px', color: '#bfbfbf' }} />
|
||||||
</Col>
|
</div>
|
||||||
<Col span={17}>
|
<Text style={{
|
||||||
<Text strong>Air Filter</Text>
|
fontSize: '12px',
|
||||||
<Paragraph style={{ fontSize: '12px', margin: 0, color: '#595959' }}>Filters incoming air to remove dust.</Paragraph>
|
color: sparepart.sparepart_stok === 'Available' || sparepart.sparepart_stok === 'available' ? '#52c41a' : '#ff4d4f',
|
||||||
</Col>
|
fontWeight: 500
|
||||||
</Row>
|
}}>
|
||||||
</Card>
|
{sparepart.sparepart_stok}
|
||||||
|
</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={17}>
|
||||||
|
<Space direction="vertical" size={4} style={{ width: '100%' }}>
|
||||||
|
<Text strong>{sparepart.sparepart_name}</Text>
|
||||||
|
<Paragraph style={{ fontSize: '12px', margin: 0, color: '#595959' }}>
|
||||||
|
{sparepart.sparepart_description || 'Deskripsi tidak tersedia'}
|
||||||
|
</Paragraph>
|
||||||
|
<div style={{
|
||||||
|
border: '1px solid #d9d9d9',
|
||||||
|
borderRadius: '4px',
|
||||||
|
padding: '4px 8px',
|
||||||
|
fontSize: '11px',
|
||||||
|
color: '#8c8c8c',
|
||||||
|
marginTop: '8px'
|
||||||
|
}}>
|
||||||
|
Kode: {sparepart.sparepart_code} | Qty: {sparepart.sparepart_qty} | Unit: {sparepart.sparepart_unit}
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div style={{ textAlign: 'center', padding: '20px', color: '#8c8c8c' }}>
|
||||||
|
Tidak ada spare parts terkait
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
import { Row, Col, Tag, Card, Button } from 'antd';
|
import { Row, Col, Tag, Card, Button } from 'antd';
|
||||||
import { CloseCircleFilled, WarningFilled, CheckCircleFilled, InfoCircleFilled } from '@ant-design/icons';
|
import {
|
||||||
|
CloseCircleFilled,
|
||||||
|
WarningFilled,
|
||||||
|
CheckCircleFilled,
|
||||||
|
InfoCircleFilled,
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
|
||||||
const DetailNotification = memo(function DetailNotification({ selectedData, onClose }) {
|
const DetailNotification = memo(function DetailNotification({ selectedData, onClose }) {
|
||||||
if (!selectedData) {
|
if (!selectedData) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get error code data from the nested structure
|
||||||
|
const errorCodeData = selectedData.error_code;
|
||||||
|
const solutionData = errorCodeData?.solution?.[0] || {};
|
||||||
|
const sparepartsData = errorCodeData?.spareparts || [];
|
||||||
|
|
||||||
|
// Determine notification type based on is_read status
|
||||||
|
const getTypeFromStatus = () => {
|
||||||
|
if (selectedData.is_read === false) return 'critical'; // Not read yet
|
||||||
|
if (selectedData.is_delivered === false) return 'warning'; // Not delivered
|
||||||
|
return 'resolved'; // Read and delivered
|
||||||
|
};
|
||||||
|
|
||||||
const getIconAndColor = (type) => {
|
const getIconAndColor = (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'critical':
|
case 'critical':
|
||||||
@@ -40,7 +57,8 @@ const DetailNotification = memo(function DetailNotification({ selectedData, onCl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { IconComponent, color, bgColor, tagColor } = getIconAndColor(selectedData.type);
|
const notificationType = getTypeFromStatus();
|
||||||
|
const { IconComponent, color, bgColor, tagColor } = getIconAndColor(notificationType);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
@@ -80,10 +98,10 @@ const DetailNotification = memo(function DetailNotification({ selectedData, onCl
|
|||||||
</div>
|
</div>
|
||||||
<div style={{ flex: 1 }}>
|
<div style={{ flex: 1 }}>
|
||||||
<Tag color={tagColor} style={{ marginBottom: '2px', fontSize: '11px' }}>
|
<Tag color={tagColor} style={{ marginBottom: '2px', fontSize: '11px' }}>
|
||||||
{selectedData.type.toUpperCase()}
|
{notificationType.toUpperCase()}
|
||||||
</Tag>
|
</Tag>
|
||||||
<div style={{ fontSize: '14px', fontWeight: 600, color: '#262626' }}>
|
<div style={{ fontSize: '14px', fontWeight: 600, color: '#262626' }}>
|
||||||
{selectedData.title}
|
{errorCodeData?.error_code_name || 'N/A'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -93,18 +111,20 @@ const DetailNotification = memo(function DetailNotification({ selectedData, onCl
|
|||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<div style={{ marginBottom: '2px' }}>
|
<div style={{ marginBottom: '2px' }}>
|
||||||
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
PLC
|
Kode Error
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
||||||
{selectedData.plc}
|
{errorCodeData?.error_code || 'N/A'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<div style={{ marginBottom: '2px' }}>
|
<div style={{ marginBottom: '2px' }}>
|
||||||
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>Tag</div>
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
|
ID Notifikasi
|
||||||
|
</div>
|
||||||
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
||||||
{selectedData.tag}
|
{selectedData.notification_error_id || 'N/A'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
@@ -114,48 +134,115 @@ const DetailNotification = memo(function DetailNotification({ selectedData, onCl
|
|||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<div style={{ marginBottom: '2px' }}>
|
<div style={{ marginBottom: '2px' }}>
|
||||||
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
Engineer
|
Solusi
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
||||||
{selectedData.engineer}
|
{solutionData?.solution_name || 'N/A'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<div style={{ marginBottom: '2px' }}>
|
<div style={{ marginBottom: '2px' }}>
|
||||||
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
Waktu
|
Waktu Dibuat
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
<div style={{ fontSize: '13px', color: '#262626', fontWeight: 500 }}>
|
||||||
{selectedData.time}
|
{selectedData.created_at
|
||||||
|
? new Date(selectedData.created_at).toLocaleString('id-ID', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
}) + ' WIB'
|
||||||
|
: 'N/A'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{/* Status */}
|
{/* Status Information */}
|
||||||
<div style={{ marginBottom: '2px' }}>
|
<Row gutter={[16, 0]}>
|
||||||
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '2px' }}>Status</div>
|
<Col span={8}>
|
||||||
<Tag color={selectedData.isRead ? 'default' : 'blue'}>
|
<div style={{ marginBottom: '2px' }}>
|
||||||
{selectedData.isRead ? 'Sudah Dibaca' : 'Belum Dibaca'}
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
</Tag>
|
Status Kirim
|
||||||
</div>
|
</div>
|
||||||
|
<Tag color={selectedData.is_send ? 'success' : 'error'}>
|
||||||
|
{selectedData.is_send ? 'Terkirim' : 'Belum Terkirim'}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<div style={{ marginBottom: '2px' }}>
|
||||||
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
|
Status Terkirim
|
||||||
|
</div>
|
||||||
|
<Tag color={selectedData.is_delivered ? 'success' : 'warning'}>
|
||||||
|
{selectedData.is_delivered ? 'Terkirim' : 'Belum Terkirim'}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<div style={{ marginBottom: '2px' }}>
|
||||||
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '0' }}>
|
||||||
|
Status Baca
|
||||||
|
</div>
|
||||||
|
<Tag color={selectedData.is_read ? 'success' : 'processing'}>
|
||||||
|
{selectedData.is_read ? 'Dibaca' : 'Belum Dibaca'}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
{/* Additional Info */}
|
{/* Description */}
|
||||||
<div
|
<div style={{ marginTop: '16px', marginBottom: '8px' }}>
|
||||||
style={{
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '4px' }}>
|
||||||
marginTop: '0',
|
Deskripsi Error
|
||||||
padding: '4px',
|
</div>
|
||||||
backgroundColor: '#f6f9ff',
|
<div
|
||||||
borderRadius: '6px',
|
style={{
|
||||||
border: '1px solid #d6e4ff',
|
fontSize: '13px',
|
||||||
}}
|
color: '#262626',
|
||||||
>
|
fontWeight: 500,
|
||||||
<div style={{ fontSize: '11px', color: '#595959' }}>
|
padding: '8px',
|
||||||
<strong>Catatan:</strong> Notifikasi ini telah dikirim ke engineer yang bersangkutan
|
backgroundColor: '#fafafa',
|
||||||
untuk ditindaklanjuti sesuai dengan prosedur yang berlaku.
|
borderRadius: '4px',
|
||||||
|
border: '1px solid #f0f0f0',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedData.message_error_issue || 'N/A'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Spareparts Information */}
|
||||||
|
{sparepartsData.length > 0 && (
|
||||||
|
<div style={{ marginTop: '16px' }}>
|
||||||
|
<div style={{ fontSize: '11px', color: '#8c8c8c', marginBottom: '4px' }}>
|
||||||
|
Spareparts Terkait
|
||||||
|
</div>
|
||||||
|
{sparepartsData.map((sparepart, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
style={{
|
||||||
|
padding: '8px',
|
||||||
|
marginBottom: '4px',
|
||||||
|
backgroundColor: '#fafafa',
|
||||||
|
borderRadius: '4px',
|
||||||
|
border: '1px solid #f0f0f0',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ fontWeight: 600, marginBottom: '4px' }}>
|
||||||
|
{sparepart.sparepart_name}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: '12px' }}>
|
||||||
|
Kode: {sparepart.sparepart_code} | Stok:{' '}
|
||||||
|
{sparepart.sparepart_stok}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user