feat: replace checkboxes with Switch component for better UI consistency

- Updated DoctorDetailPage, MySecretariesPage, RecordNumberSettingsPage, RepresentationsPage, ResourcePoolsPage, ResourceTypesPage, SecretariesPage, SecretaryDetailPage, SettingsPage, SkillsPage, SmsWalletPage, and TagsSettingsPage to use the new Switch component instead of native checkboxes.
- Enhanced accessibility by ensuring the Switch component uses appropriate roles and labels.
- Added tests for the new Switch component to ensure functionality and accessibility compliance.
- Updated styles to accommodate the new Switch component design.
This commit is contained in:
hamed
2026-08-05 16:09:46 +03:30
parent f9bbdf1e7c
commit 0e7970d6e0
38 changed files with 634 additions and 350 deletions
+41 -21
View File
@@ -4,6 +4,9 @@ import PageHeader from '../components/ui/PageHeader';
import DataTable, { type Column } from '../components/ui/DataTable';
import Modal from '../components/ui/Modal';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import Field from '../components/ui/Field';
import Input from '../components/ui/Input';
import Switch from '../components/ui/Switch';
import { ActiveBadge } from '../components/ui/StatusBadge';
import { useUrlState } from '../hooks/useUrlState';
import { usePermissions } from '../hooks/usePermissions';
@@ -74,7 +77,7 @@ export default function SkillsPage() {
</button>
<button
type="button"
className="btn secondary sm"
className="btn danger sm"
disabled={(s.resources_count ?? 0) > 0}
title={(s.resources_count ?? 0) > 0 ? 'اول از منابع برداشته شود' : undefined}
onClick={() => setToDelete(s)}
@@ -131,30 +134,47 @@ function SkillModal({
}, [open, skill]);
return (
<Modal open={open} onClose={onClose} title={skill ? 'ویرایش مهارت' : 'افزودن مهارت'}>
<div style={{ display: 'grid', gap: 14 }}>
<div style={{ display: 'grid', gap: 6 }}>
<label style={{ fontSize: 12, color: 'var(--text-2)' }}>نام مهارت</label>
<input className="field" value={name} onChange={(e) => setName(e.target.value)} placeholder="لیزر آلکساندرایت" />
</div>
<label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
<input type="checkbox" checked={active} onChange={(e) => setActive(e.target.checked)} />
فعال است
</label>
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
<Modal
open={open}
onClose={onClose}
title={skill ? 'ویرایش مهارت' : 'افزودن مهارت'}
footer={
<div className="row-actions">
<button type="button" className="btn secondary" onClick={onClose}>انصراف</button>
<button
type="button"
className="btn primary"
disabled={saving || name.trim() === ''}
onClick={() => onSave({ name: name.trim(), active })}
>
<button type="submit" form="skill-form" className="btn primary" disabled={saving || name.trim() === ''}>
{saving ? 'در حال ذخیره...' : 'ذخیره'}
</button>
</div>
</div>
}
>
<form
id="skill-form"
style={{ display: 'grid', gap: 16 }}
onSubmit={(e) => {
e.preventDefault();
if (saving || name.trim() === '') return;
onSave({ name: name.trim(), active });
}}
>
<Field label="نام مهارت" htmlFor="skill-name">
<Input
id="skill-name"
value={name}
autoFocus
onChange={(e) => setName(e.target.value)}
placeholder="لیزر آلکساندرایت"
/>
<span className="field-hint">مهارت به منبع داده میشود و در جستجوی وقت شرط میگذارد.</span>
</Field>
<Switch
id="skill-active"
checked={active}
onChange={setActive}
label="فعال است"
hint="مهارت غیرفعال در انتخابگرها پیشنهاد نمی‌شود."
/>
</form>
</Modal>
);
}