211 lines
5.1 KiB
TypeScript
211 lines
5.1 KiB
TypeScript
import React from 'react';
|
|
import { IonIcon } from '@ionic/react';
|
|
import {
|
|
chevronForwardOutline,
|
|
checkmarkCircleOutline,
|
|
timeOutline,
|
|
closeCircleOutline,
|
|
} from 'ionicons/icons';
|
|
|
|
export interface OrderSummary {
|
|
id: string;
|
|
recipientName: string;
|
|
serviceType: string;
|
|
merchantName?: string;
|
|
amount: number;
|
|
amountLabel?: string;
|
|
status: string;
|
|
createdAt: string;
|
|
avatarUrl?: string | null;
|
|
}
|
|
|
|
interface OrderSummaryCardProps {
|
|
order: OrderSummary;
|
|
onClick: (id: string) => void;
|
|
}
|
|
|
|
const OrderSummaryCard: React.FC<OrderSummaryCardProps> = ({
|
|
order,
|
|
onClick,
|
|
}) => {
|
|
const getStatusDisplay = (status: string) => {
|
|
switch (status) {
|
|
case 'paid':
|
|
return {
|
|
text: 'Paid',
|
|
color: '#3b82f6',
|
|
bg: 'rgba(59,130,246,0.1)',
|
|
icon: checkmarkCircleOutline,
|
|
};
|
|
case 'ready_for_redemption':
|
|
return {
|
|
text: 'Ready',
|
|
color: '#16a34a',
|
|
bg: 'rgba(22,163,74,0.1)',
|
|
icon: checkmarkCircleOutline,
|
|
};
|
|
case 'redeemed':
|
|
return {
|
|
text: 'Redeemed',
|
|
color: '#16a34a',
|
|
bg: 'rgba(22,163,74,0.1)',
|
|
icon: checkmarkCircleOutline,
|
|
};
|
|
case 'delivered':
|
|
return {
|
|
text: 'Delivered',
|
|
color: '#16a34a',
|
|
bg: 'rgba(22,163,74,0.1)',
|
|
icon: checkmarkCircleOutline,
|
|
};
|
|
case 'pending_payment':
|
|
return {
|
|
text: 'Pending',
|
|
color: '#f59e0b',
|
|
bg: 'rgba(245,158,11,0.1)',
|
|
icon: timeOutline,
|
|
};
|
|
case 'failed':
|
|
case 'cancelled':
|
|
return {
|
|
text: 'Failed',
|
|
color: '#ef4444',
|
|
bg: 'rgba(239,68,68,0.1)',
|
|
icon: closeCircleOutline,
|
|
};
|
|
default:
|
|
return {
|
|
text: status,
|
|
color: '#6b7280',
|
|
bg: '#f3f4f6',
|
|
icon: timeOutline,
|
|
};
|
|
}
|
|
};
|
|
|
|
const statusDisplay = getStatusDisplay(order.status);
|
|
|
|
return (
|
|
<div
|
|
onClick={() => onClick(order.id)}
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
backgroundColor: '#ffffff',
|
|
borderRadius: '24px',
|
|
padding: '16px',
|
|
margin: '0 20px 12px',
|
|
gap: '14px',
|
|
cursor: 'pointer',
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
width: '48px',
|
|
height: '48px',
|
|
borderRadius: '16px',
|
|
backgroundColor: 'rgba(109,40,217,0.1)',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
overflow: 'hidden',
|
|
flexShrink: 0,
|
|
}}
|
|
>
|
|
{order.avatarUrl ? (
|
|
<img
|
|
src={order.avatarUrl}
|
|
alt={order.recipientName}
|
|
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
|
/>
|
|
) : (
|
|
<span
|
|
style={{ fontSize: '18px', fontWeight: '700', color: '#6d28d9' }}
|
|
>
|
|
{order.recipientName.charAt(0)}
|
|
</span>
|
|
)}
|
|
</div>
|
|
<div style={{ flex: 1, minWidth: 0 }}>
|
|
<div
|
|
style={{
|
|
fontSize: '15px',
|
|
fontWeight: '700',
|
|
color: '#111827',
|
|
whiteSpace: 'nowrap',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
>
|
|
{order.serviceType} for {order.recipientName}
|
|
</div>
|
|
<div
|
|
style={{
|
|
fontSize: '13px',
|
|
fontWeight: '400',
|
|
color: '#6b7280',
|
|
marginTop: '2px',
|
|
whiteSpace: 'nowrap',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
>
|
|
{order.merchantName || 'Service provider'}
|
|
</div>
|
|
<div
|
|
style={{
|
|
fontSize: '12px',
|
|
fontWeight: '400',
|
|
color: '#9ca3af',
|
|
marginTop: '4px',
|
|
}}
|
|
>
|
|
{new Date(order.createdAt).toLocaleDateString()}
|
|
</div>
|
|
</div>
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'flex-end',
|
|
gap: '6px',
|
|
}}
|
|
>
|
|
<span style={{ fontSize: '15px', fontWeight: '700', color: '#111827' }}>
|
|
{order.amountLabel ?? `${order.amount.toFixed(2)}`}
|
|
</span>
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: '4px',
|
|
backgroundColor: statusDisplay.bg,
|
|
padding: '2px 8px',
|
|
borderRadius: '999px',
|
|
}}
|
|
>
|
|
<span
|
|
style={{
|
|
fontSize: '11px',
|
|
fontWeight: '700',
|
|
color: statusDisplay.color,
|
|
}}
|
|
>
|
|
{statusDisplay.text}
|
|
</span>
|
|
<IonIcon
|
|
icon={statusDisplay.icon}
|
|
style={{ fontSize: '12px', color: statusDisplay.color }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<IonIcon
|
|
icon={chevronForwardOutline}
|
|
style={{ fontSize: '16px', color: '#9ca3af', marginLeft: '4px' }}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default OrderSummaryCard;
|