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:
@@ -1,10 +1,97 @@
|
||||
import type { TourDefinition } from './types';
|
||||
import { appointmentsTour } from './tours/appointments';
|
||||
import { appointmentDetailTour, reserveAppointmentsTour } from './tours/appointmentsMore';
|
||||
import { appointmentCreateTour, appointmentEditTour, patientDetailTour } from './tours/patientDetail';
|
||||
import { myPatientRecordTour, myPatientsTour } from './tours/myPatients';
|
||||
import { patientsTour } from './tours/patients';
|
||||
import {
|
||||
claimDetailTour, claimsTour, discountsTour, insurancePricingTour, myFinancialTour,
|
||||
myPaymentDetailTour, myPaymentsTour, smsWalletTour, subscriptionTour,
|
||||
} from './tours/financial';
|
||||
import {
|
||||
clinicServicesTour, inventoryTour, resourceDetailTour, resourcePoolsTour, resourceSkillsTour,
|
||||
resourceTypesTour, resourcesTour, serviceCategoriesTour, serviceDetailTour, treatmentCasesTour,
|
||||
} from './tours/services';
|
||||
import {
|
||||
accountSettingsTour, appointmentSettingsTour, clinicAppointmentSettingsTour, clinicDoctorsTour,
|
||||
holidaysTour, practiceDomainTour, recordNumberSettingsTour, settingsMenuTour, tagsSettingsTour,
|
||||
} from './tours/settings';
|
||||
import {
|
||||
clinicDetailTour, clinicsTour, dashboardTour, doctorDetailTour, doctorFormTour, doctorsTour,
|
||||
mySecretariesTour, secretaryEarningsTour, secretarySettlementTour, staffSessionDetailTour,
|
||||
staffSessionsTour, staffTour,
|
||||
} from './tours/clinicStaff';
|
||||
import {
|
||||
patientRecordFormTour, representationBlogFormTour, representationBlogsTour,
|
||||
representationFinanceTour, representationProfileTour, representationSettlementTour,
|
||||
sessionEditTour, sessionNewTour, sessionPaymentTour,
|
||||
} from './tours/sessionsAndRepresentation';
|
||||
|
||||
/** هر صفحه تور خودش را در tours/ دارد و فقط اینجا ثبت میشود. */
|
||||
export const TOURS: Record<string, TourDefinition> = {
|
||||
[appointmentsTour.id]: appointmentsTour,
|
||||
};
|
||||
const ALL: TourDefinition[] = [
|
||||
appointmentsTour,
|
||||
appointmentDetailTour,
|
||||
reserveAppointmentsTour,
|
||||
appointmentCreateTour,
|
||||
appointmentEditTour,
|
||||
patientsTour,
|
||||
patientDetailTour,
|
||||
myPatientsTour,
|
||||
myPatientRecordTour,
|
||||
myPaymentsTour,
|
||||
myPaymentDetailTour,
|
||||
myFinancialTour,
|
||||
claimsTour,
|
||||
claimDetailTour,
|
||||
insurancePricingTour,
|
||||
discountsTour,
|
||||
subscriptionTour,
|
||||
smsWalletTour,
|
||||
clinicServicesTour,
|
||||
serviceDetailTour,
|
||||
serviceCategoriesTour,
|
||||
resourcesTour,
|
||||
resourceTypesTour,
|
||||
resourcePoolsTour,
|
||||
resourceSkillsTour,
|
||||
resourceDetailTour,
|
||||
inventoryTour,
|
||||
treatmentCasesTour,
|
||||
settingsMenuTour,
|
||||
accountSettingsTour,
|
||||
tagsSettingsTour,
|
||||
recordNumberSettingsTour,
|
||||
appointmentSettingsTour,
|
||||
clinicAppointmentSettingsTour,
|
||||
holidaysTour,
|
||||
practiceDomainTour,
|
||||
clinicDoctorsTour,
|
||||
dashboardTour,
|
||||
clinicsTour,
|
||||
clinicDetailTour,
|
||||
doctorsTour,
|
||||
doctorDetailTour,
|
||||
doctorFormTour,
|
||||
mySecretariesTour,
|
||||
staffTour,
|
||||
staffSessionsTour,
|
||||
staffSessionDetailTour,
|
||||
secretaryEarningsTour,
|
||||
secretarySettlementTour,
|
||||
sessionNewTour,
|
||||
sessionEditTour,
|
||||
sessionPaymentTour,
|
||||
patientRecordFormTour,
|
||||
representationBlogsTour,
|
||||
representationBlogFormTour,
|
||||
representationFinanceTour,
|
||||
representationProfileTour,
|
||||
representationSettlementTour,
|
||||
];
|
||||
|
||||
export const TOURS: Record<string, TourDefinition> = Object.fromEntries(
|
||||
ALL.map((tour) => [tour.id, tour]),
|
||||
);
|
||||
|
||||
export function getTour(id?: string): TourDefinition | null {
|
||||
return id ? TOURS[id] ?? null : null;
|
||||
|
||||
@@ -59,4 +59,50 @@ describe('registry', () => {
|
||||
expect(new Set(anchors).size).toBe(anchors.length);
|
||||
}
|
||||
});
|
||||
|
||||
it('متن هر استپ فارسی و غیرخالی است', () => {
|
||||
for (const tour of Object.values(TOURS)) {
|
||||
for (const step of tour.steps) {
|
||||
expect(step.title.trim().length).toBeGreaterThan(2);
|
||||
expect(step.body.trim().length).toBeGreaterThan(10);
|
||||
// متن راهنما برای کاربر فارسیزبان است؛ استپِ انگلیسیمانده یعنی جا افتاده.
|
||||
expect(step.title).toMatch(/[-ۿ]/);
|
||||
expect(step.body).toMatch(/[-ۿ]/);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* لنگرِ بیالمان بیصدا حذف میشود، پس تورِ خراب هیچ خطایی نمیدهد و فقط استپش را
|
||||
* از دست میدهد. این تست همان سکوت را میشکند: هر anchor باید در کدِ صفحات وجود
|
||||
* داشته باشد.
|
||||
*/
|
||||
describe('انطباق لنگرها با کد صفحات', () => {
|
||||
it('هیچ استپی به data-tour ناموجود اشاره نمیکند', async () => {
|
||||
// خواندن مستقیم فایلها، نه import.meta.glob: آن فقط زیر Vite کار میکند و
|
||||
// ts-loaderِ Encore همین فایل را هم type-check میکند و build را قرمز میکرد.
|
||||
const { readdirSync, readFileSync } = await import('node:fs');
|
||||
const { join } = await import('node:path');
|
||||
|
||||
const walk = (dir: string): string[] =>
|
||||
readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
||||
const path = join(dir, entry.name);
|
||||
if (entry.isDirectory()) return walk(path);
|
||||
return entry.name.endsWith('.tsx') && !entry.name.includes('.test.') ? [path] : [];
|
||||
});
|
||||
|
||||
const sources = walk('assets/admin').map((path) => readFileSync(path, 'utf8'));
|
||||
const declared = new Set(
|
||||
sources.flatMap((src) => [...src.matchAll(/data-tour="([a-z0-9-]+)"/g)].map((m) => m[1])),
|
||||
);
|
||||
|
||||
expect(declared.size).toBeGreaterThan(0);
|
||||
|
||||
const orphans = Object.values(TOURS).flatMap((tour) =>
|
||||
tour.steps.filter((s) => !declared.has(s.anchor)).map((s) => `${tour.id}:${s.anchor}`),
|
||||
);
|
||||
|
||||
expect(orphans).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const appointmentDetailTour: TourDefinition = {
|
||||
id: 'appointment-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'appt-patient',
|
||||
title: 'اطلاعات نوبت',
|
||||
body: 'نام بیمار، پزشک، خدمت، ساعت و هزینهٔ همین نوبت.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'appt-status',
|
||||
title: 'وضعیت و اقدامات',
|
||||
body: 'وضعیت فعلی نوبت را از اینجا عوض کنید — مثلاً تأیید، حضور بیمار یا لغو.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'appt-events',
|
||||
title: 'تاریخچهٔ رویدادها',
|
||||
body: 'هر تغییر وضعیت با زمان و عاملش ثبت میشود؛ برای پیگیری اختلاف مفید است.',
|
||||
side: 'top',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const reserveAppointmentsTour: TourDefinition = {
|
||||
id: 'appointments-reserve',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'page-title',
|
||||
title: 'نوبتهای رزرو شده',
|
||||
body: 'نوبتهایی که بیرون از تقویم عادی و بهصورت دستی رزرو شدهاند.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'reserve-doctor',
|
||||
title: 'انتخاب پزشک',
|
||||
body: 'در کلینیک، اول پزشک را انتخاب کنید تا نوبتهای رزروش بیاید.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'reserve-new',
|
||||
title: 'نوبت رزرو جدید',
|
||||
body: 'تا وقتی پزشکی انتخاب نشده، این دکمه غیرفعال است.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'reserve-list',
|
||||
title: 'فهرست رزروها',
|
||||
body: 'هر ردیف یک نوبت رزروشده با بیمار و زمان آن.',
|
||||
side: 'top',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const dashboardTour: TourDefinition = {
|
||||
id: 'dashboard',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'داشبورد', body: 'خلاصهٔ امروز: نوبتها، درآمد، بیماران و کارهای در انتظار.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const clinicsTour: TourDefinition = {
|
||||
id: 'clinics',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'کلینیکها', body: 'کلینیکهایی که به آنها دسترسی دارید.', side: 'bottom' },
|
||||
{ anchor: 'page-pagination', title: 'صفحهبندی', body: 'تعداد کل و جابهجایی بین صفحهها.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const clinicDetailTour: TourDefinition = {
|
||||
id: 'clinic-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پروندهٔ کلینیک', body: 'اطلاعات، آدرس، تصاویر و تنظیمات این کلینیک.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const doctorsTour: TourDefinition = {
|
||||
id: 'doctors',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پزشکان', body: 'فهرست پزشکان و دسترسی به پروفایل هرکدام.', side: 'bottom' },
|
||||
{ anchor: 'page-pagination', title: 'صفحهبندی', body: 'تعداد کل پزشکان و حرکت بین صفحهها.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const doctorDetailTour: TourDefinition = {
|
||||
id: 'doctor-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پروفایل پزشک', body: 'مشخصات، تخصصها، آدرسها، تعرفهها و وضعیت فعالبودن پزشک.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const doctorFormTour: TourDefinition = {
|
||||
id: 'doctor-new',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'افزودن پزشک', body: 'پزشک جدید را با موبایل و تخصصش ثبت کنید.', side: 'bottom' },
|
||||
{ anchor: 'doctor-form', title: 'فرم', body: 'موبایل کلید حساب است؛ اگر کاربری با آن شماره باشد، به همان وصل میشود.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const mySecretariesTour: TourDefinition = {
|
||||
id: 'my-secretaries',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'منشیها', body: 'منشیهای شما و دسترسیهایشان.', side: 'bottom' },
|
||||
{ anchor: 'secretaries-tabs', title: 'فعلی و قبلی', body: 'منشی قطعهمکاریشده در تب دوم میماند و حذف نمیشود.', side: 'bottom' },
|
||||
{ anchor: 'secretaries-add', title: 'افزودن منشی', body: 'بعد از ذخیره، پنجرهٔ مجوزها باز میشود تا دسترسیهایش را دقیق تعیین کنید. سقف تعداد به پلن اشتراک بستگی دارد.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const staffTour: TourDefinition = {
|
||||
id: 'staff',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'مدیریت پرسنل', body: 'کارکنان درمانی که جلسه انجام میدهند — با مهارتها و سهمشان.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'فهرست پرسنل', body: 'مهارت هر نفر تعیین میکند در چه سرویسی قابل انتخاب است.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const staffSessionsTour: TourDefinition = {
|
||||
id: 'my-sessions',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'جلسات امروز من', body: 'جلسههایی که امروز به شما سپرده شده است.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const staffSessionDetailTour: TourDefinition = {
|
||||
id: 'my-session-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'جزئیات جلسه', body: 'خدمت، بیمار، مصرف انبار و ثبت انجام جلسه.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const secretaryEarningsTour: TourDefinition = {
|
||||
id: 'secretary-earnings',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'درآمد نوبتهای آنلاین', body: 'سهم شما از نوبتهایی که آنلاین ثبت و پرداخت شدهاند.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'ریز نوبتها', body: 'هر ردیف یک نوبت با سهم شما از آن.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const secretarySettlementTour: TourDefinition = {
|
||||
id: 'secretary-settlement',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'تسویه حساب', body: 'برداشت سهم نوبتهای آنلاین به شماره شبای خودتان.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'درخواستها', body: 'وضعیت هر درخواست برداشت اینجا دیده میشود.', side: 'top' },
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const myPaymentsTour: TourDefinition = {
|
||||
id: 'my-payments',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'لیست پرداختها', body: 'همهٔ پرداختهای ثبتشدهٔ بیماران شما، جدیدترین بالا.', side: 'bottom' },
|
||||
{ anchor: 'page-search', title: 'جستجو', body: 'با نام بیمار یا شمارهٔ صورتحساب بگردید.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'ردیفهای پرداخت', body: 'با کلیک روی هر بیمار، صورتحسابها و آیتمهایش باز میشود.', side: 'top' },
|
||||
{ anchor: 'page-pagination', title: 'صفحهبندی', body: 'تعداد کل و جابهجایی بین صفحهها.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const myPaymentDetailTour: TourDefinition = {
|
||||
id: 'my-payment-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پرداختهای این بیمار', body: 'صورتحسابهای ثبتشده برای همین بیمار و ماندهحسابش.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'آیتمهای صورتحساب', body: 'هر ردیف یک خدمت با سهم بیمار و سهم بیمه.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const myFinancialTour: TourDefinition = {
|
||||
id: 'my-financial',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'مدیریت پرداخت', body: 'درگاه، حساب بانکی و روشهای دریافت وجه از بیمار.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const claimsTour: TourDefinition = {
|
||||
id: 'claims',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پروندههای بیمه', body: 'مطالبات بیمه به تفکیک بیمار؛ چقدر ثبت شده، چقدر وصول شده.', side: 'bottom' },
|
||||
{ anchor: 'page-search', title: 'جستجوی بیمار', body: 'با نام یا کد ملی بیمار پیدایش کنید.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'فهرست مطالبات', body: 'روی هر ردیف بزنید تا ریز خدمات و سهم بیمهاش باز شود.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const claimDetailTour: TourDefinition = {
|
||||
id: 'claim-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'جزئیات مطالبه', body: 'خدمات بیمهایِ همین بیمار و وضعیت وصول هرکدام.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'ریز خدمات', body: 'سهم بیمه و سهم بیمار برای هر خدمت جدا آمده است.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const insurancePricingTour: TourDefinition = {
|
||||
id: 'insurance-pricing',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'مدیریت بیمه', body: 'قراردادهای بیمهٔ پایه و تکمیلی و درصد پوشش هرکدام.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const discountsTour: TourDefinition = {
|
||||
id: 'discounts',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'مدیریت تخفیفها', body: 'قوانین تخفیف که هنگام صدور صورتحساب اعمال میشوند.', side: 'bottom' },
|
||||
{ anchor: 'discounts-rules', title: 'قوانین', body: 'برای هر خدمت یا کل فاکتور، درصد یا مبلغ ثابت تعریف کنید.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const subscriptionTour: TourDefinition = {
|
||||
id: 'subscription',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'اشتراک', body: 'پلن فعلی و پلنهای قابل خرید.', side: 'bottom' },
|
||||
{ anchor: 'subscription-current', title: 'پلن فعلی', body: 'روزهای باقیمانده و دکمهٔ تمدید همینجاست.', side: 'bottom' },
|
||||
{ anchor: 'subscription-plans', title: 'پلنها', body: 'امکانات هر پلن زیرش نوشته شده؛ خرید از روی همین کارتها انجام میشود.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const smsWalletTour: TourDefinition = {
|
||||
id: 'sms-wallet',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'کیف پول پیامک', body: 'ارسال پیامک به بیماران از موجودی همین کیف پول کم میشود.', side: 'bottom' },
|
||||
{ anchor: 'sms-balance', title: 'موجودی و مصرف', body: 'موجودی فعلی و آمار مصرف. وقتی موجودی کم شود، اینجا هشدار میگیرید.', side: 'bottom' },
|
||||
{ anchor: 'page-pagination', title: 'تاریخچه', body: 'شارژها و مصرفهای قبلی صفحهبندی شدهاند.', side: 'top' },
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const myPatientsTour: TourDefinition = {
|
||||
id: 'my-patients',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'page-title',
|
||||
title: 'پروندهٔ بیماران',
|
||||
body: 'فهرست مراجعهکنندگانی که برایشان پرونده ثبت شده است. با ثبت اولین نوبت، پرونده خودکار ساخته میشود.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'page-action',
|
||||
title: 'پروندهٔ دستی',
|
||||
body: 'برای بیماری که هنوز نوبت نگرفته، از اینجا پرونده بسازید.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'patients-search',
|
||||
title: 'جستجو و نمای فهرست',
|
||||
body: 'جستجو با نام، موبایل یا کد ملی. دو آیکون کنارش، نمای کارتی و لیستی را عوض میکنند.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'patients-records',
|
||||
title: 'پروندهها',
|
||||
body: 'با کلیک روی هر پرونده، اطلاعات بیمار و مراجعهها و پرداختهایش باز میشود.',
|
||||
side: 'top',
|
||||
},
|
||||
{
|
||||
anchor: 'page-pagination',
|
||||
title: 'صفحهبندی',
|
||||
body: 'شمار کل پروندهها و جابهجایی بین صفحهها.',
|
||||
side: 'top',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const myPatientRecordTour: TourDefinition = {
|
||||
id: 'my-patient-record',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'record-banner',
|
||||
title: 'شناسنامهٔ بیمار',
|
||||
body: 'خلاصهٔ هویتی و تماس بیمار، شمارهٔ پرونده و تاریخ تشکیل آن.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'record-tabs',
|
||||
title: 'بخشهای پرونده',
|
||||
body: 'اطلاعات پرونده، مراجعهها، پرداختها و نوبتها؛ هر کدام در تب خودش.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'page-action',
|
||||
title: 'مراجعهٔ جدید و بازگشت',
|
||||
body: 'ثبت مراجعهٔ تازه برای همین بیمار، یا برگشتن به فهرست پروندهها.',
|
||||
side: 'bottom',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const patientDetailTour: TourDefinition = {
|
||||
id: 'patient-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'patient-banner',
|
||||
title: 'شناسنامهٔ پرونده',
|
||||
body: 'نام، شمارهٔ پرونده، برچسبها، نوبت و جلسهٔ بعدی و وضعیت بدهی — همه یکجا.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'patient-tabs',
|
||||
title: 'بخشهای پرونده',
|
||||
body: 'سرویسها، نوبتها، دورههای درمان، پرداختها، کیف پول، یادداشت، ضمیمه و پروندهٔ پزشکی.',
|
||||
side: 'bottom',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const appointmentCreateTour: TourDefinition = {
|
||||
id: 'appointment-create',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'page-title',
|
||||
title: 'ثبت نوبت جدید',
|
||||
body: 'چهار قدم دارد: پزشک، مراجعهکننده، سرویس و زمان.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'create-doctor',
|
||||
title: 'پزشک یا منبع',
|
||||
body: 'اول پزشک را انتخاب کنید؛ سرویسها و ساعتهای آزاد از برنامهٔ همو میآیند.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'create-patient',
|
||||
title: 'مراجعهکننده',
|
||||
body: 'بیمار قبلی را جستجو کنید، یا مشخصات شخص جدید را وارد کنید تا پروندهاش ساخته شود.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'create-service',
|
||||
title: 'سرویسها',
|
||||
body: 'اول بخش، بعد یک یا چند سرویس. مدت و هزینهٔ نوبت از همینها حساب میشود.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'create-submit',
|
||||
title: 'ثبت',
|
||||
body: 'تا وقتی پزشک، بیمار، سرویس و زمان کامل نشده، دکمه غیرفعال است.',
|
||||
side: 'top',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const appointmentEditTour: TourDefinition = {
|
||||
id: 'appointment-edit',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'edit-service',
|
||||
title: 'ویرایش نوبت',
|
||||
body: 'بخش، سرویس، پرسنل، زمان و وضعیت نوبت را از همینجا عوض کنید.',
|
||||
side: 'bottom',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const patientsTour: TourDefinition = {
|
||||
id: 'patients',
|
||||
version: 1,
|
||||
steps: [
|
||||
{
|
||||
anchor: 'page-title',
|
||||
title: 'پروندهها',
|
||||
body: 'فهرست کامل پروندههای بیماران این محیط، با امکان جستجو و فیلتر.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'patients-search',
|
||||
title: 'جستجو',
|
||||
body: 'کد ملی، شمارهٔ پرونده یا نام مراجعهکننده را بنویسید.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'patients-filters',
|
||||
title: 'فیلترها',
|
||||
body: 'جنسیت، بیمه، بازهٔ پذیرش، بدهی و برچسب. عدد روی دکمه یعنی چند فیلتر فعال است.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'patients-new',
|
||||
title: 'تشکیل پرونده',
|
||||
body: 'پروندهٔ جدید برای بیماری که هنوز ثبت نشده است.',
|
||||
side: 'bottom',
|
||||
},
|
||||
{
|
||||
anchor: 'page-pagination',
|
||||
title: 'صفحهبندی',
|
||||
body: 'نمای کارتی ۱۶ و نمای جدولی ۱۲ پرونده در هر صفحه نشان میدهد.',
|
||||
side: 'top',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const clinicServicesTour: TourDefinition = {
|
||||
id: 'clinic-services',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'سرویسها', body: 'خدماتی که در نوبتدهی و صورتحساب استفاده میشوند؛ هرکدام مدت و تعرفهٔ خودش را دارد.', side: 'bottom' },
|
||||
{ anchor: 'page-action', title: 'سرویس جدید', body: 'خدمت تازه را اینجا تعریف کنید تا در ثبت نوبت قابل انتخاب شود.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const serviceDetailTour: TourDefinition = {
|
||||
id: 'service-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'جزئیات سرویس', body: 'تعرفه، مدت، بیمه و تنظیمات نوبتدهی همین خدمت.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const serviceCategoriesTour: TourDefinition = {
|
||||
id: 'service-categories',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'دستهبندیها', body: 'سرویسها را دستهبندی کنید تا در فهرستها و فیلترها مرتب بمانند.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'دستهها', body: 'هر دسته را میتوان ویرایش یا حذف کرد.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const resourcesTour: TourDefinition = {
|
||||
id: 'resources',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'منابع', body: 'اتاق، تخت یا دستگاه — هر چیزی که خودش تقویم نوبت دارد.', side: 'bottom' },
|
||||
{ anchor: 'page-action', title: 'منبع جدید', body: 'منبع تازه بسازید و پزشک ناظرش را مشخص کنید.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'فهرست منابع', body: 'با کلیک روی هر منبع، تقویم و سرویسهایش باز میشود.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const resourceTypesTour: TourDefinition = {
|
||||
id: 'resource-types',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'نوع منابع', body: 'دستهبندی منابع؛ مثلاً اتاق عمل، یونیت دندانپزشکی یا دستگاه لیزر.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'نوعها', body: 'هنگام ساخت منبع، یکی از همین نوعها انتخاب میشود.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const resourcePoolsTour: TourDefinition = {
|
||||
id: 'resource-pools',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'استخر منابع', body: 'چند منبع همکار را در یک استخر بگذارید تا سیستم خودش یکی از آزادها را بدهد.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'استخرها', body: 'اعضای هر استخر از همینجا مدیریت میشوند.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const resourceSkillsTour: TourDefinition = {
|
||||
id: 'resource-skills',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'مهارتها', body: 'مهارت لازم برای هر خدمت؛ فقط منبع یا پرسنلِ دارای آن مهارت قابل انتخاب میشود.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'فهرست مهارتها', body: 'مهارتها را بسازید و بعد به منابع و پرسنل نسبت دهید.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const resourceDetailTour: TourDefinition = {
|
||||
id: 'resource-detail',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'جزئیات منبع', body: 'مشخصات منبع، سرویسهایش، مهارتها و دسترسی به تقویمش.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const inventoryTour: TourDefinition = {
|
||||
id: 'inventory',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'انبارداری', body: 'کالاهای مصرفی و پکیجها؛ مصرف هر جلسه از همین موجودی کم میشود.', side: 'bottom' },
|
||||
{ anchor: 'inventory-tabs', title: 'دو بخش', body: 'کالای مصرفی و پکیج. پکیج چند کالا را با هم مصرف میکند.', side: 'bottom' },
|
||||
{ anchor: 'inventory-stats', title: 'وضعیت انبار', body: 'ارزش موجودی و کالاهایی که به مرز هشدار رسیدهاند.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const treatmentCasesTour: TourDefinition = {
|
||||
id: 'treatment-cases',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'دورههای درمان', body: 'درمانهای چندجلسهای بیماران و پیشرفت هر دوره.', side: 'bottom' },
|
||||
{ anchor: 'treatment-tabs', title: 'بخشها', body: 'دورهها و جلسهها را جدا ببینید و بر اساس وضعیت فیلتر کنید.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const sessionNewTour: TourDefinition = {
|
||||
id: 'session-new',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'ثبت مراجعه', body: 'یک مراجعهٔ تازه برای همین بیمار ثبت میکنید.', side: 'bottom' },
|
||||
{ anchor: 'session-card', title: 'فرم مراجعه', body: 'خدمت انجامشده، پرسنل و مبلغ. بعد از ثبت، صورتحسابش قابل صدور است.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const sessionEditTour: TourDefinition = {
|
||||
id: 'session-edit',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'ویرایش مراجعه', body: 'خدمت، پرسنل یا مبلغ همین مراجعه را اصلاح کنید.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const sessionPaymentTour: TourDefinition = {
|
||||
id: 'session-payment',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پرداخت مراجعه', body: 'دریافت وجه بابت این مراجعه و ثبت روش پرداخت.', side: 'bottom' },
|
||||
{ anchor: 'session-card', title: 'مبلغ و روش', body: 'سهم بیمه از سهم بیمار جدا حساب میشود؛ باقیمانده همان چیزی است که دریافت میکنید.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const patientRecordFormTour: TourDefinition = {
|
||||
id: 'patient-record-form',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پروندهٔ بیمار', body: 'ساخت یا ویرایش پروندهٔ یک مراجعهکننده.', side: 'bottom' },
|
||||
{ anchor: 'record-form', title: 'فرم', body: 'موبایل کلید شناسایی بیمار است؛ کد ملی و بیمه بعداً هم قابل تکمیلاند.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const representationBlogsTour: TourDefinition = {
|
||||
id: 'representation-blogs',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'وبلاگ من', body: 'مقالههایی که نوشتهاید و وضعیت بررسی هرکدام.', side: 'bottom' },
|
||||
{ anchor: 'page-action', title: 'مقالهٔ جدید', body: 'مقاله بعد از تأیید ادمین روی سایت منتشر میشود.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'فهرست مقالهها', body: 'وضعیت هر مقاله: پیشنویس، در انتظار بررسی یا منتشرشده.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const representationBlogFormTour: TourDefinition = {
|
||||
id: 'representation-blog-form',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'نوشتن مقاله', body: 'عنوان، متن، تصویر و اطلاعات سئو مقاله.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const representationFinanceTour: TourDefinition = {
|
||||
id: 'representation-finance',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'گزارش مالی', body: 'پورسانت شما از اشتراکهایی که مجموعههای تحت پوششتان خریدهاند.', side: 'bottom' },
|
||||
{ anchor: 'page-pagination', title: 'دورهها', body: 'رکوردهای مالی صفحهبندی شدهاند.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const representationProfileTour: TourDefinition = {
|
||||
id: 'representation-profile',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پروفایل نماینده', body: 'مشخصات شما، شهر تحت پوشش و اطلاعات حساب بانکی برای تسویه.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const representationSettlementTour: TourDefinition = {
|
||||
id: 'representation-settlement',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'تسویه حساب', body: 'درخواست برداشت پورسانت و وضعیت درخواستهای قبلی.', side: 'bottom' },
|
||||
{ anchor: 'page-pagination', title: 'تاریخچه', body: 'درخواستهای قبلی و نتیجهٔ هرکدام.', side: 'top' },
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
import type { TourDefinition } from '../types';
|
||||
|
||||
export const settingsMenuTour: TourDefinition = {
|
||||
id: 'settings-menu',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'تنظیمات', body: 'همهٔ تنظیمات محیط از همینجا شاخه میگیرد: نوبتدهی، سرویسها، بیمه، برچسبها، اشتراک و کاربران.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const accountSettingsTour: TourDefinition = {
|
||||
id: 'account-settings',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'حساب کاربری', body: 'شمارهٔ ورود، رمز عبور و اطلاعات شخصی حسابتان.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const tagsSettingsTour: TourDefinition = {
|
||||
id: 'tags-settings',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'برچسبها', body: 'برچسبهایی که به پروندهٔ بیماران میچسبانید و بعد با آنها فیلتر میکنید.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const recordNumberSettingsTour: TourDefinition = {
|
||||
id: 'record-number-settings',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'شمارهٔ پرونده', body: 'الگوی شمارهگذاری پروندههای جدید — پیشوند، طول و شمارهٔ شروع.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const appointmentSettingsTour: TourDefinition = {
|
||||
id: 'appointment-settings',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'مدیریت نوبتدهی', body: 'برنامهٔ هفتگی، مدت نوبت، تعطیلیها و قواعد لغو نوبت.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const clinicAppointmentSettingsTour: TourDefinition = {
|
||||
id: 'clinic-appointment-settings',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'نوبتدهی کلینیک', body: 'تنظیمات نوبتدهی در سطح کلینیک؛ روی همهٔ پزشکان عضو اثر میگذارد.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const holidaysTour: TourDefinition = {
|
||||
id: 'holidays',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'تعطیلات', body: 'روزهایی که نوبتدهی بسته است. تعطیلات رسمی کشور از قبل هست و میتوانید روز دلخواه هم اضافه کنید.', side: 'bottom' },
|
||||
{ anchor: 'page-table', title: 'فهرست روزها', body: 'هر ردیف یک روز تعطیل؛ حذفش نوبتدهی همان روز را باز میکند.', side: 'top' },
|
||||
],
|
||||
};
|
||||
|
||||
export const practiceDomainTour: TourDefinition = {
|
||||
id: 'practice-domain',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'حوزهٔ فعالیت', body: 'نوع کار محیط شما؛ فرمهای پرونده و گردش درمان بر اساس همین انتخاب میشود.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
|
||||
export const clinicDoctorsTour: TourDefinition = {
|
||||
id: 'clinic-doctors',
|
||||
version: 1,
|
||||
steps: [
|
||||
{ anchor: 'page-title', title: 'پزشکان کلینیک', body: 'پزشکان عضو، دعوت پزشک جدید و قطع همکاری.', side: 'bottom' },
|
||||
{ anchor: 'page-action', title: 'دعوت پزشک', body: 'با شمارهٔ موبایل دعوت بفرستید؛ پزشک بعد از پذیرش، در نوبتدهی کلینیک دیده میشود.', side: 'bottom' },
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user