refactor(ui): close residual theme audit debt
This commit is contained in:
parent
57f7f35ad7
commit
5453bb4922
@ -40,24 +40,33 @@ def included(path: pathlib.Path) -> bool:
|
||||
def approved_ui(path: pathlib.Path) -> bool:
|
||||
return "components" in path.parts and "ui" in path.parts
|
||||
|
||||
def collect(pattern: re.Pattern[str], exclude_approved_ui: bool) -> list[tuple[str, int, str]]:
|
||||
def collect(
|
||||
pattern: re.Pattern[str],
|
||||
exclude_approved_ui: bool,
|
||||
label: str,
|
||||
) -> list[tuple[str, int, str]]:
|
||||
matches = []
|
||||
for path in sorted(web_src.rglob("*")):
|
||||
if not path.is_file() or not included(path):
|
||||
continue
|
||||
if exclude_approved_ui and approved_ui(path):
|
||||
continue
|
||||
rel = path.relative_to(web_src).as_posix()
|
||||
if label == "hardcoded color literals" and rel == "index.css":
|
||||
continue
|
||||
try:
|
||||
lines = path.read_text(encoding="utf-8").splitlines()
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
rel = path.relative_to(web_src).as_posix()
|
||||
for line_number, line in enumerate(lines, start=1):
|
||||
if pattern.search(line):
|
||||
matches.append((rel, line_number, line.rstrip()))
|
||||
return matches
|
||||
|
||||
results = [(label, title, collect(pattern, exclude_approved_ui)) for label, title, pattern, exclude_approved_ui in patterns]
|
||||
results = [
|
||||
(label, title, collect(pattern, exclude_approved_ui, label))
|
||||
for label, title, pattern, exclude_approved_ui in patterns
|
||||
]
|
||||
total = sum(len(matches) for _, _, matches in results)
|
||||
|
||||
print(f"UI drift audit mode={mode}")
|
||||
|
||||
@ -12,19 +12,19 @@ export const TIER_POLICIES: Record<UserTier, TierPermissions> = {
|
||||
allowedRiskStyleIds: ['safe'],
|
||||
maxDailyProfitTargetUsd: 0, // No profit target adjustment
|
||||
label: 'Free Tier',
|
||||
color: '#94a3b8' // Zinc-400
|
||||
color: 'var(--bl-text-secondary)'
|
||||
},
|
||||
pro: {
|
||||
allowedRiskStyleIds: ['safe', 'balanced'],
|
||||
maxDailyProfitTargetUsd: 100,
|
||||
label: 'Pro Tier',
|
||||
color: '#3b82f6' // Blue-500
|
||||
color: 'var(--bl-info-strong)'
|
||||
},
|
||||
elite: {
|
||||
allowedRiskStyleIds: ['safe', 'balanced', 'aggressive'],
|
||||
maxDailyProfitTargetUsd: 10000,
|
||||
label: 'Elite Tier',
|
||||
color: '#00ff88' // Primary Green
|
||||
color: 'var(--bl-success)'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -141,7 +141,7 @@ export const EntriesTab = ({ botState = DEFAULT_BOT_STATE }: EntriesTabProps) =>
|
||||
const entryState = deriveEntryState(entry, botState);
|
||||
return (
|
||||
<div key={entry.stock_instance_id} className="group relative rounded-[2.5rem] p-1 transition-all duration-500 bg-white/[0.01] hover:bg-gradient-to-br hover:from-green-500/10 hover:to-transparent">
|
||||
<div className="bg-[#0a0b0d] border border-white/5 rounded-[2.4rem] p-8 h-full flex flex-col transition-all group-hover:border-white/10 group-hover:shadow-2xl">
|
||||
<div className="bg-[var(--card-elevated)] border border-white/5 rounded-[2.4rem] p-8 h-full flex flex-col transition-all group-hover:border-white/10 group-hover:shadow-2xl">
|
||||
|
||||
{/* Card Top */}
|
||||
<div className="flex items-start justify-between mb-8">
|
||||
@ -248,7 +248,7 @@ export const EntriesTab = ({ botState = DEFAULT_BOT_STATE }: EntriesTabProps) =>
|
||||
|
||||
{/* 2. FORM DRAWER (IF ADDING/EDITING) */}
|
||||
{(isAdding || editingEntry) && (
|
||||
<div className="bg-[#0a0b0d] border border-white/10 rounded-[3rem] p-10 shadow-2xl animate-in zoom-in-95 duration-300">
|
||||
<div className="bg-[var(--card-elevated)] border border-white/10 rounded-[3rem] p-10 shadow-2xl animate-in zoom-in-95 duration-300">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<h3 className="text-lg font-black text-white uppercase tracking-tight flex items-center gap-3">
|
||||
<Plus size={20} className="text-green-400" />
|
||||
|
||||
@ -22,7 +22,7 @@ const PlanCard: React.FC<{
|
||||
}> = ({ id, policy }) => {
|
||||
const isElite = id === 'elite';
|
||||
const isPro = id === 'pro';
|
||||
const themeColor = isElite ? '#00ff88' : isPro ? '#3498db' : '#929292';
|
||||
const themeColor = isElite ? 'var(--bl-success)' : isPro ? 'var(--bl-info-strong)' : 'var(--bl-text-secondary)';
|
||||
|
||||
const price = id === 'free' ? '$0' : id === 'pro' ? '$49' : '$199';
|
||||
const description = id === 'free'
|
||||
@ -78,7 +78,7 @@ const PlanCard: React.FC<{
|
||||
<span style={{ fontSize: 14, color: 'var(--muted-foreground)', fontWeight: 900, textTransform: 'uppercase' }}>/mo</span>
|
||||
</div>
|
||||
<div className="stat-chip">
|
||||
<Sparkles size={14} style={{ color: '#fbbf24' }} />
|
||||
<Sparkles size={14} style={{ color: 'var(--bl-warning)' }} />
|
||||
Professional grade DNA
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1299,7 +1299,7 @@ export const PositionsTab = ({ botState, onManageHolding }: PositionsTabProps) =
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={`h-auto rounded-none px-4 py-3 text-sm font-semibold transition-all border-b-2 ${selectedProfileId === 'all'
|
||||
? 'border-[#00ff88] text-[#00ff88]'
|
||||
? 'border-[var(--bl-success)] text-[var(--bl-success)]'
|
||||
: 'border-transparent text-gray-500 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
@ -1313,7 +1313,7 @@ export const PositionsTab = ({ botState, onManageHolding }: PositionsTabProps) =
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={`h-auto rounded-none px-4 py-3 text-sm font-semibold transition-all border-b-2 ${selectedProfileId === p.id
|
||||
? 'border-[#00ff88] text-[#00ff88]'
|
||||
? 'border-[var(--bl-success)] text-[var(--bl-success)]'
|
||||
: 'border-transparent text-gray-500 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
@ -2002,11 +2002,11 @@ export const PositionsTab = ({ botState, onManageHolding }: PositionsTabProps) =
|
||||
{trace.stateReason}
|
||||
</div>
|
||||
<div className="flex items-center justify-end gap-2 text-white/60">
|
||||
{trace.entryOrder && <Lock size={14} aria-label="Lock acquired" className="text-[#38bdf8]" />}
|
||||
{trace.hasHistoryMatch && <RefreshCw size={14} aria-label="Reconciliation applied" className="text-[#22c55e]" />}
|
||||
{trace.state === 'PARTIAL_EXIT' && <AlertTriangle size={14} aria-label="Partial fill" className="text-[#facc15]" />}
|
||||
{trace.hasCancel && <XCircle size={14} aria-label="Cancel detected" className="text-[#f87171]" />}
|
||||
{trace.state === 'CLOSED' && <CheckCircle size={14} aria-label="Finalized" className="text-[#34d399]" />}
|
||||
{trace.entryOrder && <Lock size={14} aria-label="Lock acquired" className="text-[var(--bl-info-strong)]" />}
|
||||
{trace.hasHistoryMatch && <RefreshCw size={14} aria-label="Reconciliation applied" className="text-[var(--bl-success)]" />}
|
||||
{trace.state === 'PARTIAL_EXIT' && <AlertTriangle size={14} aria-label="Partial fill" className="text-[var(--bl-warning)]" />}
|
||||
{trace.hasCancel && <XCircle size={14} aria-label="Cancel detected" className="text-[var(--bl-danger)]" />}
|
||||
{trace.state === 'CLOSED' && <CheckCircle size={14} aria-label="Finalized" className="text-[var(--bl-success)]" />}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -220,7 +220,7 @@ export const SettingsTab = ({ botState }: SettingsTabProps) => {
|
||||
|
||||
{/* Break */}
|
||||
<div className="form-group full-width" style={{ marginTop: '10px', opacity: 0.5 }}>
|
||||
<hr style={{ border: '0', borderTop: '1px solid rgba(255,255,255,0.1)' }} />
|
||||
<hr style={{ border: '0', borderTop: '1px solid var(--bl-border-subtle)' }} />
|
||||
<small>Research & Screener Credentials</small>
|
||||
</div>
|
||||
|
||||
@ -250,7 +250,7 @@ export const SettingsTab = ({ botState }: SettingsTabProps) => {
|
||||
</div>
|
||||
|
||||
<div className="form-group full-width" style={{ marginTop: '10px', opacity: 0.5 }}>
|
||||
<hr style={{ border: '0', borderTop: '1px solid rgba(255,255,255,0.1)' }} />
|
||||
<hr style={{ border: '0', borderTop: '1px solid var(--bl-border-subtle)' }} />
|
||||
<small>Alpaca Credentials</small>
|
||||
</div>
|
||||
|
||||
@ -314,8 +314,8 @@ export const SettingsTab = ({ botState }: SettingsTabProps) => {
|
||||
|
||||
<style>{`
|
||||
.primary-button {
|
||||
background: #00ff88;
|
||||
color: #000;
|
||||
background: var(--bl-success);
|
||||
color: black;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px;
|
||||
@ -324,8 +324,8 @@ export const SettingsTab = ({ botState }: SettingsTabProps) => {
|
||||
}
|
||||
.secondary-button {
|
||||
background: transparent;
|
||||
color: #ccc;
|
||||
border: 1px solid #ccc;
|
||||
color: var(--bl-text-secondary);
|
||||
border: 1px solid var(--bl-text-secondary);
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
@ -344,15 +344,15 @@ export const SettingsTab = ({ botState }: SettingsTabProps) => {
|
||||
gap: 8px;
|
||||
}
|
||||
.form-group label {
|
||||
color: #929292;
|
||||
color: var(--bl-text-secondary);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.form-group input {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: var(--bl-surface-highlight);
|
||||
border: 1px solid var(--bl-border-subtle);
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
color: #fff;
|
||||
color: var(--foreground);
|
||||
font-family: monospace;
|
||||
}
|
||||
.form-group input:disabled {
|
||||
@ -369,12 +369,12 @@ export const SettingsTab = ({ botState }: SettingsTabProps) => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
color: #9aa0a6;
|
||||
color: var(--bl-text-secondary);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.settings-hint a {
|
||||
color: #00ff88;
|
||||
color: var(--bl-success);
|
||||
text-decoration: none;
|
||||
}
|
||||
.settings-hint a:hover {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user