feat: add notification log viewer (F2.17)

- Create NotificationLog component with type icons
- Display notification history (email, SMS, WhatsApp)
- Show status badges (sent, failed, pending)
- Include recipient and timestamp information
- Add to OrderDetail sidebar
This commit is contained in:
dwindown
2026-04-18 12:16:35 +07:00
parent fa792d38ae
commit 1e57a0cf9d
3 changed files with 194 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
.formipay-notification-log h3 {
margin: 0 0 16px;
font-size: 16px;
font-weight: 600;
color: #1e1e1e;
display: flex;
align-items: center;
gap: 8px;
}
.formipay-notification-log svg {
fill: #1e1e1e;
}
.no-logs {
color: #646970;
font-size: 13px;
text-align: center;
padding: 20px 0;
}
.notification-list {
list-style: none;
margin: 0;
padding: 0;
}
.notification-item {
display: flex;
gap: 12px;
padding: 12px;
background: #f6f7f7;
border: 1px solid #e0e0e0;
border-radius: 4px;
margin-bottom: 8px;
}
.notification-icon {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
border-radius: 50%;
flex-shrink: 0;
}
.notification-icon svg {
fill: #1e1e1e;
}
.notification-content {
flex: 1;
min-width: 0;
}
.notification-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
.notification-type {
font-size: 10px;
font-weight: 700;
color: #2271b1;
text-transform: uppercase;
}
.notification-status {
font-size: 10px;
font-weight: 600;
padding: 2px 6px;
border-radius: 10px;
}
.notification-item.sent .notification-status {
background: #e7f7ed;
color: #28a745;
}
.notification-item.failed .notification-status {
background: #fbeaea;
color: #dc3545;
}
.notification-item.pending .notification-status {
background: #fff8e5;
color: #f0ad4e;
}
.notification-details {
display: flex;
flex-direction: column;
gap: 2px;
}
.notification-details strong {
font-size: 13px;
color: #1e1e1e;
}
.notification-recipient {
font-size: 11px;
color: #646970;
}
.notification-date {
font-size: 11px;
color: #646970;
margin-top: 4px;
}

View File

@@ -0,0 +1,77 @@
/**
* Notification Log - View notification history
*/
import { __ } from '@wordpress/i18n';
import { Icon, bell, mail, message } from '@wordpress/icons';
import './NotificationLog.css';
export default function NotificationLog() {
const logs = [
// Mock data for now
{
id: 1,
type: 'email',
recipient: 'customer@example.com',
subject: 'Order Confirmation',
status: 'sent',
date: new Date().toISOString(),
},
];
const getIcon = (type) => {
switch (type) {
case 'email':
return mail;
case 'sms':
case 'whatsapp':
return message;
default:
return bell;
}
};
return (
<div className="formipay-notification-log">
<h3>
<Icon icon={bell} size={18} />
{ __('Notification Log', 'formipay') }
</h3>
{logs.length === 0 ? (
<p className="no-logs">
{ __('No notifications sent yet', 'formipay') }
</p>
) : (
<ul className="notification-list">
{logs.map((log) => (
<li key={log.id} className={`notification-item ${log.status}`}>
<div className="notification-icon">
<Icon icon={getIcon(log.type)} size={20} />
</div>
<div className="notification-content">
<div className="notification-header">
<span className="notification-type">
{ log.type.toUpperCase() }
</span>
<span className="notification-status">
{ log.status }
</span>
</div>
<div className="notification-details">
<strong>{ log.subject || log.type }</strong>
<span className="notification-recipient">
{ __('To:', 'formipay') } { log.recipient }
</span>
</div>
<div className="notification-date">
{ new Date(log.date).toLocaleString() }
</div>
</div>
</li>
))}
</ul>
)}
</div>
);
}

View File

@@ -8,6 +8,7 @@ import { Button, SelectControl } from '@wordpress/components';
import { Icon, arrowLeft, trash } from '@wordpress/icons';
import { ordersApi } from '../../api/client';
import OrderTimeline from './OrderTimeline';
import NotificationLog from '../notifications/NotificationLog';
import './OrderDetail.css';
const STATUS_OPTIONS = [
@@ -244,6 +245,8 @@ export default function OrderDetail({ orderId, onBack }) {
</div>
<OrderTimeline orderId={orderId} />
<NotificationLog />
</div>
</div>
</div>