feat: Добавлены шаблоны дизайна и управление большими группами
Some checks failed
continuous-integration/drone/push Build is failing

- Система готовых шаблонов (8 шт): Minimalist, Dark, Corporate, Creative, Nature, Retro, Neon, Soft
- Компонент ExpandableGroup для автоматического сворачивания больших списков ссылок
- Визуальный селектор шаблонов с превью в CustomizationPanel
- Поддержка во всех макетах (timeline, masonry, magazine, cards)
- CSS модули для улучшенной стилизации
- Настраиваемые лимиты отображения для разных макетов (5, 8, 3-5 ссылок)
- Полная интеграция с overlay системой и кастомными шрифтами
This commit is contained in:
2025-11-09 10:53:45 +09:00
parent 5ddc30fe0e
commit 644a0487e1
8 changed files with 1011 additions and 91 deletions

View File

@@ -6,6 +6,7 @@ import Image from 'next/image'
import Link from 'next/link'
import { useEffect, useState, Fragment } from 'react'
import FontLoader from '../components/FontLoader'
import ExpandableGroup from '../components/ExpandableGroup'
interface LinkItem {
id: number
@@ -654,37 +655,13 @@ export default function UserPage({
{group.description && (
<p className="text-muted small mb-3">{group.description}</p>
)}
{group.links.map(link => (
<Link
key={link.id}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="d-block text-decoration-none mb-2"
>
<div className="p-2 border rounded hover-shadow"
style={{
borderColor: designSettings.theme_color + '40',
transition: 'all 0.2s ease'
}}
>
<div className="d-flex align-items-center">
{link.icon_url && designSettings.show_link_icons && (
<img
src={link.icon_url}
width={16}
height={16}
className="me-2 rounded"
alt={link.title}
/>
)}
<small className="text-truncate" style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
{link.title}
</small>
</div>
</div>
</Link>
))}
<ExpandableGroup
links={group.links}
layout="cards"
initialShowCount={8}
overlayColor={designSettings.group_overlay_enabled ? designSettings.group_overlay_color : undefined}
overlayOpacity={designSettings.group_overlay_enabled ? designSettings.group_overlay_opacity : undefined}
/>
</div>
</div>
</div>
@@ -755,33 +732,13 @@ export default function UserPage({
{group.description}
</p>
)}
{group.links.slice(0, 5).map(link => (
<Link
key={link.id}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="d-block text-decoration-none mb-2"
>
<div className="d-flex align-items-center">
{link.icon_url && designSettings.show_link_icons && (
<img
src={link.icon_url}
width={16}
height={16}
className="me-2 rounded"
alt={link.title}
/>
)}
<small style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
{link.title}
</small>
</div>
</Link>
))}
{group.links.length > 5 && (
<small className="text-muted">+{group.links.length - 5} еще...</small>
)}
<ExpandableGroup
links={group.links}
layout="timeline"
initialShowCount={5}
overlayColor={designSettings.group_overlay_enabled ? designSettings.group_overlay_color : undefined}
overlayOpacity={designSettings.group_overlay_enabled ? designSettings.group_overlay_opacity : undefined}
/>
</div>
</div>
<div className="card-footer">
@@ -861,38 +818,13 @@ export default function UserPage({
{group.description || `${group.links.length} ссылок в этой группе`}
</p>
<div className="links-preview">
{group.links.slice(0, index === 0 ? 5 : 3).map(link => (
<Link
key={link.id}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="d-block text-decoration-none mb-2"
>
<div className="d-flex align-items-center p-2 border rounded hover-shadow"
style={{
borderColor: designSettings.theme_color + '40',
transition: 'all 0.2s ease'
}}
>
{link.icon_url && designSettings.show_link_icons && (
<img
src={link.icon_url}
width={16}
height={16}
className="me-2 rounded"
alt={link.title}
/>
)}
<small style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
{link.title}
</small>
</div>
</Link>
))}
{group.links.length > (index === 0 ? 5 : 3) && (
<small className="text-muted">и еще {group.links.length - (index === 0 ? 5 : 3)}...</small>
)}
<ExpandableGroup
links={group.links}
layout="magazine"
initialShowCount={index === 0 ? 5 : 3}
overlayColor={designSettings.group_overlay_enabled ? designSettings.group_overlay_color : undefined}
overlayOpacity={designSettings.group_overlay_enabled ? designSettings.group_overlay_opacity : undefined}
/>
</div>
</div>
</div>