Исправлена подсветка шаблонов, добавлен макет тестовый список, исправлены проблемы со шрифтами
- Добавлено поле template_id в модель DesignSettings - Исправлена логика подсветки выбранного шаблона в TemplatesSelector - Добавлен новый макет 'test-list' - полный несворачиваемый список - Обновлены шрифты с поддержкой CSS переменных - Создан CSS модуль для тестового списка - Обеспечена совместимость иконок во всех макетах
This commit is contained in:
@@ -6,6 +6,7 @@ import { designTemplates, DesignTemplate } from '../constants/designTemplates'
|
||||
|
||||
interface DesignSettings {
|
||||
id?: number
|
||||
template_id?: string
|
||||
theme_color: string
|
||||
background_image?: string
|
||||
background_image_url?: string
|
||||
@@ -92,6 +93,7 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
|
||||
const formData = new FormData()
|
||||
|
||||
// Добавляем все настройки
|
||||
formData.append('template_id', settings.template_id || '')
|
||||
formData.append('theme_color', settings.theme_color)
|
||||
formData.append('dashboard_layout', settings.dashboard_layout)
|
||||
formData.append('groups_default_expanded', settings.groups_default_expanded.toString())
|
||||
@@ -135,6 +137,7 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
|
||||
} else {
|
||||
// Если файл не выбран, отправляем только JSON настройки (картинка остается прежней)
|
||||
const editableSettings = {
|
||||
template_id: settings.template_id,
|
||||
theme_color: settings.theme_color,
|
||||
dashboard_layout: settings.dashboard_layout,
|
||||
groups_default_expanded: settings.groups_default_expanded,
|
||||
@@ -144,7 +147,6 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
|
||||
font_family: settings.font_family,
|
||||
custom_css: settings.custom_css,
|
||||
header_text_color: settings.header_text_color || '#000000',
|
||||
header_text_color: settings.header_text_color || '#000000',
|
||||
group_text_color: settings.group_text_color || '#333333',
|
||||
link_text_color: settings.link_text_color || '#666666',
|
||||
cover_overlay_enabled: settings.cover_overlay_enabled || false,
|
||||
@@ -195,10 +197,31 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
|
||||
setSettings(prev => ({
|
||||
...prev,
|
||||
...template.settings,
|
||||
id: prev.id // Сохраняем оригинальный ID
|
||||
id: prev.id, // Сохраняем оригинальный ID
|
||||
template_id: template.id // Добавляем ID шаблона для отслеживания
|
||||
}))
|
||||
}
|
||||
|
||||
// Определяем текущий шаблон
|
||||
const getCurrentTemplateId = () => {
|
||||
// Если есть сохраненный template_id
|
||||
if ((settings as any).template_id) {
|
||||
return (settings as any).template_id
|
||||
}
|
||||
|
||||
// Или пытаемся определить по совпадению настроек
|
||||
for (const template of designTemplates) {
|
||||
if (
|
||||
template.settings.theme_color === settings.theme_color &&
|
||||
template.settings.background_color === settings.dashboard_background_color &&
|
||||
template.settings.dashboard_layout === settings.dashboard_layout
|
||||
) {
|
||||
return template.id
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (!isOpen) return null
|
||||
|
||||
return (
|
||||
@@ -328,6 +351,12 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
|
||||
label: 'Журнальный',
|
||||
icon: 'bi-newspaper',
|
||||
description: 'Стиль журнала с крупными изображениями'
|
||||
},
|
||||
{
|
||||
value: 'test-list',
|
||||
label: 'Тестовый список',
|
||||
icon: 'bi-list-check',
|
||||
description: 'Полный несворачиваемый список всех групп и ссылок'
|
||||
}
|
||||
].map((layout) => (
|
||||
<div key={layout.value} className="col-md-6 col-lg-4">
|
||||
@@ -683,7 +712,7 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
|
||||
<div className="tab-pane fade show active">
|
||||
<TemplatesSelector
|
||||
onTemplateSelect={handleTemplateSelect}
|
||||
currentTemplate={undefined} // Можно добавить определение текущего шаблона
|
||||
currentTemplate={getCurrentTemplateId()}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import React from 'react'
|
||||
import { designTemplates, DesignTemplate } from '../constants/designTemplates'
|
||||
import styles from './TemplatesSelector.module.css'
|
||||
|
||||
interface TemplatesSelectorProps {
|
||||
onTemplateSelect: (template: DesignTemplate) => void
|
||||
@@ -10,13 +9,16 @@ interface TemplatesSelectorProps {
|
||||
}
|
||||
|
||||
export function TemplatesSelector({ onTemplateSelect, currentTemplate }: TemplatesSelectorProps) {
|
||||
const handleTemplateClick = (template: DesignTemplate) => {
|
||||
const handleTemplateClick = (template: DesignTemplate, event: React.MouseEvent) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
console.log('Template clicked:', template.name)
|
||||
console.log('onTemplateSelect function:', onTemplateSelect)
|
||||
onTemplateSelect(template)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.templateSelector}>
|
||||
<div>
|
||||
<h6 className="mb-3">
|
||||
<i className="bi bi-palette me-2"></i>
|
||||
Готовые шаблоны
|
||||
@@ -24,90 +26,72 @@ export function TemplatesSelector({ onTemplateSelect, currentTemplate }: Templat
|
||||
<div className="row g-3">
|
||||
{designTemplates.map((template) => (
|
||||
<div key={template.id} className="col-md-6 col-lg-4">
|
||||
<div
|
||||
className={`${styles.templateCard} card h-100 ${currentTemplate === template.id ? `${styles.selected} border-primary` : 'border-secondary'}`}
|
||||
onClick={() => handleTemplateClick(template)}
|
||||
<button
|
||||
className={`btn w-100 h-100 p-0 border ${currentTemplate === template.id ? 'border-primary' : 'border-secondary'}`}
|
||||
onClick={(e) => handleTemplateClick(template, e)}
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
className={styles.templatePreview}
|
||||
style={{
|
||||
background: template.settings.background_color,
|
||||
}}
|
||||
>
|
||||
{/* Мини-превью дизайна */}
|
||||
<div className={styles.previewContent}>
|
||||
<div>
|
||||
<div
|
||||
className={styles.previewHeader}
|
||||
style={{
|
||||
backgroundColor: template.settings.header_text_color,
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
className={styles.previewSubtitle}
|
||||
style={{
|
||||
backgroundColor: template.settings.group_text_color,
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className={styles.previewButton}
|
||||
style={{
|
||||
backgroundColor: template.settings.theme_color,
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
className={styles.previewText}
|
||||
style={{
|
||||
backgroundColor: template.settings.link_text_color,
|
||||
}}
|
||||
></div>
|
||||
<div className="card h-100">
|
||||
<div
|
||||
className="card-img-top"
|
||||
style={{
|
||||
height: '120px',
|
||||
background: template.settings.background_color || '#ffffff',
|
||||
position: 'relative'
|
||||
}}
|
||||
>
|
||||
{/* Простое превью */}
|
||||
<div className="p-3 h-100 d-flex flex-column justify-content-between">
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
height: '20px',
|
||||
backgroundColor: template.settings.header_text_color || '#000',
|
||||
borderRadius: '4px',
|
||||
opacity: 0.8,
|
||||
width: '70%',
|
||||
marginBottom: '8px'
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
style={{
|
||||
height: '12px',
|
||||
backgroundColor: template.settings.group_text_color || '#666',
|
||||
borderRadius: '2px',
|
||||
opacity: 0.6,
|
||||
width: '50%'
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
height: '24px',
|
||||
backgroundColor: template.settings.theme_color || '#007bff',
|
||||
borderRadius: '6px',
|
||||
width: '80%',
|
||||
marginBottom: '4px'
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Overlay для демонстрации */}
|
||||
{template.settings.group_overlay_enabled && (
|
||||
<div
|
||||
className={styles.overlayDemo}
|
||||
style={{
|
||||
backgroundColor: template.settings.group_overlay_color || '#000000',
|
||||
opacity: template.settings.group_overlay_opacity || 0.3,
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
<div className="card-body">
|
||||
<h6 className="card-title">{template.name}</h6>
|
||||
<p className="card-text small text-muted">{template.description}</p>
|
||||
|
||||
{currentTemplate === template.id && (
|
||||
<div className="mt-2">
|
||||
<span className="badge bg-primary">
|
||||
<i className="bi bi-check-lg me-1"></i>
|
||||
Выбран
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card-body p-3">
|
||||
<h6
|
||||
className="card-title mb-2"
|
||||
style={{
|
||||
fontFamily: template.settings.heading_font_family || template.settings.font_family,
|
||||
color: template.settings.header_text_color
|
||||
}}
|
||||
>
|
||||
{template.name}
|
||||
</h6>
|
||||
<p
|
||||
className="card-text small mb-0"
|
||||
style={{
|
||||
fontFamily: template.settings.body_font_family || template.settings.font_family,
|
||||
color: template.settings.group_description_text_color
|
||||
}}
|
||||
>
|
||||
{template.description}
|
||||
</p>
|
||||
|
||||
{currentTemplate === template.id && (
|
||||
<div className="mt-2">
|
||||
<span className="badge bg-primary">
|
||||
<i className="bi bi-check-lg me-1"></i>
|
||||
Выбран
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user