feat(tour): add onboarding tours for various admin pages

- Integrated TourButton component into SettingsMenuPage, SkillsPage, SmsWalletPage, StaffPage, StaffSessionDetailPage, StaffTreatmentSessionsPage, SubscriptionPage, TagsSettingsPage, TreatmentCasesPage to enhance user onboarding experience.
- Created new tour definitions for appointments, clinics, staff management, financial management, and patient management, ensuring comprehensive guidance for users navigating the admin panel.
- Updated documentation to reflect the addition of tours and their implementation details.
This commit is contained in:
hamed
2026-08-10 10:10:20 +03:30
parent 20c8eaaad9
commit ecdefa3c24
73 changed files with 1008 additions and 76 deletions
+11 -4
View File
@@ -14,6 +14,8 @@ import Pagination from '../components/ui/Pagination';
import PatientTagsCell from '../components/PatientTagsCell';
import PatientsFilterModal, { type PatientFilters } from '../components/PatientsFilterModal';
import { usePermissions } from '../hooks/usePermissions';
import { useTour } from '../hooks/useTour';
import TourButton from '../components/ui/TourButton';
import {
SearchHeaderP, TurnsFilter, PatientsGridView, PatientsCategoryView, AddTurn,
} from '../components/icons/FilesToolbarIcons';
@@ -161,6 +163,8 @@ export default function PatientsListPage() {
queryFn: () => api.get(`/api/v1/patients?${qs.toString()}`),
});
useTour('patients', { ready: !isLoading });
const activeFilters = countFilters(filters);
const records = data?.data ?? EMPTY;
const total = data?.meta?.totalRecords ?? 0;
@@ -183,14 +187,17 @@ export default function PatientsListPage() {
return (
<div className="fade-in">
{/* Head — تیتر تنها (tauri files/head) */}
<p className="text-[var(--text)] text-[16px] md:text-[18px] lg:text-[20px] font-bold">پروندهها</p>
<div className="flex items-center gap-1" data-tour="page-title">
<p className="text-[var(--text)] text-[16px] md:text-[18px] lg:text-[20px] font-bold">پروندهها</p>
<TourButton tourId="patients" />
</div>
{/* Inputs — ردیف کنترل‌ها (tauri files/inputs) */}
<div className="my-[16px] md:my-[20px] lg:my-[24px]">
<div className="flex flex-col lg:flex-row items-stretch lg:items-center gap-[16px] lg:gap-[20px]">
{/* جستجو + سوییچ نما */}
<div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 flex-1 w-full">
<div className="w-full md:w-[442px]">
<div className="w-full md:w-[442px]" data-tour="patients-search">
<div className="flex items-center rounded-[6px] border border-[var(--border)] bg-[var(--bg)]" style={{ height: 48, paddingInline: 4 }}>
<input
dir="rtl"
@@ -211,7 +218,7 @@ export default function PatientsListPage() {
{/* فیلتر + تشکیل پرونده */}
<div className="flex items-center w-full lg:w-auto justify-between lg:justify-end" style={{ gap: 12 }}>
<button
type="button" aria-label="فیلترها" onClick={() => setFilterOpen(true)}
type="button" aria-label="فیلترها" data-tour="patients-filters" onClick={() => setFilterOpen(true)}
className="flex items-center justify-center rounded-[4px] cursor-pointer"
style={{ width: 62, height: 48, border: '1px solid var(--primary)', background: 'transparent', position: 'relative' }}
>
@@ -222,7 +229,7 @@ export default function PatientsListPage() {
</button>
{canCreate && (
<button
type="button" onClick={() => navigate('/admin/patients/new')}
type="button" data-tour="patients-new" onClick={() => navigate('/admin/patients/new')}
className="flex items-center justify-center gap-2 rounded-[4px] cursor-pointer"
style={{ height: 48, minWidth: 137, background: 'var(--primary)', border: 'none', padding: '0 16px' }}
>