feat: Add Store link to admin header and notification activity log
- Add Store link to admin header (visible when customer SPA is enabled) - Add storeUrl and customerSpaEnabled to WNW_CONFIG in Assets.php and StandaloneAdmin.php - Update window.d.ts with new WNW_CONFIG properties - Create ActivityLog.tsx component with search, filters, and pagination - Add /notifications/logs API endpoint to NotificationsController - Update Notifications.tsx to link to activity log page - Add ActivityLog route to App.tsx
This commit is contained in:
@@ -6,15 +6,15 @@ import { formatRelativeOrDate } from '@/lib/dates';
|
||||
import { formatMoney } from '@/lib/currency';
|
||||
import { ArrowLeft, Printer, ExternalLink, Loader2, Ticket, FileText, Pencil, RefreshCw } from 'lucide-react';
|
||||
import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '@/components/ui/select';
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle
|
||||
} from '@/components/ui/alert-dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { showErrorToast, showSuccessToast, getPageLoadErrorMessage } from '@/lib/errorHandling';
|
||||
@@ -67,7 +67,7 @@ export default function OrderShow() {
|
||||
function printInvoice() {
|
||||
triggerPrint('invoice');
|
||||
}
|
||||
|
||||
|
||||
const [showRetryDialog, setShowRetryDialog] = useState(false);
|
||||
const qrRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const q = useQuery({
|
||||
@@ -90,16 +90,16 @@ export default function OrderShow() {
|
||||
onMutate: async (nextStatus) => {
|
||||
// Cancel outgoing refetches
|
||||
await qc.cancelQueries({ queryKey: ['order', id] });
|
||||
|
||||
|
||||
// Snapshot previous value
|
||||
const previous = qc.getQueryData(['order', id]);
|
||||
|
||||
|
||||
// Optimistically update
|
||||
qc.setQueryData(['order', id], (old: any) => ({
|
||||
...old,
|
||||
status: nextStatus,
|
||||
}));
|
||||
|
||||
|
||||
return { previous };
|
||||
},
|
||||
onSuccess: () => {
|
||||
@@ -183,8 +183,8 @@ export default function OrderShow() {
|
||||
useEffect(() => {
|
||||
if (!isPrintMode || !qrRef.current || !order) return;
|
||||
(async () => {
|
||||
try {
|
||||
const mod = await import( 'qrcode' );
|
||||
try {
|
||||
const mod = await import('qrcode');
|
||||
const QR = (mod as any).default || (mod as any);
|
||||
const text = `ORDER:${order.number || id}`;
|
||||
await QR.toCanvas(qrRef.current, text, { width: 128, margin: 1 });
|
||||
@@ -208,9 +208,6 @@ export default function OrderShow() {
|
||||
<button className="border rounded-md px-3 py-2 text-sm flex items-center gap-2 no-print" onClick={printLabel} title={__('Print shipping label')}>
|
||||
<Ticket className="w-4 h-4" /> {__('Label')}
|
||||
</button>
|
||||
<Link className="border rounded-md px-3 py-2 text-sm flex items-center gap-2 no-print" to={`/orders`} title={__('Back to orders list')}>
|
||||
<ExternalLink className="w-4 h-4" /> {__('Orders')}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -232,8 +229,8 @@ export default function OrderShow() {
|
||||
<div className="px-4 py-3 border-b flex items-center justify-between">
|
||||
<div className="font-medium">{__('Summary')}</div>
|
||||
<div className="w-[180px] flex items-center gap-2">
|
||||
<Select
|
||||
value={order.status || ''}
|
||||
<Select
|
||||
value={order.status || ''}
|
||||
onValueChange={(v) => handleStatusChange(v)}
|
||||
disabled={statusMutation.isPending}
|
||||
>
|
||||
@@ -333,9 +330,9 @@ export default function OrderShow() {
|
||||
<div className="opacity-60">{meta.label}</div>
|
||||
<div className="font-medium">
|
||||
{meta.key.includes('url') || meta.key.includes('redirect') ? (
|
||||
<a
|
||||
href={meta.value}
|
||||
target="_blank"
|
||||
<a
|
||||
href={meta.value}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:underline flex items-center gap-1"
|
||||
>
|
||||
@@ -482,7 +479,7 @@ export default function OrderShow() {
|
||||
<div className="flex items-start justify-between mb-6">
|
||||
<div>
|
||||
<div className="text-xl font-semibold">Invoice</div>
|
||||
<div className="opacity-60">Order #{order.number} · {new Date((order.date_ts||0)*1000).toLocaleString()}</div>
|
||||
<div className="opacity-60">Order #{order.number} · {new Date((order.date_ts || 0) * 1000).toLocaleString()}</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="font-medium">{siteTitle}</div>
|
||||
@@ -508,7 +505,7 @@ export default function OrderShow() {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(order.items || []).map((it:any) => (
|
||||
{(order.items || []).map((it: any) => (
|
||||
<tr key={it.id}>
|
||||
<td className="py-1 pr-2">{it.name}</td>
|
||||
<td className="py-1 px-2 text-right">×{it.qty}</td>
|
||||
@@ -542,7 +539,7 @@ export default function OrderShow() {
|
||||
</div>
|
||||
<div className="text-xs opacity-60 mb-1">{__('Items')}</div>
|
||||
<ul className="text-sm list-disc pl-4">
|
||||
{(order.items||[]).map((it:any)=> (
|
||||
{(order.items || []).map((it: any) => (
|
||||
<li key={it.id}>{it.name} ×{it.qty}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user