Add color overlay settings for link buttons

- Added link_overlay_enabled, link_overlay_color, link_overlay_opacity to DesignSettings model
- Created migration 0008 for new fields
- Updated CustomizationPanel with link overlay controls section
- Added validation for new overlay settings in serializer
- Updated PublicDesignSettingsSerializer to include overlay settings
- Applied link overlay to all ExpandableGroup components in public page
- Added preview in customization panel for link overlay effect
This commit is contained in:
2025-11-09 13:00:25 +09:00
parent cefd884172
commit d59c1ad42a
7 changed files with 267 additions and 6 deletions

View File

@@ -62,6 +62,10 @@ interface PublicDesignSettings {
cover_overlay_enabled?: boolean
cover_overlay_color?: string
cover_overlay_opacity?: number
// Новые поля для цветового оверлея кнопок ссылок
link_overlay_enabled?: boolean
link_overlay_color?: string
link_overlay_opacity?: number
}
export default function UserPage({
@@ -315,6 +319,8 @@ export default function UserPage({
initialShowCount={5}
className=""
linkClassName="btn btn-outline-primary btn-sm d-flex align-items-center justify-content-start"
overlayColor={designSettings.link_overlay_enabled ? designSettings.link_overlay_color : undefined}
overlayOpacity={designSettings.link_overlay_enabled ? designSettings.link_overlay_opacity : undefined}
/>
</div>
</div>
@@ -474,6 +480,8 @@ export default function UserPage({
initialShowCount={10}
className="row"
linkClassName="col-auto mb-1"
overlayColor={designSettings.link_overlay_enabled ? designSettings.link_overlay_color : undefined}
overlayOpacity={designSettings.link_overlay_enabled ? designSettings.link_overlay_opacity : undefined}
/>
</div>
</div>
@@ -554,6 +562,8 @@ export default function UserPage({
initialShowCount={6}
className="row"
linkClassName="col-12 col-md-6 col-lg-4 mb-3"
overlayColor={designSettings.link_overlay_enabled ? designSettings.link_overlay_color : undefined}
overlayOpacity={designSettings.link_overlay_enabled ? designSettings.link_overlay_opacity : undefined}
/>
</div>
</div>
@@ -687,8 +697,8 @@ export default function UserPage({
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}
overlayColor={designSettings.link_overlay_enabled ? designSettings.link_overlay_color : undefined}
overlayOpacity={designSettings.link_overlay_enabled ? designSettings.link_overlay_opacity : undefined}
/>
</div>
</div>
@@ -773,8 +783,8 @@ export default function UserPage({
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}
overlayColor={designSettings.link_overlay_enabled ? designSettings.link_overlay_color : undefined}
overlayOpacity={designSettings.link_overlay_enabled ? designSettings.link_overlay_opacity : undefined}
/>
</div>
</div>

View File

@@ -31,6 +31,10 @@ interface DesignSettings {
group_description_text_color?: string
body_font_family?: string
heading_font_family?: string
// Новые поля для цветового оверлея кнопок ссылок
link_overlay_enabled?: boolean
link_overlay_color?: string
link_overlay_opacity?: number
}
interface CustomizationPanelProps {
@@ -115,6 +119,9 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
formData.append('group_description_text_color', settings.group_description_text_color || '#666666')
formData.append('body_font_family', settings.body_font_family || 'sans-serif')
formData.append('heading_font_family', settings.heading_font_family || 'sans-serif')
formData.append('link_overlay_enabled', (settings.link_overlay_enabled || false).toString())
formData.append('link_overlay_color', settings.link_overlay_color || '#000000')
formData.append('link_overlay_opacity', (settings.link_overlay_opacity || 0.2).toString())
formData.append('background_image', backgroundImageFile)
const response = await fetch(`${API}/api/customization/settings/`, {
@@ -158,7 +165,10 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
show_groups_title: settings.show_groups_title !== false,
group_description_text_color: settings.group_description_text_color || '#666666',
body_font_family: settings.body_font_family || 'sans-serif',
heading_font_family: settings.heading_font_family || 'sans-serif'
heading_font_family: settings.heading_font_family || 'sans-serif',
link_overlay_enabled: settings.link_overlay_enabled || false,
link_overlay_color: settings.link_overlay_color || '#000000',
link_overlay_opacity: settings.link_overlay_opacity || 0.2
}
const response = await fetch(`${API}/api/customization/settings/`, {
@@ -703,6 +713,90 @@ export function CustomizationPanel({ isOpen, onClose, onSettingsUpdate }: Custom
Чтобы настроить конкретную группу (публичность, избранное, разворачивание), используйте кнопку редактирования рядом с названием группы в основном списке.
</div>
</div>
{/* Секция цветового оверлея кнопок ссылок */}
<div className="col-12 mt-4">
<div className="border rounded p-3">
<div className="d-flex align-items-center justify-content-between mb-3">
<h6 className="mb-0">Цветовое перекрытие кнопок ссылок</h6>
<div className="form-check form-switch">
<input
className="form-check-input"
type="checkbox"
id="linkOverlay"
checked={settings.link_overlay_enabled || false}
onChange={(e) => {
console.log('Link overlay enabled:', e.target.checked)
handleChange('link_overlay_enabled', e.target.checked)
}}
/>
<label className="form-check-label" htmlFor="linkOverlay">
Включить цветовое перекрытие кнопок ссылок
</label>
</div>
</div>
<div className="row">
{settings.link_overlay_enabled && (
<>
<div className="col-md-6 mb-3">
<label className="form-label">Цвет перекрытия</label>
<input
type="color"
className="form-control form-control-color"
value={settings.link_overlay_color || '#000000'}
onChange={(e) => {
console.log('Link overlay color:', e.target.value)
handleChange('link_overlay_color', e.target.value)
}}
/>
</div>
<div className="col-md-6 mb-3">
<label className="form-label">
Прозрачность ({Math.round((settings.link_overlay_opacity || 0.2) * 100)}%)
</label>
<input
type="range"
className="form-range"
min="0"
max="1"
step="0.1"
value={settings.link_overlay_opacity || 0.2}
onChange={(e) => {
const value = parseFloat(e.target.value)
console.log('Link overlay opacity:', value)
handleChange('link_overlay_opacity', value)
}}
/>
</div>
<div className="col-12">
<label className="form-label">Предварительный просмотр</label>
<div className="position-relative rounded" style={{ height: '60px', border: '1px solid #dee2e6', overflow: 'hidden' }}>
<div
className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center"
style={{
backgroundColor: '#f8f9fa',
color: '#333',
fontSize: '14px',
fontWeight: '500'
}}
>
Кнопка ссылки
</div>
<div
className="position-absolute top-0 start-0 w-100 h-100"
style={{
backgroundColor: settings.link_overlay_color || '#000000',
opacity: settings.link_overlay_opacity || 0.2,
}}
></div>
</div>
</div>
</>
)}
</div>
</div>
</div>
</div>
</div>
)}