216 lines
7.9 KiB
TypeScript
216 lines
7.9 KiB
TypeScript
import React from 'react';
|
|
|
|
export type StatusType = 'product' | 'order' | 'user' | 'discount' | 'comment' | 'generic';
|
|
|
|
export type ProductStatus = 'active' | 'inactive' | 'draft';
|
|
export type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
|
|
export type UserStatus = 'verified' | 'unverified' | boolean;
|
|
export type DiscountStatus = 'active' | 'inactive';
|
|
export type CommentStatus = 'approved' | 'rejected' | 'pending';
|
|
|
|
export type StatusValue = ProductStatus | OrderStatus | UserStatus | DiscountStatus | CommentStatus | string;
|
|
|
|
interface StatusBadgeProps {
|
|
status: StatusValue;
|
|
type?: StatusType;
|
|
className?: string;
|
|
size?: 'sm' | 'md' | 'lg';
|
|
}
|
|
|
|
const getStatusConfig = (status: StatusValue, type?: StatusType) => {
|
|
// Handle boolean status (for verified/unverified)
|
|
if (typeof status === 'boolean') {
|
|
return {
|
|
color: status
|
|
? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'
|
|
: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
text: status ? 'تأیید شده' : 'تأیید نشده',
|
|
};
|
|
}
|
|
|
|
const statusStr = String(status).toLowerCase();
|
|
|
|
switch (type) {
|
|
case 'product':
|
|
switch (statusStr) {
|
|
case 'active':
|
|
return {
|
|
color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
text: 'فعال',
|
|
};
|
|
case 'inactive':
|
|
return {
|
|
color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
text: 'غیرفعال',
|
|
};
|
|
case 'draft':
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: 'پیشنویس',
|
|
};
|
|
default:
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: statusStr,
|
|
};
|
|
}
|
|
|
|
case 'order':
|
|
switch (statusStr) {
|
|
case 'pending':
|
|
return {
|
|
color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
text: 'در انتظار',
|
|
};
|
|
case 'processing':
|
|
return {
|
|
color: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
|
|
text: 'در حال پردازش',
|
|
};
|
|
case 'shipped':
|
|
return {
|
|
color: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200',
|
|
text: 'ارسال شده',
|
|
};
|
|
case 'delivered':
|
|
return {
|
|
color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
text: 'تحویل شده',
|
|
};
|
|
case 'cancelled':
|
|
return {
|
|
color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
text: 'لغو شده',
|
|
};
|
|
case 'refunded':
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: 'مرجوع شده',
|
|
};
|
|
default:
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: statusStr,
|
|
};
|
|
}
|
|
|
|
case 'user':
|
|
switch (statusStr) {
|
|
case 'verified':
|
|
case 'true':
|
|
return {
|
|
color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
text: 'تأیید شده',
|
|
};
|
|
case 'unverified':
|
|
case 'false':
|
|
return {
|
|
color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
text: 'تأیید نشده',
|
|
};
|
|
default:
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: statusStr,
|
|
};
|
|
}
|
|
|
|
case 'discount':
|
|
switch (statusStr) {
|
|
case 'active':
|
|
return {
|
|
color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
text: 'فعال',
|
|
};
|
|
case 'inactive':
|
|
return {
|
|
color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
text: 'غیرفعال',
|
|
};
|
|
default:
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: statusStr,
|
|
};
|
|
}
|
|
|
|
case 'comment':
|
|
switch (statusStr) {
|
|
case 'approved':
|
|
return {
|
|
color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
text: 'تأیید شده',
|
|
};
|
|
case 'rejected':
|
|
return {
|
|
color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
text: 'رد شده',
|
|
};
|
|
case 'pending':
|
|
return {
|
|
color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
text: 'در انتظار',
|
|
};
|
|
default:
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: statusStr,
|
|
};
|
|
}
|
|
|
|
default:
|
|
// Generic status handling
|
|
switch (statusStr) {
|
|
case 'active':
|
|
case 'true':
|
|
return {
|
|
color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
text: 'فعال',
|
|
};
|
|
case 'inactive':
|
|
case 'false':
|
|
return {
|
|
color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
text: 'غیرفعال',
|
|
};
|
|
default:
|
|
return {
|
|
color: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200',
|
|
text: statusStr,
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
const getSizeClasses = (size: 'sm' | 'md' | 'lg') => {
|
|
switch (size) {
|
|
case 'sm':
|
|
return 'px-2 py-0.5 text-xs';
|
|
case 'md':
|
|
return 'px-2.5 py-0.5 text-xs';
|
|
case 'lg':
|
|
return 'px-3 py-1 text-sm';
|
|
default:
|
|
return 'px-2.5 py-0.5 text-xs';
|
|
}
|
|
};
|
|
|
|
export const StatusBadge: React.FC<StatusBadgeProps> = ({
|
|
status,
|
|
type = 'generic',
|
|
className = '',
|
|
size = 'md',
|
|
}) => {
|
|
const config = getStatusConfig(status, type);
|
|
const sizeClasses = getSizeClasses(size);
|
|
|
|
return (
|
|
<span
|
|
className={`inline-flex items-center rounded-full font-medium ${config.color} ${sizeClasses} ${className}`}
|
|
>
|
|
{config.text}
|
|
</span>
|
|
);
|
|
};
|
|
|