import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { CheckIcon, SparklesIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import { api } from '../lib/api'; import type { ApiResponse } from '../lib/api'; import type { SubscriptionPlan, MySubscription, SubscriptionPeriod } from '../types'; import { formatDate, formatRial, formatNumber } from '../lib/utils'; import Modal from '../components/ui/Modal'; import PageHeader from '../components/ui/PageHeader'; const PLAN_FEATURE_LABELS: Record = { patient_records: 'پرونده بیمار', services: 'مدیریت سرویس‌ها', sms_panel: 'پنل پیامک', }; const PLAN_DISPLAY: Record = { free: { label: 'رایگان', color: '#64748b' }, basic: { label: 'پایه', color: '#3b82f6' }, professional: { label: 'حرفه‌ای', color: '#8b5cf6' }, }; const GATEWAY_LABELS: Record = { mellat: 'ملت', sep: 'سپ' }; export default function SubscriptionPage() { const qc = useQueryClient(); const [purchaseTarget, setPurchaseTarget] = useState(null); const [selectedGateway, setSelectedGateway] = useState<'mellat' | 'sep'>('mellat'); const { data: plansData, isLoading: plansLoading } = useQuery>({ queryKey: ['subscription-plans'], queryFn: () => api.get('/api/v1/subscription/plans'), }); const { data: myData } = useQuery>({ queryKey: ['subscription-my'], queryFn: () => api.get('/api/v1/subscription/my'), }); const plans = plansData?.data ?? []; const my = myData?.data; const trialMutation = useMutation({ mutationFn: () => api.post('/api/v1/subscription/trial', {}), onSuccess: () => { qc.invalidateQueries({ queryKey: ['subscription-my'] }); toast.success('تریال رایگان با موفقیت فعال شد'); }, onError: (err: any) => toast.error(err.message), }); const purchaseMutation = useMutation({ mutationFn: ({ period_uuid, gateway }: { period_uuid: string; gateway: string }) => api.post<{ data: { payment_url: string } }>('/api/v1/subscription-payment', { period_uuid, gateway }), onSuccess: (res: any) => { const url = res?.data?.payment_url; if (url) window.location.href = url; else toast.error('خطا در دریافت لینک پرداخت'); }, onError: (err: any) => toast.error(err.message), }); const daysTotal = my?.expires_at && my?.starts_at ? Math.round((my.expires_at - my.starts_at) / 86400) : null; const daysProgress = daysTotal && my?.days_remaining != null ? Math.max(0, Math.min(100, ((daysTotal - my.days_remaining) / daysTotal) * 100)) : null; return ( <> {/* وضعیت اشتراک فعلی */} {my && (
پنل {PLAN_DISPLAY[my.plan.name]?.label ?? my.plan.name} {my.is_trial && تریال}
{my.expires_at ?
انقضا: {formatDate(my.expires_at)} — {formatNumber(my.days_remaining ?? 0)} روز باقی‌مانده
:
بدون تاریخ انقضا
}
{!my.used_trial && ( )}
{daysProgress !== null && (
)}
)} {/* کارت‌های پلن */} {plansLoading ? (
در حال بارگذاری...
) : (
{plans.map((plan) => ( setPurchaseTarget(period)} /> ))}
)} {/* Modal پرداخت */} setPurchaseTarget(null)} title={`خرید ${purchaseTarget?.label ?? ''}`} >
{(['mellat', 'sep'] as const).map((gw) => ( ))}

مبلغ: {purchaseTarget ? formatRial(purchaseTarget.price_rials) : ''}

); } function PlanCard({ plan, currentPlanLevel, usedTrial, onPurchase, }: { plan: SubscriptionPlan; currentPlanLevel: number; usedTrial: boolean; onPurchase: (period: SubscriptionPeriod) => void; }) { const display = PLAN_DISPLAY[plan.name] ?? { label: plan.name, color: '#64748b' }; const isCurrent = plan.level === currentPlanLevel; const paidPeriods = plan.periods.filter((p) => !p.is_trial); const trialPeriod = plan.periods.find((p) => p.is_trial); return (
{isCurrent && ( پنل فعلی )}
{display.label}
حداکثر {plan.max_secretaries} منشی
    {Object.entries(plan.features).map(([key, enabled]) => (
  • {PLAN_FEATURE_LABELS[key] ?? key}
  • ))}
{paidPeriods.length > 0 && (
{paidPeriods.map((period) => (
{period.label}
{formatRial(period.price_rials)}
))}
)} {trialPeriod && !usedTrial && plan.level > 0 && (
تریال {trialPeriod.duration_months} ماهه رایگان — از دکمه بالای صفحه فعال کنید
)}
); }