- Refactor color palette in `ui-design-spec.md` to utilize CSS variables exclusively, eliminating fixed hex values and Tailwind utility classes. - Complete dark mode implementation in `uiStore.ts`, ensuring proper theme application via `applyTheme()` and `applyBrand()`. - Create `admin-theme-dark-light-audit.md` to document the transition process, outlining issues with inline styles and fixed colors. - Introduce `theme-tokens.test.ts` to enforce rules against fixed hex colors and ensure compliance with the design system. - Update various components and styles to replace inline styles and fixed colors with CSS variables, ensuring consistent theming across light and dark modes. - Ensure all changes maintain visual integrity in both light and dark modes, with a focus on accessibility and contrast standards.
120 lines
5.2 KiB
TypeScript
120 lines
5.2 KiB
TypeScript
import { useState } from 'react';
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { api } from '../lib/api';
|
|
import type { ApiResponse } from '../lib/api';
|
|
import type { PatientRecord } from '../types';
|
|
import type { SessionCardData } from '../components/SessionServiceCard';
|
|
import SessionStepper from '../components/SessionStepper';
|
|
import CreateStep from '../components/session/CreateStep';
|
|
import PaymentStep from '../components/session/PaymentStep';
|
|
import DetailsStep from '../components/session/DetailsStep';
|
|
import { ArrowLeftPH, ArrowLeftD, CloseModalD } from '../components/icons/FilesServiceIcons';
|
|
|
|
/**
|
|
* ثبت مراجعه جدید — پورت کامل tauri /files/create-service (حالت ایجاد):
|
|
* ویزارد سهگامی «ایجاد سرویس ← پرداخت ← جزییات». گام ۱ session را میسازد
|
|
* (تاریخ/ساعت پذیرش، خدمات + پرسنل، کالای مصرفی، پکیج، بیمهی شرطی)؛
|
|
* گامهای ۲ و ۳ همان کامپوننتهای مشترک SessionPaymentPage هستند.
|
|
*/
|
|
export default function NewSessionPage() {
|
|
const { recordUuid = '' } = useParams();
|
|
const nav = useNavigate();
|
|
|
|
const steps = ['ایجاد سرویس', 'پرداخت', 'جزییات'];
|
|
const [activeStep, setActiveStep] = useState(0);
|
|
const [createdUuid, setCreatedUuid] = useState('');
|
|
|
|
const recordQ = useQuery<ApiResponse<PatientRecord>>({
|
|
queryKey: ['patient-detail', recordUuid],
|
|
queryFn: () => api.get(`/api/v1/patient/${recordUuid}`),
|
|
enabled: !!recordUuid,
|
|
});
|
|
const record = recordQ.data?.data as PatientRecord | undefined;
|
|
const patientName = record?.user_name || record?.profile?.full_name || '—';
|
|
|
|
// بعد از ساخت session در گام ۱، گامهای ۲/۳ از لیست sessions تغذیه میشوند.
|
|
const sessionsQ = useQuery<ApiResponse<SessionCardData[]>>({
|
|
queryKey: ['patient-sessions', recordUuid],
|
|
queryFn: () => api.get(`/api/v1/patient/${recordUuid}/sessions`),
|
|
enabled: !!recordUuid && !!createdUuid,
|
|
});
|
|
const session = (sessionsQ.data?.data ?? []).find((s) => s.uuid === createdUuid);
|
|
|
|
const walletQ = useQuery<ApiResponse<{ balance_rials: number }>>({
|
|
queryKey: ['patient-wallet', recordUuid],
|
|
queryFn: () => api.get(`/api/v1/patient/${recordUuid}/wallet`),
|
|
enabled: !!recordUuid && !!createdUuid,
|
|
});
|
|
const walletBalance = (walletQ.data?.data as any)?.balance_rials ?? 0;
|
|
|
|
const finish = () => nav(`/admin/patients/${recordUuid}?tab=services`);
|
|
|
|
return (
|
|
<div className="fade-in" style={{ width: '100%' }}>
|
|
{/* breadcrumb — tauri AddService header */}
|
|
<div style={{ display: 'flex', justifyContent: 'flex-start', marginBottom: 30 }}>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, color: 'var(--text-2)', fontSize: 12, padding: '0 16px' }}>
|
|
<div
|
|
onClick={() => nav(-1)}
|
|
className="bg-[var(--surface)]"
|
|
style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '6px 8px', borderRadius: 12, cursor: 'pointer' }}
|
|
>
|
|
<ArrowLeftPH style={{ width: 18, height: 18, rotate: '180deg' }} />
|
|
<span>بازگشت</span>
|
|
</div>
|
|
<ArrowLeftD />
|
|
<span>پرونده</span>
|
|
<ArrowLeftD />
|
|
<span style={{ color: 'var(--text)' }}>{patientName}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* card — tauri width 748 centered */}
|
|
<div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
|
|
<div className="bg-[var(--surface)]" style={{ width: 748, maxWidth: '100%', padding: 24 }}>
|
|
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 8 }}>
|
|
<button
|
|
type="button"
|
|
aria-label="بستن"
|
|
onClick={() => nav(-1)}
|
|
style={{ minWidth: 40, height: 40, marginBottom: 8, borderRadius: '50%', border: 'none', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
|
|
>
|
|
<CloseModalD />
|
|
</button>
|
|
</div>
|
|
|
|
<SessionStepper activeStep={activeStep} steps={steps} />
|
|
|
|
{activeStep === 0 && (
|
|
<CreateStep
|
|
recordUuid={recordUuid}
|
|
profile={record?.profile}
|
|
onCreated={(uuid) => { setCreatedUuid(uuid); setActiveStep(1); }}
|
|
onCancel={() => nav(-1)}
|
|
/>
|
|
)}
|
|
|
|
{activeStep === 1 && (
|
|
session ? (
|
|
<PaymentStep
|
|
recordUuid={recordUuid}
|
|
session={session}
|
|
walletBalance={walletBalance}
|
|
onContinue={() => setActiveStep(2)}
|
|
onCancel={finish}
|
|
/>
|
|
) : (
|
|
<div style={{ padding: '40px 0', textAlign: 'center', color: 'var(--text-3)', fontSize: 14 }}>در حال بارگذاری...</div>
|
|
)
|
|
)}
|
|
|
|
{activeStep === 2 && session && (
|
|
<DetailsStep session={session} recordUuid={recordUuid} onBack={() => setActiveStep(1)} onFinish={finish} />
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|