fix: sync header_style DB column with theme editor selections (#158)
The frontend never sent header_style/hero_divider_style as separate fields when creating or updating events, so the database columns always kept their default value of 'standard' — making the hero header impossible to enable through the admin UI. - Extract headerStyle/heroDividerStyle from theme config and include in create and update payloads (CreateEventPage, EventDetailsPage) - Add backend fallback to extract values from color_theme JSON when not explicitly provided, ensuring older clients stay in sync
This commit is contained in:
@@ -86,6 +86,14 @@ docs/*_PLAN.md
|
||||
docs/test-*.md
|
||||
docs/feature-*.md
|
||||
|
||||
# Scaffolding documentation (local development reference)
|
||||
docs/DATABASE_SCHEMA.md
|
||||
docs/BACKEND_SERVICES.md
|
||||
docs/API_ROUTES.md
|
||||
docs/FRONTEND_ARCHITECTURE.md
|
||||
docs/DEVELOPER_ONBOARDING.md
|
||||
docs/ENVIRONMENT_VARIABLES.md
|
||||
|
||||
# Local backup directory (from testing)
|
||||
backup/
|
||||
|
||||
|
||||
@@ -365,6 +365,26 @@ router.post('/', adminAuth, requirePermission('events.create'), [
|
||||
await fs.mkdir(path.join(eventPath, 'collages'), { recursive: true });
|
||||
await fs.mkdir(path.join(eventPath, 'individual'), { recursive: true });
|
||||
|
||||
// Sync header_style / hero_divider_style from color_theme JSON when not
|
||||
// explicitly provided in the request body (#158).
|
||||
let effectiveHeaderStyle = header_style;
|
||||
let effectiveDividerStyle = hero_divider_style;
|
||||
if (color_theme && (!req.body.header_style || !req.body.hero_divider_style)) {
|
||||
try {
|
||||
if (typeof color_theme === 'string' && color_theme.startsWith('{')) {
|
||||
const parsed = JSON.parse(color_theme);
|
||||
if (!req.body.header_style && parsed.headerStyle) {
|
||||
effectiveHeaderStyle = parsed.headerStyle;
|
||||
}
|
||||
if (!req.body.hero_divider_style && parsed.heroDividerStyle) {
|
||||
effectiveDividerStyle = parsed.heroDividerStyle;
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// color_theme is not JSON – nothing to extract
|
||||
}
|
||||
}
|
||||
|
||||
// Insert into database
|
||||
const insertResult = await db('events').insert({
|
||||
slug,
|
||||
@@ -394,8 +414,8 @@ router.post('/', adminAuth, requirePermission('events.create'), [
|
||||
hero_logo_visible: formatBoolean(hero_logo_visible !== undefined ? hero_logo_visible : true),
|
||||
hero_logo_size: hero_logo_size || 'medium',
|
||||
hero_logo_position: hero_logo_position || 'top',
|
||||
header_style: header_style || 'standard',
|
||||
hero_divider_style: hero_divider_style || 'wave',
|
||||
header_style: effectiveHeaderStyle || 'standard',
|
||||
hero_divider_style: effectiveDividerStyle || 'wave',
|
||||
hero_image_anchor: hero_image_anchor || 'center'
|
||||
}).returning('id');
|
||||
|
||||
@@ -810,6 +830,27 @@ router.put('/:id', adminAuth, requirePermission('events.edit'), [
|
||||
updates.hero_logo_visible = formatBoolean(updates.hero_logo_visible);
|
||||
}
|
||||
|
||||
// Sync header_style / hero_divider_style from color_theme JSON when not
|
||||
// explicitly provided in the request body (#158). This ensures the
|
||||
// database columns stay in sync even if the frontend only sends the
|
||||
// serialised theme object.
|
||||
if (updates.color_theme && !Object.prototype.hasOwnProperty.call(updates, 'header_style')) {
|
||||
try {
|
||||
const themeStr = typeof updates.color_theme === 'string' ? updates.color_theme : '';
|
||||
if (themeStr.startsWith('{')) {
|
||||
const parsed = JSON.parse(themeStr);
|
||||
if (parsed.headerStyle) {
|
||||
updates.header_style = parsed.headerStyle;
|
||||
}
|
||||
if (parsed.heroDividerStyle && !Object.prototype.hasOwnProperty.call(updates, 'hero_divider_style')) {
|
||||
updates.hero_divider_style = parsed.heroDividerStyle;
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// color_theme is not JSON (e.g. preset name) – nothing to extract
|
||||
}
|
||||
}
|
||||
|
||||
// Update event
|
||||
await db('events')
|
||||
.where('id', id)
|
||||
|
||||
@@ -292,6 +292,8 @@ export const CreateEventPage: React.FC = () => {
|
||||
password: formData.require_password ? formData.password : undefined,
|
||||
welcome_message: formData.welcome_message || '',
|
||||
color_theme: JSON.stringify(formData.theme_config),
|
||||
header_style: formData.theme_config.headerStyle || 'standard',
|
||||
hero_divider_style: formData.theme_config.heroDividerStyle || 'wave',
|
||||
expiration_days: requireExpiration ? formData.expires_in_days : undefined,
|
||||
allow_user_uploads: formData.allow_user_uploads,
|
||||
upload_category_id: formData.upload_category_id,
|
||||
|
||||
@@ -550,6 +550,9 @@ export const EventDetailsPage: React.FC = () => {
|
||||
hero_logo_position: editForm.hero_logo_position,
|
||||
// Hero image anchor position (#162)
|
||||
hero_image_anchor: editForm.hero_image_anchor,
|
||||
// Header style settings (decoupled from layout, #158)
|
||||
header_style: currentTheme?.headerStyle || 'standard',
|
||||
hero_divider_style: currentTheme?.heroDividerStyle || 'wave',
|
||||
};
|
||||
|
||||
// Only include fields that have defined values
|
||||
|
||||
Reference in New Issue
Block a user