feat(landing): настоящие логотипы продуктов и карточки в их фирменных цветах
Две одинаковые серые плитки не давали понять, что это разные приложения, а у Бонитировки стояла служебная заглушка вместо логотипа. - logo_url и brand_color у продукта; логотипы взяты из самих приложений; - фон и рамка карточки — мягкий градиент фирменного цвета, ссылка тоже; - в шапке было «1 — ФЛАГМАНСКИЙ ПРОДУКТ», стало «2 — ПРОДУКТА В PRODUCTION».
This commit is contained in:
@@ -15,7 +15,7 @@ publicRouter.get('/content', async (_req, res) => {
|
|||||||
query<unknown>(
|
query<unknown>(
|
||||||
`SELECT id, slug, title, subtitle, description,
|
`SELECT id, slug, title, subtitle, description,
|
||||||
status, audience, icon_key, tags, sort_order, site_url,
|
status, audience, icon_key, tags, sort_order, site_url,
|
||||||
title_en, subtitle_en, description_en
|
title_en, subtitle_en, description_en, logo_url, brand_color
|
||||||
FROM products
|
FROM products
|
||||||
WHERE is_published = true
|
WHERE is_published = true
|
||||||
ORDER BY sort_order ASC`
|
ORDER BY sort_order ASC`
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 828 B |
@@ -15,6 +15,8 @@ export interface Product {
|
|||||||
title_en?: string | null;
|
title_en?: string | null;
|
||||||
subtitle_en?: string | null;
|
subtitle_en?: string | null;
|
||||||
description_en?: string | null;
|
description_en?: string | null;
|
||||||
|
logo_url?: string | null;
|
||||||
|
brand_color?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApproachItem {
|
export interface ApproachItem {
|
||||||
|
|||||||
@@ -163,7 +163,18 @@ export function Landing() {
|
|||||||
? (STATUS_LABELS_EN[p.status] || STATUS_LABELS_EN.planned)
|
? (STATUS_LABELS_EN[p.status] || STATUS_LABELS_EN.planned)
|
||||||
: statusBadge.text;
|
: statusBadge.text;
|
||||||
return (
|
return (
|
||||||
<div key={p.id} className="bg-gradient-to-br from-slate-50 to-brand-50 border border-slate-200 rounded-3xl p-8 grid md:grid-cols-2 gap-7 items-center">
|
<div
|
||||||
|
key={p.id}
|
||||||
|
className="border rounded-3xl p-8 grid md:grid-cols-2 gap-7 items-center transition-shadow hover:shadow-md"
|
||||||
|
style={{
|
||||||
|
// Карточка в цвете самого продукта: две одинаковые серые
|
||||||
|
// плитки не давали понять, что это разные приложения.
|
||||||
|
background: p.brand_color
|
||||||
|
? `linear-gradient(135deg, ${p.brand_color}0D 0%, ${p.brand_color}1A 100%)`
|
||||||
|
: undefined,
|
||||||
|
borderColor: p.brand_color ? `${p.brand_color}33` : undefined,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex gap-2 mb-4">
|
<div className="flex gap-2 mb-4">
|
||||||
<span className={`text-xs px-2.5 py-1 rounded font-medium ${statusBadge.cls}`}>{badgeText}</span>
|
<span className={`text-xs px-2.5 py-1 rounded font-medium ${statusBadge.cls}`}>{badgeText}</span>
|
||||||
@@ -172,9 +183,19 @@ export function Landing() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3 mb-3">
|
<div className="flex items-center gap-3 mb-3">
|
||||||
<div className="w-12 h-12 bg-brand-800 rounded-xl flex items-center justify-center text-white">
|
{p.logo_url ? (
|
||||||
<ProductIcon name={p.icon_key || ''} size={24} />
|
<img
|
||||||
</div>
|
src={p.logo_url}
|
||||||
|
alt={String(pick(p, 'title') || '')}
|
||||||
|
width={48}
|
||||||
|
height={48}
|
||||||
|
className="w-12 h-12 rounded-xl object-contain bg-white border border-slate-200/70 p-1"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-12 h-12 bg-brand-800 rounded-xl flex items-center justify-center text-white">
|
||||||
|
<ProductIcon name={p.icon_key || ''} size={24} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div>
|
<div>
|
||||||
<div className="text-2xl font-medium text-brand-900 tracking-tight">{pick(p, 'title')}</div>
|
<div className="text-2xl font-medium text-brand-900 tracking-tight">{pick(p, 'title')}</div>
|
||||||
{pick(p, 'subtitle') && (
|
{pick(p, 'subtitle') && (
|
||||||
@@ -193,7 +214,8 @@ export function Landing() {
|
|||||||
href={p.site_url}
|
href={p.site_url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
className="inline-flex items-center gap-1.5 mt-5 text-sm font-medium text-brand-900 border-b border-brand-900/30 hover:border-brand-900 transition-colors"
|
className="inline-flex items-center gap-1.5 mt-5 text-sm font-medium border-b transition-colors"
|
||||||
|
style={{ color: p.brand_color || undefined, borderColor: p.brand_color ? `${p.brand_color}55` : undefined }}
|
||||||
>
|
>
|
||||||
{p.site_url.replace(/^https?:\/\//, '')}
|
{p.site_url.replace(/^https?:\/\//, '')}
|
||||||
<ArrowRightIcon width={14} height={14} />
|
<ArrowRightIcon width={14} height={14} />
|
||||||
|
|||||||
Reference in New Issue
Block a user