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:
@@ -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',
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user