Files
clinicpro/assets/admin/components/paymentMethods/BankAccountTable.tsx
T
hamedandClaude Opus 4.8 b459d082a4 feat: port payment management tab from tauri to admin dashboard
Add per-clinic payment methods (bank accounts + POS/card-reader devices)
under the "مدیریت پرداخت" settings tab at /admin/my-financial, ported from
clinic-pro-tauri's mock-only PaymentManagement tab into a real persisted
feature. These records are referenceable (by uuid) from patient invoices to
record which method a service payment was made with.

Backend (new src/PaymentMethod domain):
- BankAccount + Pos entities, repositories, PaymentMethodService (validation,
  ownership scoping, create/update/toggle logic).
- Thin PaymentMethodController exposing /api/v1/my/payment-methods/{bank-accounts,pos}
  (GET/POST/PUT + PATCH .../status), guarded to clinic/doctor/secretary/admin.
- Migration for bank_accounts + pos_devices tables.
- Functional tests (success + validation/404/403 + empty boundaries).
- docs/api/payment-method.md.

Frontend:
- Replace MyFinancialPage content with the payment-management UI (two tabs,
  tables, add/edit modals, status toggle) using the admin design system.
- usePaymentMethods hook (TanStack Query) + presentational components.
- Update page test to cover tabs, data, empty state and the add modal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:39:32 +03:30

69 lines
2.1 KiB
TypeScript

import React from 'react';
import { PencilIcon } from '@heroicons/react/24/outline';
import DataTable, { type Column } from '../ui/DataTable';
import StatusToggle from './StatusToggle';
import type { BankAccount } from '../../hooks/usePaymentMethods';
/**
* جدول حساب‌های بانکی — پورت مبدأ BankAccountList.jsx.
* ستون «شماره ترمینال» مبدأ به «شماره کارت» تغییر کرد (حساب بانکی ترمینال ندارد؛
* فرم افزودن شماره کارت می‌گیرد).
*/
export default function BankAccountTable({
data,
loading,
togglingUuid,
onToggle,
onEdit,
onAdd,
}: {
data: BankAccount[];
loading?: boolean;
togglingUuid: string | null;
onToggle: (uuid: string) => void;
onEdit: (account: BankAccount) => void;
onAdd: () => void;
}) {
const columns: Column<BankAccount>[] = [
{ key: 'bank_name', header: 'نام بانک' },
{ key: 'card_number', header: 'شماره کارت', render: (r) => r.card_number || '—' },
{ key: 'account_number', header: 'شماره حساب', render: (r) => r.account_number || '—' },
{
key: 'is_active',
header: 'وضعیت',
render: (r) => (
<StatusToggle
active={r.is_active}
disabled={togglingUuid === r.uuid}
onToggle={() => onToggle(r.uuid)}
/>
),
},
];
return (
<>
<p style={{ fontSize: 13.5, color: 'var(--text-2)', margin: '0 0 14px' }}>
مدیریت و اضافه کردن حساب های بانکی کلینیک
</p>
<DataTable<BankAccount>
columns={columns}
data={data}
loading={loading}
emptyMessage="هنوز حساب بانکی ثبت نشده است"
emptyAction={<button className="btn primary sm" onClick={onAdd}>افزودن حساب بانکی</button>}
actions={(r) => (
<button
className="btn sm ghost"
style={{ color: 'var(--accent)' }}
onClick={() => onEdit(r)}
>
<PencilIcon style={{ width: 14 }} />
ویرایش
</button>
)}
/>
</>
);
}