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:
hamed
2026-07-27 16:41:52 +03:30
parent c29035c21e
commit 55ab2f5dfc
73 changed files with 1485 additions and 1110 deletions
+12 -12
View File
@@ -44,9 +44,9 @@ const PLAN_META: Record<string, { label: string; desc: string; tint: string }> =
/** Gradient blur behind each plan card — matches the tauri source per plan tier. */
const PLAN_GRADIENT: Record<string, string> = {
free: 'radial-gradient(circle, #f5ecfd 0%, #e9eaf9 70%, transparent 100%)',
basic: 'radial-gradient(circle, #e2eee5 0%, #f5edfd 60%, transparent 100%)',
professional: 'linear-gradient(180deg, #f9eedd 0%, #e8e9fa 0%, rgba(255,255,255,0) 100%)',
free: 'radial-gradient(circle, var(--violet-bg) 0%, var(--primary-soft) 70%, transparent 100%)',
basic: 'radial-gradient(circle, var(--success-bg) 0%, var(--violet-bg) 60%, transparent 100%)',
professional: 'linear-gradient(180deg, var(--warning-bg) 0%, var(--primary-soft) 0%, transparent 100%)',
};
export const planMetaOf = (name: string) => PLAN_META[name] ?? PLAN_META.free;
@@ -305,7 +305,7 @@ function CurrentPlanCard({ my, onRenew }: { my: MySubscriptionData['subscription
{daysLeft < 3 && (
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 4 }}>
<div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
<InfoCircleRedFilled color="#d22d32" />
<InfoCircleRedFilled color="var(--danger)" />
<span style={{ fontSize: 14, fontWeight: 500, color: 'var(--text)' }}>
{daysLeft <= 0 ? 'اشتراک شما به پایان رسیده است' : `${formatNumber(daysLeft)} روز تا پایان اشتراک`}
</span>
@@ -380,7 +380,7 @@ function PlanCard({
data-testid={`plan-card-${plan.name}`}
style={{
width: '100%', minWidth: 0, height: 522, borderRadius: 10,
border: isSelected ? '2px solid #494cb3' : '2px solid var(--border)',
border: isSelected ? '2px solid var(--primary-600)' : '2px solid var(--border)',
background: 'var(--surface)', display: 'flex', flexDirection: 'column',
padding: 16, position: 'relative', overflow: 'hidden',
}}
@@ -397,11 +397,11 @@ function PlanCard({
{isPopular && (
<div style={{
position: 'absolute', width: 'fit-content', height: 32, top: -18, right: -20,
background: '#3d4395', color: '#fff', padding: '0 16px', borderRadius: '0 10px 0 10px',
background: 'var(--primary-700)', color: 'var(--on-primary)', padding: '0 16px', borderRadius: '0 10px 0 10px',
fontSize: 13, fontWeight: 500, display: 'flex', alignItems: 'center', gap: 8, zIndex: 1,
}}>
محبوبترین
<SparkleIcon size={15} color="#FDD835" />
<SparkleIcon size={15} color="var(--warning)" />
</div>
)}
@@ -490,8 +490,8 @@ function PlanCard({
</span>
<span style={{ position: 'relative', display: 'inline-flex', width: 22, height: 22 }}>
{enabled
? <CheckCircleIcon style={{ width: 22, height: 22, color: '#3c9a4f' }} />
: <CloseCircleFilled size={22} color="#d7d7d7" />}
? <CheckCircleIcon style={{ width: 22, height: 22, color: 'var(--success)' }} />
: <CloseCircleFilled size={22} color="var(--border-2)" />}
</span>
</div>
);
@@ -507,7 +507,7 @@ function PlanCard({
}}>
<button
onClick={onTrial} disabled={trialPending}
style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', fontSize: 16, fontWeight: 500, color: '#5559ce' }}
style={{ background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', fontSize: 16, fontWeight: 500, color: 'var(--primary)' }}
>
{trialPending ? 'در حال فعال‌سازی...' : 'فعال سازی'}
</button>
@@ -519,7 +519,7 @@ function PlanCard({
</div>
</div>
<svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }} viewBox="0 0 268 59" preserveAspectRatio="none">
<rect x="0.5" y="0.5" width="267" height="58" rx="6" fill="transparent" stroke="#636ed0" strokeWidth="1" strokeDasharray="6 4" />
<rect x="0.5" y="0.5" width="267" height="58" rx="6" fill="transparent" strokeWidth="1" strokeDasharray="6 4" style={{ stroke: 'var(--primary)' }}/>
</svg>
</div>
)}
@@ -541,7 +541,7 @@ function PlanCard({
disabled={!selectedPeriod}
style={{
marginTop: 'auto', width: '100%', height: 48, borderRadius: 4, border: 'none',
background: 'var(--primary)', color: '#fff', fontWeight: 700, fontSize: 16,
background: 'var(--primary)', color: 'var(--on-primary)', fontWeight: 700, fontSize: 16,
fontFamily: 'inherit', cursor: selectedPeriod ? 'pointer' : 'not-allowed',
}}
>