- Updated UsersPage to fetch users from the new admin endpoint. - Enhanced user data structure to include 'name' and modified rendering logic. - Added RepresentationDetailPage for detailed representation management. - Created AdminApiController to handle user and representation CRUD operations. - Implemented pagination and search functionality for users and representations. - Updated user and representation data models to reflect new API structure.
102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
import React from 'react';
|
|
import type { AppointmentStatus, PaymentStatus, SmsTemplateStatus, SettlementStatus } from '../../types';
|
|
|
|
const variants: Record<string, string> = {
|
|
yellow: 'bg-yellow-100 text-yellow-800',
|
|
blue: 'bg-blue-100 text-blue-800',
|
|
purple: 'bg-purple-100 text-purple-800',
|
|
orange: 'bg-orange-100 text-orange-800',
|
|
indigo: 'bg-indigo-100 text-indigo-800',
|
|
green: 'bg-green-100 text-green-800',
|
|
red: 'bg-red-100 text-red-800',
|
|
gray: 'bg-gray-100 text-gray-700',
|
|
rose: 'bg-rose-100 text-rose-800',
|
|
};
|
|
|
|
const dots: Record<string, string> = {
|
|
yellow: 'bg-yellow-500',
|
|
blue: 'bg-blue-500',
|
|
purple: 'bg-purple-500',
|
|
orange: 'bg-orange-500',
|
|
indigo: 'bg-indigo-500',
|
|
green: 'bg-green-500',
|
|
red: 'bg-red-500',
|
|
gray: 'bg-gray-400',
|
|
rose: 'bg-rose-500',
|
|
};
|
|
|
|
const appointmentMap: Record<AppointmentStatus, { color: string; label: string }> = {
|
|
waiting_for_payment: { color: 'yellow', label: 'در انتظار پرداخت' },
|
|
reserved: { color: 'blue', label: 'رزرو شده' },
|
|
checked_in: { color: 'purple', label: 'ورود به مطب' },
|
|
waiting: { color: 'orange', label: 'در صف انتظار' },
|
|
in_progress: { color: 'indigo', label: 'در حال ویزیت' },
|
|
visited: { color: 'green', label: 'ویزیت شده' },
|
|
completed: { color: 'green', label: 'تکمیل شده' },
|
|
cancelled_by_user: { color: 'red', label: 'لغو توسط بیمار' },
|
|
cancelled_by_doctor: { color: 'red', label: 'لغو توسط پزشک' },
|
|
cancelled_by_admin: { color: 'red', label: 'لغو توسط ادمین' },
|
|
auto_cancel_unpaid: { color: 'gray', label: 'لغو خودکار' },
|
|
no_show: { color: 'rose', label: 'غیبت' },
|
|
};
|
|
|
|
const paymentMap: Record<PaymentStatus, { color: string; label: string }> = {
|
|
pending: { color: 'yellow', label: 'در انتظار' },
|
|
received: { color: 'green', label: 'موفق' },
|
|
canceled: { color: 'red', label: 'لغو شده' },
|
|
refund: { color: 'blue', label: 'استرداد' },
|
|
};
|
|
|
|
const smsMap: Record<SmsTemplateStatus, { color: string; label: string }> = {
|
|
draft: { color: 'gray', label: 'پیشنویس' },
|
|
pending: { color: 'yellow', label: 'در انتظار تأیید' },
|
|
approved: { color: 'green', label: 'تأیید شده' },
|
|
rejected: { color: 'red', label: 'رد شده' },
|
|
};
|
|
|
|
const settlementMap: Record<SettlementStatus, { color: string; label: string }> = {
|
|
pending: { color: 'yellow', label: 'در انتظار' },
|
|
approved: { color: 'green', label: 'تأیید شده' },
|
|
rejected: { color: 'red', label: 'رد شده' },
|
|
};
|
|
|
|
interface Props {
|
|
type: 'appointment' | 'payment' | 'sms' | 'settlement' | 'active';
|
|
value: string;
|
|
}
|
|
|
|
export default function StatusBadge({ type, value }: Props) {
|
|
let color = '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 === 'active') {
|
|
color = value === 'true' || value === 'active' ? 'green' : 'gray';
|
|
label = value === 'true' || value === 'active' ? 'فعال' : 'غیرفعال';
|
|
}
|
|
|
|
return (
|
|
<span className={`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium ${variants[color] ?? variants.gray}`}>
|
|
<span className={`w-1.5 h-1.5 rounded-full ${dots[color] ?? dots.gray}`} />
|
|
{label}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export function ActiveBadge({ active }: { active: boolean }) {
|
|
return (
|
|
<StatusBadge type="active" value={active ? 'active' : 'inactive'} />
|
|
);
|
|
}
|