Files
clinicpro/assets/admin/components/ui/StatusBadge.tsx
T
hamed 357adb1d14 feat: enhance payment status handling and summary in MyPaymentsPage
- Added support for 'partial' payment status in MyPaymentsPage and related components.
- Updated API responses to include 'paid_rials' and 'summary' for invoices.
- Introduced InvoicePaymentStatus service to derive payment status based on actual payments.
- Enhanced tests to cover new payment scenarios including partial payments and payment methods.
- Updated documentation to reflect changes in payment status and API responses.
2026-07-19 10:38:29 +03:30

97 lines
4.1 KiB
TypeScript

import React from 'react';
import type { AppointmentStatus, PaymentStatus, SmsTemplateStatus, SettlementStatus, ClaimStatus, InvoiceListStatus } from '../../types';
type BadgeColor = 'green' | 'amber' | 'red' | 'blue' | 'violet' | 'gray';
const appointmentMap: Record<AppointmentStatus, { color: BadgeColor; label: string }> = {
pending: { color: 'blue', label: 'ثبت شده' },
confirmed: { color: 'green', label: 'قطعی شده' },
following_up: { color: 'amber', label: 'در حال پیگیری' },
salon: { color: 'violet', label: 'سالن' },
completed: { color: 'green', label: 'ویزیت شده' },
cancelled_by_user: { color: 'red', label: 'لغو توسط بیمار' },
cancelled_by_doctor: { color: 'red', label: 'لغو شده' },
no_show: { color: 'gray', label: 'غیبت' },
expired: { color: 'gray', label: 'منقضی' },
};
const paymentMap: Record<PaymentStatus, { color: BadgeColor; label: string }> = {
pending: { color: 'amber', label: 'در انتظار' },
success: { color: 'green', label: 'موفق' },
failed: { color: 'red', label: 'ناموفق' },
canceled: { color: 'red', label: 'لغو شده' },
refunded: { color: 'blue', label: 'استرداد' },
};
const smsMap: Record<SmsTemplateStatus, { color: BadgeColor; label: string }> = {
draft: { color: 'gray', label: 'پیش‌نویس' },
pending: { color: 'amber', label: 'در انتظار تأیید' },
approved: { color: 'green', label: 'تأیید شده' },
rejected: { color: 'red', label: 'رد شده' },
};
const settlementMap: Record<SettlementStatus, { color: BadgeColor; label: string }> = {
pending: { color: 'amber', label: 'در انتظار' },
approved: { color: 'green', label: 'تأیید شده' },
rejected: { color: 'red', label: 'رد شده' },
};
const claimMap: Record<ClaimStatus, { color: BadgeColor; label: string }> = {
pending: { color: 'gray', label: 'در انتظار ارسال' },
submitted: { color: 'blue', label: 'ارسال شده' },
approved: { color: 'amber', label: 'تأیید شده' },
rejected: { color: 'red', label: 'رد شده' },
paid: { color: 'green', label: 'پرداخت شده' },
mixed: { color: 'violet', label: 'وضعیت‌های مختلف' },
};
const invoiceMap: Record<InvoiceListStatus, { color: BadgeColor; label: string }> = {
paid: { color: 'green', label: 'پرداخت شده' },
partial: { color: 'blue', label: 'پرداخت ناقص' },
unsettled: { color: 'amber', label: 'تسویه نشده' },
};
interface Props {
type: 'appointment' | 'payment' | 'sms' | 'settlement' | 'active' | 'claim' | 'invoice';
value: string;
}
export default function StatusBadge({ type, value }: Props) {
let color: BadgeColor = 'gray';
let label = value;
if (type === 'appointment') {
const m = appointmentMap[value as AppointmentStatus];
if (m) { color = m.color; label = m.label; }
} else if (type === 'payment') {
const m = paymentMap[value as PaymentStatus];
if (m) { color = m.color; label = m.label; }
} else if (type === 'sms') {
const m = smsMap[value as SmsTemplateStatus];
if (m) { color = m.color; label = m.label; }
} else if (type === 'settlement') {
const m = settlementMap[value as SettlementStatus];
if (m) { color = m.color; label = m.label; }
} else if (type === 'claim') {
const m = claimMap[value as ClaimStatus];
if (m) { color = m.color; label = m.label; }
} else if (type === 'invoice') {
const m = invoiceMap[value as InvoiceListStatus];
if (m) { color = m.color; label = m.label; }
} else if (type === 'active') {
color = value === 'true' || value === 'active' ? 'green' : 'gray';
label = value === 'true' || value === 'active' ? 'فعال' : 'غیرفعال';
}
return (
<span className={`badge ${color}`}>
<span className="bdot" />
{label}
</span>
);
}
export function ActiveBadge({ active }: { active: boolean }) {
return <StatusBadge type="active" value={active ? 'active' : 'inactive'} />;
}