build: 444813b5-5daf-49b2-bf1a-7e4caeab4e17
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user