Implement comprehensive dark/light mode overhaul for admin panel
- 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.
This commit is contained in:
@@ -19,14 +19,14 @@ const PAYMENT_LABELS = PAYMENT_METHOD_LABELS;
|
||||
|
||||
/** vertical hairline divider between meta columns (tauri MUI vertical Divider). */
|
||||
function VDivider({ h = 24 }: { h?: number }) {
|
||||
return <span className="dark:bg-[#35343D]" style={{ width: 1, height: h, background: '#E5E7EB', flexShrink: 0, margin: '0 16px', alignSelf: 'center' }} />;
|
||||
return <span style={{ width: 1, height: h, background: 'var(--surface-2)', flexShrink: 0, margin: '0 16px', alignSelf: 'center' }} />;
|
||||
}
|
||||
|
||||
function Meta({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13 }}>
|
||||
<span className="dark:text-[#A1A1A1]" style={{ color: '#6B7280' }}>{label}:</span>
|
||||
<span className="dark:text-[#D7D8ED]" style={{ color: '#525252', fontWeight: 500 }}>{value}</span>
|
||||
<span style={{ color: 'var(--text-2)' }}>{label}:</span>
|
||||
<span style={{ color: 'var(--text)', fontWeight: 500 }}>{value}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -49,16 +49,16 @@ export default function SessionPaymentAccordion({ session, expanded, onToggle }:
|
||||
const finalPrice = formatRial(session.final_price_rials ?? 0);
|
||||
|
||||
return (
|
||||
<div className="dark:border-[#35343D]" style={{ border: '1px solid #E5E7EB', borderRadius: 8, marginBottom: 16, overflow: 'hidden' }}>
|
||||
<div style={{ border: '1px solid var(--border)', borderRadius: 8, marginBottom: 16, overflow: 'hidden' }}>
|
||||
{/* summary */}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggle}
|
||||
aria-expanded={expanded}
|
||||
className="bg-white dark:bg-[#2B2D3A]"
|
||||
className="bg-[var(--surface)]"
|
||||
style={{ display: 'flex', alignItems: 'center', gap: 4, width: '100%', padding: '12px 16px', border: 'none', cursor: 'pointer', textAlign: 'start', flexWrap: 'wrap' }}
|
||||
>
|
||||
<span className="dark:text-[#D7D8ED]" style={{ minWidth: 150, color: '#2f2f2f', fontWeight: 500, fontSize: 14 }}>{name}</span>
|
||||
<span style={{ minWidth: 150, color: 'var(--text)', fontWeight: 500, fontSize: 14 }}>{name}</span>
|
||||
<VDivider />
|
||||
<Meta label="تاریخ" value={session.created_at ? formatDate(session.created_at) : '—'} />
|
||||
<VDivider />
|
||||
@@ -66,26 +66,26 @@ export default function SessionPaymentAccordion({ session, expanded, onToggle }:
|
||||
<span style={{ flex: 1 }} />
|
||||
<VDivider />
|
||||
<span style={{
|
||||
color: '#fff', padding: '3px 16px', borderRadius: 4, fontSize: 12, fontWeight: 600,
|
||||
textAlign: 'center', minWidth: 90, background: paid ? '#10B981' : '#F59E0B',
|
||||
color: 'var(--on-primary)', padding: '3px 16px', borderRadius: 4, fontSize: 12, fontWeight: 600,
|
||||
textAlign: 'center', minWidth: 90, background: paid ? 'var(--success)' : 'var(--warning)',
|
||||
}}>
|
||||
{paid ? 'پرداخت شده' : 'تسویه نشده'}
|
||||
</span>
|
||||
<ChevronDownIcon className="dark:text-[#D7D8ED]" style={{ width: 20, height: 20, color: '#525252', marginInlineStart: 8, transition: 'transform .2s', transform: expanded ? 'rotate(180deg)' : 'none' }} />
|
||||
<ChevronDownIcon style={{ width: 20, height: 20, color: 'var(--text)', marginInlineStart: 8, transition: 'transform .2s', transform: expanded ? 'rotate(180deg)' : 'none' }} />
|
||||
</button>
|
||||
|
||||
{/* details */}
|
||||
{expanded && (
|
||||
<div className="dark:border-[#35343D] dark:bg-[#222433]" style={{ borderTop: '1px solid #E5E7EB' }}>
|
||||
<div className="dark:bg-[var(--surface)]" style={{ borderTop: '1px solid var(--border)' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '12px 16px 8px' }}>
|
||||
<FilesServicePaymentsCheck color="#6B7280" size={18} style={{ transform: 'rotate(180deg)' }} />
|
||||
<span className="dark:text-[#A1A1A1]" style={{ color: '#6B7280', fontWeight: 600, fontSize: 13 }}>پرداختیها</span>
|
||||
<FilesServicePaymentsCheck color="var(--text-2)" size={18} style={{ transform: 'rotate(180deg)' }} />
|
||||
<span style={{ color: 'var(--text-2)', fontWeight: 600, fontSize: 13 }}>پرداختیها</span>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: '0 16px 16px' }}>
|
||||
{paid ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '12px 0', flexWrap: 'wrap' }}>
|
||||
<FilesServicePaymentsCheck color="#6B7280" size={20} />
|
||||
<FilesServicePaymentsCheck color="var(--text-2)" size={20} />
|
||||
<Meta label="تاریخ" value={formatDate(session.updated_at ?? session.created_at ?? 0)} />
|
||||
<VDivider h={32} />
|
||||
<Meta label="مبلغ" value={finalPrice} />
|
||||
@@ -95,7 +95,7 @@ export default function SessionPaymentAccordion({ session, expanded, onToggle }:
|
||||
<Meta label="پرسنل" value={session.doctor_name || '—'} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="dark:text-[#A1A1A1]" style={{ padding: 16, textAlign: 'center', color: '#6B7280', fontSize: 13 }}>هیچ پرداختی ثبت نشده است.</div>
|
||||
<div style={{ padding: 16, textAlign: 'center', color: 'var(--text-2)', fontSize: 13 }}>هیچ پرداختی ثبت نشده است.</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user