refactor(frontend): move repeated Tailwind chains into BEM classes

This commit is contained in:
Vaka.pro
2026-04-27 20:42:21 +03:00
parent 17d59c3639
commit d46d4c4487
14 changed files with 273 additions and 101 deletions

View File

@@ -4,9 +4,9 @@ import { Footer } from './Footer';
export function AppShell() {
return (
<div className="flex min-h-screen flex-col">
<div className="app-shell">
<Header />
<main className="container-page flex-1 py-6 sm:py-10">
<main className="app-shell__main">
<Outlet />
</main>
<Footer />

View File

@@ -17,15 +17,15 @@ export function Footer() {
});
return (
<footer className="container-page mt-10 py-6 text-xs text-muted">
<div className="flex flex-col items-center justify-between gap-2 sm:flex-row">
<div className="flex items-center gap-2">
<footer className="app-footer">
<div className="app-footer__inner">
<div className="app-footer__brand">
<Gift className="h-4 w-4" aria-hidden />
<span className="font-display text-sm">{t('app.name')}</span>
<span className="app-footer__brand-name">{t('app.name')}</span>
</div>
<div className="flex items-center gap-3">
<div className="app-footer__meta">
<span>{t('footer.frontend', { version: FRONTEND_VERSION })}</span>
<span className="opacity-50">·</span>
<span className="app-footer__separator">·</span>
<span>{t('footer.backend', { version: data?.backend ?? '...' })}</span>
</div>
</div>

View File

@@ -44,21 +44,21 @@ export function Header() {
if (!user) return null;
return (
<header className="container-page pt-6">
<div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border bg-surface/80 px-4 py-3 backdrop-blur">
<Link to="/" className="flex items-center gap-2">
<span className="inline-flex h-9 w-9 items-center justify-center rounded-md bg-primary text-primary-foreground shadow-card">
<header className="app-header">
<div className="app-header__inner">
<Link to="/" className="app-header__brand">
<span className="app-header__brand-mark">
<Gift className="h-4 w-4" />
</span>
<div>
<div className="font-display text-lg leading-tight">{t('app.name')}</div>
<div className="text-xs text-muted">
<div className="app-header__brand-title">{t('app.name')}</div>
<div className="app-header__brand-subtitle">
{t('header.signedInAs', { name: user.displayName })}
</div>
</div>
</Link>
<nav className="flex flex-wrap items-center gap-1">
<nav className="app-header__nav">
{links.map((l) => (
<NavLink
key={l.to}
@@ -66,8 +66,8 @@ export function Header() {
end={l.end}
className={({ isActive }) =>
cn(
'inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors',
isActive ? 'bg-primary text-primary-foreground shadow-card' : 'text-ink hover:bg-ink/5',
'app-header__nav-link',
isActive && 'app-header__nav-link--active',
)
}
>
@@ -80,8 +80,8 @@ export function Header() {
to={`/u/${friend.data.slug}`}
className={({ isActive }) =>
cn(
'inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors',
isActive ? 'bg-primary text-primary-foreground shadow-card' : 'text-ink hover:bg-ink/5',
'app-header__nav-link',
isActive && 'app-header__nav-link--active',
)
}
>
@@ -91,7 +91,7 @@ export function Header() {
)}
</nav>
<div className="flex items-center gap-1">
<div className="app-header__actions">
<LanguageSwitcher />
<Button
variant="ghost"