Feature: Add WhatsApp notifications for collection-ready orders
- Implement WhatsApp Business API integration via Meta Cloud API - Add phoneNumber field to Order model for storing customer phone numbers - Update admin order detail page with phone number input for collection orders - Send WhatsApp notification when admin marks order as ready for collection - Add WhatsApp service module with phone number formatting and message sending - Create database migrations for collection-related fields - Add WhatsApp credentials to .env configuration Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
a105fdf660
commit
36cc6dddff
@@ -10,15 +10,17 @@ function formatPrice(cents: number) {
|
||||
return `£${(cents / 100).toFixed(2)}`;
|
||||
}
|
||||
|
||||
function statusLabel(status: string) {
|
||||
if (status === 'PAID') return 'Confirmed';
|
||||
function statusLabel(status: string, trackingNumber?: string | null, collectedByCustomer?: boolean) {
|
||||
if (status === 'DELIVERED') return collectedByCustomer ? 'Collected' : 'Delivered';
|
||||
if (status === 'PAID') return trackingNumber ? 'Dispatched' : 'Awaiting dispatch';
|
||||
if (status === 'FAILED') return 'Failed';
|
||||
if (status === 'PENDING') return 'Waiting payment';
|
||||
return 'Processing';
|
||||
}
|
||||
|
||||
function statusClasses(status: string) {
|
||||
if (status === 'PAID') return 'bg-splash-blue/10 text-splash-blue';
|
||||
function statusClasses(status: string, trackingNumber?: string | null) {
|
||||
if (status === 'DELIVERED') return 'bg-green-500/10 text-green-600';
|
||||
if (status === 'PAID') return trackingNumber ? 'bg-splash-blue/10 text-splash-blue' : 'bg-splash-orange/10 text-splash-orange';
|
||||
if (status === 'FAILED') return 'bg-splash-pink/10 text-splash-pink';
|
||||
return 'bg-splash-orange/10 text-splash-orange';
|
||||
}
|
||||
@@ -114,13 +116,21 @@ export default async function AccountPage() {
|
||||
{new Date(order.createdAt).toLocaleDateString(undefined, { dateStyle: 'medium' })} ·{' '}
|
||||
{order.items.length} item{order.items.length === 1 ? '' : 's'}
|
||||
</p>
|
||||
<span className={`tag-label mt-1 inline-block rounded-full px-3 py-1 ${statusClasses(order.status)}`}>
|
||||
{statusLabel(order.status)}
|
||||
<span className={`tag-label mt-1 inline-block rounded-full px-3 py-1 ${statusClasses(order.status, order.trackingNumber)}`}>
|
||||
{statusLabel(order.status, order.trackingNumber, order.collectedByCustomer)}
|
||||
</span>
|
||||
</div>
|
||||
<span className="font-mono text-sm">{formatPrice(order.total)}</span>
|
||||
</Link>
|
||||
|
||||
{/* Collection Ready Notification */}
|
||||
{order.isCollectionPickup && order.readyForCollection && (
|
||||
<div className="mt-3 border-t border-line pt-3 bg-green-500/5 p-3 rounded border border-green-500/30 text-sm">
|
||||
<p className="text-green-700 font-medium">✓ Your order is ready for collection</p>
|
||||
<p className="text-muted text-xs mt-1">Please come collect your order at your earliest convenience</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tracking Information */}
|
||||
{order.carrier && order.trackingNumber && (
|
||||
<div className="mt-3 border-t border-line pt-3 text-sm">
|
||||
|
||||
Reference in New Issue
Block a user