160 lines
9.1 KiB
Python
160 lines
9.1 KiB
Python
import re
|
|
|
|
html_path = "bot/app/web/templates/subscription_webapp.html"
|
|
|
|
with open(html_path, 'r', encoding='utf-8') as f:
|
|
html = f.read()
|
|
|
|
replacements = {
|
|
r'class="flex items-start justify-between gap-3"': 'class="panel-head"',
|
|
r'class="text-lg font-extrabold leading-tight text-\[var\(--text-primary\)\]"': 'class="section-title"',
|
|
r'class="mt-\[3px\] text-\[13px\] text-\[var\(--text-secondary\)\]"': 'class="section-caption"',
|
|
r'class="min-w-0 font-\[family-name:var\(--font-mono\)\] text-\[11px\] font-bold text-\[var\(--text-muted\)\]"': 'class="metric-label"',
|
|
r'class="min-w-0 text-right text-sm font-bold text-\[var\(--text-primary\)\]"': 'class="metric-value"',
|
|
r'class="m-0 text-\[32px\] font-extrabold leading-\[1\.08\] text-\[var\(--text-primary\)\]"': 'class="main-value"',
|
|
r'class="mt-1\.5 mb-0 text-sm leading-\[1\.45\] text-\[var\(--text-secondary\)\]"': 'class="main-caption"',
|
|
r'class="login-text login-status hidden m-0 min-h-5 text-sm leading-\[1\.45\] text-\[var\(--text-secondary\)\]"': 'class="status-text hidden"',
|
|
r'class="login-text login-status hidden"': 'class="status-text hidden"',
|
|
r'class="actions grid min-w-0 grid-cols-\[minmax\(0,1fr\)_48px\] gap-2"': 'class="actions-row"',
|
|
r'class="hidden flex flex-wrap justify-center gap-x-4 gap-y-1\.5"': 'class="legal-links hidden"',
|
|
r'class="flex min-h-12 items-center justify-between gap-3"': 'class="app-header"',
|
|
r'class="flex min-w-0 items-center gap-2\.5"': 'class="app-header-title"',
|
|
r'class="flex min-w-0 items-center gap-2"': 'class="app-header-actions"',
|
|
r'class="flex min-w-0 items-center justify-between gap-2\.5"': 'class="panel-head-sm"',
|
|
r'class="flex min-w-0 items-center justify-center gap-3\.5"': 'class="login-head"',
|
|
}
|
|
|
|
for pattern, repl in replacements.items():
|
|
html = re.sub(pattern, repl, html)
|
|
|
|
with open(html_path, 'w', encoding='utf-8') as f:
|
|
f.write(html)
|
|
|
|
js_path = "bot/app/web/templates/subscription_webapp.js"
|
|
with open(js_path, 'r', encoding='utf-8') as f:
|
|
js = f.read()
|
|
|
|
js_replacements = {
|
|
r"panelHead: 'flex items-start justify-between gap-3',": "panelHead: 'panel-head',",
|
|
r"flowCaption: 'mt-\[3px\] text-\[13px\] text-\[var\(--text-secondary\)\]',": "flowCaption: 'section-caption',",
|
|
r"sectionTitle: 'text-lg font-extrabold leading-tight text-\[var\(--text-primary\)\]',": "sectionTitle: 'section-title',",
|
|
r"metricLabel: 'min-w-0 font-\[family-name:var\(--font-mono\)\] text-\[11px\] font-bold text-\[var\(--text-muted\)\]',": "metricLabel: 'metric-label',",
|
|
r"metricValue: 'min-w-0 text-right text-sm font-bold text-\[var\(--text-primary\)\]',": "metricValue: 'metric-value',",
|
|
r"referralLinkRow: 'grid min-h-\[58px\] grid-cols-\[minmax\(0,1fr\)_48px\] items-center gap-2\.5 rounded-\[var\(--radius-md\)\] border border-\[var\(--border\)\] bg-\[rgba\(255,255,255,0\.02\)\] px-3 py-\[11px\]',": "referralLinkRow: 'referral-link-row',",
|
|
r"referralLinkValue: 'mt-1 font-\[family-name:var\(--font-mono\)\] text-xs font-bold leading-\[1\.35\] text-\[var\(--text-primary\)\]',": "referralLinkValue: 'referral-link-value',",
|
|
r"bonusRow: 'grid min-h-\[58px\] grid-cols-\[minmax\(0,0\.8fr\)_minmax\(0,1\.2fr\)\] items-center gap-2\.5 rounded-\[var\(--radius-md\)\] border border-\[var\(--border\)\] bg-\[rgba\(255,255,255,0\.02\)\] px-3 py-\[11px\]',": "bonusRow: 'bonus-row',",
|
|
r"empty: 'rounded-\[var\(--radius-md\)\] border border-\[var\(--border\)\] bg-\[rgba\(255,255,255,0\.02\)\] p-\[13px\] text-sm leading-\[1\.45\] text-\[var\(--text-secondary\)\]',": "empty: 'empty-state',",
|
|
r"planCard: 'flex min-h-16 w-full min-w-0 items-center justify-between gap-3 rounded-\[var\(--radius-md\)\] border border-\[var\(--border\)\] bg-\[rgba\(255,255,255,0\.02\)\] p-\[13px\] text-left text-\[var\(--text-primary\)\] transition-\[transform,border-color,background,box-shadow\] hover:-translate-y-0\.5 hover:border-\[color-mix\(in_srgb,var\(--accent\)_42%,var\(--border\)\)\] hover:bg-\[var\(--bg-card-hover\)\]',": "planCard: 'plan-card',",
|
|
r"planCardActive: 'border-\[var\(--accent\)\] bg-\[color-mix\(in_srgb,var\(--accent\)_8%,transparent\)\] ring-1 ring-\[color-mix\(in_srgb,var\(--accent\)_58%,transparent\)\] shadow-\[0_12px_30px_rgba\(0,0,0,0\.2\)\]',": "planCardActive: 'plan-card-active',",
|
|
r"planName: 'block text-\[15px\] font-extrabold leading-tight',": "planName: 'plan-name',",
|
|
r"planMeta: 'mt-1 block font-\[family-name:var\(--font-mono\)\] text-\[11px\] font-bold leading-\[1\.3\] text-\[var\(--text-muted\)\]',": "planMeta: 'plan-meta',",
|
|
r"planPrice: 'block max-w-\[48%\] flex-none text-right font-\[family-name:var\(--font-mono\)\] text-\[15px\] font-extrabold leading-tight text-\[var\(--accent\)\]',": "planPrice: 'plan-price',",
|
|
r"notice: 'rounded-\[var\(--radius-md\)\] border border-\[var\(--border\)\] bg-\[rgba\(255,255,255,0\.02\)\] p-\[13px\] text-sm leading-\[1\.45\] text-\[var\(--text-secondary\)\]',": "notice: 'notice',",
|
|
r"stepNum: 'block font-\[family-name:var\(--font-mono\)\] text-\[11px\] font-extrabold leading-\[1\.1\] text-current',": "stepNum: 'step-num',",
|
|
r"stepName: 'mt-1 block text-xs font-extrabold leading-\[1\.15\] text-current'": "stepName: 'step-name'"
|
|
}
|
|
|
|
for pattern, repl in js_replacements.items():
|
|
js = re.sub(pattern, repl, js)
|
|
|
|
with open(js_path, 'w', encoding='utf-8') as f:
|
|
f.write(js)
|
|
|
|
# CSS additions
|
|
css_path = "bot/app/web/templates/subscription_webapp.tailwind.css"
|
|
with open(css_path, 'r', encoding='utf-8') as f:
|
|
css = f.read()
|
|
|
|
new_components = """
|
|
.panel-head {
|
|
@apply flex items-start justify-between gap-3;
|
|
}
|
|
.section-title {
|
|
@apply text-lg font-extrabold leading-tight text-[var(--text-primary)];
|
|
}
|
|
.section-caption {
|
|
@apply mt-[3px] text-[13px] text-[var(--text-secondary)];
|
|
}
|
|
.metric-label {
|
|
@apply min-w-0 font-[family-name:var(--font-mono)] text-[11px] font-bold text-[var(--text-muted)];
|
|
}
|
|
.metric-value {
|
|
@apply min-w-0 text-right text-sm font-bold text-[var(--text-primary)];
|
|
}
|
|
.referral-link-row {
|
|
@apply grid min-h-[58px] grid-cols-[minmax(0,1fr)_48px] items-center gap-2.5 rounded-[var(--radius-md)] border border-[var(--border)] bg-[rgba(255,255,255,0.02)] px-3 py-[11px];
|
|
}
|
|
.referral-link-value {
|
|
@apply mt-1 font-[family-name:var(--font-mono)] text-xs font-bold leading-[1.35] text-[var(--text-primary)];
|
|
}
|
|
.bonus-row {
|
|
@apply grid min-h-[58px] grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)] items-center gap-2.5 rounded-[var(--radius-md)] border border-[var(--border)] bg-[rgba(255,255,255,0.02)] px-3 py-[11px];
|
|
}
|
|
.empty-state {
|
|
@apply rounded-[var(--radius-md)] border border-[var(--border)] bg-[rgba(255,255,255,0.02)] p-[13px] text-sm leading-[1.45] text-[var(--text-secondary)];
|
|
}
|
|
.plan-card {
|
|
@apply flex min-h-16 w-full min-w-0 items-center justify-between gap-3 rounded-[var(--radius-md)] border border-[var(--border)] bg-[rgba(255,255,255,0.02)] p-[13px] text-left text-[var(--text-primary)] transition-[transform,border-color,background,box-shadow] hover:-translate-y-0.5 hover:border-[color-mix(in_srgb,var(--accent)_42%,var(--border))] hover:bg-[var(--bg-card-hover)];
|
|
transition-duration: 200ms;
|
|
}
|
|
.plan-card-active {
|
|
@apply border-[var(--accent)] bg-[color-mix(in_srgb,var(--accent)_8%,transparent)] ring-1 ring-[color-mix(in_srgb,var(--accent)_58%,transparent)] shadow-[0_12px_30px_rgba(0,0,0,0.2)];
|
|
}
|
|
.plan-name {
|
|
@apply block text-[15px] font-extrabold leading-tight;
|
|
}
|
|
.plan-meta {
|
|
@apply mt-1 block font-[family-name:var(--font-mono)] text-[11px] font-bold leading-[1.3] text-[var(--text-muted)];
|
|
}
|
|
.plan-price {
|
|
@apply block max-w-[48%] flex-none text-right font-[family-name:var(--font-mono)] text-[15px] font-extrabold leading-tight text-[var(--accent)];
|
|
}
|
|
.notice {
|
|
@apply rounded-[var(--radius-md)] border border-[var(--border)] bg-[rgba(255,255,255,0.02)] p-[13px] text-sm leading-[1.45] text-[var(--text-secondary)];
|
|
}
|
|
.step-num {
|
|
@apply block font-[family-name:var(--font-mono)] text-[11px] font-extrabold leading-[1.1] text-current;
|
|
}
|
|
.step-name {
|
|
@apply mt-1 block text-xs font-extrabold leading-[1.15] text-current;
|
|
}
|
|
.main-value {
|
|
@apply m-0 text-[32px] font-extrabold leading-[1.08] text-[var(--text-primary)];
|
|
}
|
|
.main-caption {
|
|
@apply mt-1.5 mb-0 text-sm leading-[1.45] text-[var(--text-secondary)];
|
|
}
|
|
.status-text {
|
|
@apply m-0 min-h-5 text-sm leading-[1.45] text-[var(--text-secondary)];
|
|
}
|
|
.legal-links {
|
|
@apply flex flex-wrap justify-center gap-x-4 gap-y-1.5;
|
|
}
|
|
.actions-row {
|
|
@apply grid min-w-0 grid-cols-[minmax(0,1fr)_48px] gap-2;
|
|
}
|
|
.app-header {
|
|
@apply flex min-h-12 items-center justify-between gap-3;
|
|
}
|
|
.app-header-title {
|
|
@apply flex min-w-0 items-center gap-2.5;
|
|
}
|
|
.app-header-actions {
|
|
@apply flex min-w-0 items-center gap-2;
|
|
}
|
|
.panel-head-sm {
|
|
@apply flex min-w-0 items-center justify-between gap-2.5;
|
|
}
|
|
.login-head {
|
|
@apply flex min-w-0 items-center justify-center gap-3.5;
|
|
}
|
|
"""
|
|
|
|
css_split = css.split('.btn {')
|
|
new_css = css_split[0] + new_components + '\n .btn {' + css_split[1]
|
|
|
|
with open(css_path, 'w', encoding='utf-8') as f:
|
|
f.write(new_css)
|
|
|
|
print("Done")
|