Feature: Royal Mail tracking integration (hybrid approach)

Add ability to sync shipment tracking data from Royal Mail API:

- Create Royal Mail API service (src/lib/royalmail.ts) to fetch tracking status
- Add sync-tracking endpoint to pull latest status from Royal Mail
- Create SyncRoyalMailButton component for admin panel
- Add 'Sync from Royal Mail' button on order detail page
- Auto-update order status based on Royal Mail tracking status

Admin workflow:
1. Create shipping label in Royal Mail Click & Drop
2. Copy tracking number into tracking form
3. Click 'Sync from Royal Mail' to fetch and update status
4. System maps Royal Mail status to our order status (SHIPPED, DELIVERED, etc)

Uses Royal Mail's public tracking API - no special credentials required.
Supports manual label creation workflow (hybrid approach).
This commit is contained in:
Andymick
2026-07-18 20:36:40 +01:00
parent 440a735b8a
commit c476f92a66
5 changed files with 265 additions and 7 deletions
+23 -6
View File
@@ -1,6 +1,7 @@
import { notFound } from 'next/navigation';
import { prisma } from '@/lib/prisma';
import AdminNav from '@/components/AdminNav';
import SyncRoyalMailButton from '@/components/SyncRoyalMailButton';
import { archiveOrder, unarchiveOrder, updateOrderTracking } from '../actions';
function formatPrice(cents: number) {
@@ -133,13 +134,29 @@ export default async function OrderDetailPage({ params }: { params: { id: string
</div>
</div>
<button
type="submit"
className="bg-clay px-4 py-2 text-sm font-medium text-paper hover:bg-clay-dark"
>
Update Tracking Info
</button>
<div className="flex gap-3">
<button
type="submit"
className="bg-clay px-4 py-2 text-sm font-medium text-paper hover:bg-clay-dark"
>
Update Tracking Info
</button>
</div>
</form>
{order.trackingNumber && (
<div className="mt-4 border-t border-line pt-4">
<p className="tag-label mb-3">Royal Mail Integration</p>
<SyncRoyalMailButton
orderId={order.id}
trackingNumber={order.trackingNumber}
onSuccess={() => {
// In a real app, we'd refresh the page or update state
console.log('Tracking synced successfully');
}}
/>
</div>
)}
</div>
<div className="mt-10 divide-y divide-line border-t border-line">