Files
clinicpro/assets/admin/pages/ClinicDetailPage.tsx
T
hamed 942634c98e refactor: update UI components for consistency and dark mode support
- Refactored PaymentsPage, RatingsPage, RepresentationDetailPage, RepresentationsPage, SecretariesPage, SettlementsPage, SmsPage, UserDetailPage, and UsersPage to use consistent class names for styling.
- Updated button styles to use new utility classes for primary, secondary, and danger buttons.
- Enhanced dark mode support across various components by adjusting text and background colors.
- Introduced new utility classes for form inputs, labels, and info rows to standardize styling.
- Implemented Zustand for persistent UI state management, including dark mode toggle functionality.
- Updated CSS to include new styles for skeleton loading and animations.
- Added optional dependencies for improved compatibility with different platforms.
2026-06-10 12:30:14 +03:30

90 lines
3.4 KiB
TypeScript

import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import type { Clinic } from '../types';
import { formatDate } from '../lib/utils';
import PageHeader from '../components/ui/PageHeader';
import { ActiveBadge } from '../components/ui/StatusBadge';
function InfoRow({ label, value }: { label: string; value: React.ReactNode }) {
return (
<div className="cp-info-row">
<span className="cp-info-label text-sm">{label}</span>
<span className="cp-info-value">{value ?? '—'}</span>
</div>
);
}
export default function ClinicDetailPage() {
const { uuid } = useParams<{ uuid: string }>();
const navigate = useNavigate();
const { data, isLoading } = useQuery({
queryKey: ['clinic', uuid],
queryFn: () => api.get<ApiResponse<Clinic>>(`/api/v1/clinic/${uuid}`),
enabled: !!uuid,
});
const clinic = data?.data;
return (
<div>
<PageHeader
title="جزئیات کلینیک"
breadcrumbs={[
{ label: 'داشبورد', to: '/admin/dashboard' },
{ label: 'کلینیک‌ها', to: '/admin/clinics' },
{ label: 'جزئیات' },
]}
action={
<button onClick={() => navigate('/admin/clinics')}
className="flex items-center gap-2 text-sm text-slate-500 dark:text-slate-400 hover:text-slate-800 dark:hover:text-slate-100 transition-colors">
<ArrowRightIcon className="w-4 h-4" />
بازگشت
</button>
}
/>
{isLoading ? (
<div className="cp-card p-6 space-y-3">
{Array.from({ length: 5 }).map((_, i) => (
<div key={i} className="h-8 rounded-lg skeleton" />
))}
</div>
) : clinic ? (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-6">
<div className="flex items-center gap-4 mb-6">
{clinic.logo ? (
<img src={clinic.logo} alt="" className="w-16 h-16 rounded-xl object-cover" />
) : (
<div className="w-16 h-16 rounded-xl bg-blue-100 flex items-center justify-center text-blue-700 text-2xl font-bold">
{clinic.name?.[0]}
</div>
)}
<h2 className="font-bold text-gray-900 text-lg">{clinic.name}</h2>
</div>
<InfoRow label="تلفن" value={clinic.phone ? <span dir="ltr">{clinic.phone}</span> : null} />
<InfoRow label="وضعیت" value={<ActiveBadge active={clinic.is_active} />} />
<InfoRow label="تاریخ ثبت" value={formatDate(clinic.created_at)} />
</div>
{clinic.description && (
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-6">
<h3 className="font-semibold text-gray-800 mb-3">توضیحات</h3>
<p className="text-sm text-gray-600 leading-relaxed">{clinic.description}</p>
</div>
)}
</div>
) : (
<div className="bg-white rounded-2xl border border-gray-100 p-16 text-center text-gray-400">
کلینیکی یافت نشد
</div>
)}
</div>
);
}