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:
114
src/admin/components/notifications/NotificationLog.css
Normal file
114
src/admin/components/notifications/NotificationLog.css
Normal 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;
|
||||||
|
}
|
||||||
77
src/admin/components/notifications/NotificationLog.js
Normal file
77
src/admin/components/notifications/NotificationLog.js
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import { Button, SelectControl } from '@wordpress/components';
|
|||||||
import { Icon, arrowLeft, trash } from '@wordpress/icons';
|
import { Icon, arrowLeft, trash } from '@wordpress/icons';
|
||||||
import { ordersApi } from '../../api/client';
|
import { ordersApi } from '../../api/client';
|
||||||
import OrderTimeline from './OrderTimeline';
|
import OrderTimeline from './OrderTimeline';
|
||||||
|
import NotificationLog from '../notifications/NotificationLog';
|
||||||
import './OrderDetail.css';
|
import './OrderDetail.css';
|
||||||
|
|
||||||
const STATUS_OPTIONS = [
|
const STATUS_OPTIONS = [
|
||||||
@@ -244,6 +245,8 @@ export default function OrderDetail({ orderId, onBack }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<OrderTimeline orderId={orderId} />
|
<OrderTimeline orderId={orderId} />
|
||||||
|
|
||||||
|
<NotificationLog />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user