diff --git a/src/config/defaultHamkarUiConfig.ts b/src/config/defaultHamkarUiConfig.ts index 7651421..6760ab3 100644 --- a/src/config/defaultHamkarUiConfig.ts +++ b/src/config/defaultHamkarUiConfig.ts @@ -9,6 +9,10 @@ export type HamkarBrandColors = { secondaryColor: string /** Registry `background_color` → CSS `--bg` (dynamicMode) */ backgroundColor: string + /** Menu / header icon stroke (brand_chrome) */ + menuIconColor: string + /** Selected menu icon + label (brand_chrome) */ + menuIconActiveColor: string } export type HamkarUiSettings = { @@ -102,6 +106,8 @@ function normalizeBrand(raw: unknown): HamkarBrandColors { primaryColor: asColor(brand.primaryColor), secondaryColor: asColor(brand.secondaryColor), backgroundColor: asColor(brand.backgroundColor), + menuIconColor: asColor(brand.menuIconColor), + menuIconActiveColor: asColor(brand.menuIconActiveColor), } } @@ -115,6 +121,8 @@ export function createDefaultHamkarUiConfig(): HamkarUiConfig { primaryColor: '', secondaryColor: '', backgroundColor: '', + menuIconColor: '', + menuIconActiveColor: '', }, settings: { pricing_box_theme: '1', @@ -177,6 +185,10 @@ export function hamkarUiToApiPayload(config: HamkarUiConfig) { primaryColor: emptyToNull(normalized.defaultSnapshot.brand.primaryColor), secondaryColor: emptyToNull(normalized.defaultSnapshot.brand.secondaryColor), backgroundColor: emptyToNull(normalized.defaultSnapshot.brand.backgroundColor), + menuIconColor: emptyToNull(normalized.defaultSnapshot.brand.menuIconColor), + menuIconActiveColor: emptyToNull( + normalized.defaultSnapshot.brand.menuIconActiveColor, + ), }, settings: { ...normalized.defaultSnapshot.settings }, } @@ -191,6 +203,8 @@ export function hamkarUiToApiPayload(config: HamkarUiConfig) { primaryColor: emptyToNull(normalized.brand.primaryColor), secondaryColor: emptyToNull(normalized.brand.secondaryColor), backgroundColor: emptyToNull(normalized.brand.backgroundColor), + menuIconColor: emptyToNull(normalized.brand.menuIconColor), + menuIconActiveColor: emptyToNull(normalized.brand.menuIconActiveColor), }, settings: { ...normalized.settings }, ...(snap ? { defaultSnapshot: snap } : {}), diff --git a/src/pages/HamkarUiConfigPage.vue b/src/pages/HamkarUiConfigPage.vue index 6d1ca2e..8b4a64a 100644 --- a/src/pages/HamkarUiConfigPage.vue +++ b/src/pages/HamkarUiConfigPage.vue @@ -75,6 +75,8 @@ const palette = computed(() => ({ header: swatchHex(config.brand.primaryColor, '#ffffff'), accent: swatchHex(config.brand.secondaryColor, '#2563EB'), page: swatchHex(config.brand.backgroundColor, '#fafafa'), + menuIcon: swatchHex(config.brand.menuIconColor, textOn(swatchHex(config.brand.primaryColor, '#ffffff'))), + menuIconActive: swatchHex(config.brand.menuIconActiveColor, '#2563EB'), })) const previewChrome = computed(() => { @@ -99,8 +101,14 @@ const previewChrome = computed(() => { color: onHeader, borderTop: headerEdge, }, + brandFooter: { + background: p.header, + color: p.menuIcon, + }, accent: p.accent, - muted: onHeader === '#ffffff' ? 'rgba(255,255,255,0.72)' : '#616161', + menuIcon: p.menuIcon, + menuIconActive: p.menuIconActive, + muted: p.menuIcon, } }) @@ -120,6 +128,14 @@ function seedEditableColors(normalized: HamkarUiConfig) { if (!normalized.brand.secondaryColor) normalized.brand.secondaryColor = effective.accent if (!normalized.brand.backgroundColor) normalized.brand.backgroundColor = effective.pageBg } + if (!normalized.brand.menuIconColor) { + normalized.brand.menuIconColor = textOn( + swatchHex(normalized.brand.primaryColor, effective.headerBg), + ) + } + if (!normalized.brand.menuIconActiveColor) { + normalized.brand.menuIconActiveColor = effective.accent + } } function ensureDefaultSnapshot( @@ -148,6 +164,8 @@ function ensureDefaultSnapshot( primaryColor: String(opts.primaryColor || normalized.brand.primaryColor || ''), secondaryColor: String(opts.secondaryColor || normalized.brand.secondaryColor || ''), backgroundColor: String(opts.backgroundColor || normalized.brand.backgroundColor || ''), + menuIconColor: String(normalized.brand.menuIconColor || ''), + menuIconActiveColor: String(normalized.brand.menuIconActiveColor || ''), }, settings: { ...normalized.settings }, }) @@ -267,6 +285,8 @@ function resetToDefault() { config.brand.primaryColor = snap.brand.primaryColor config.brand.secondaryColor = snap.brand.secondaryColor config.brand.backgroundColor = snap.brand.backgroundColor + config.brand.menuIconColor = snap.brand.menuIconColor + config.brand.menuIconActiveColor = snap.brand.menuIconActiveColor config.settings = { ...snap.settings } // Named factory modes must not keep brand chrome overrides. config.brandManaged = snap.registryMode === 'dynamicMode' @@ -328,15 +348,20 @@ onMounted(load) v-for="(item, i) in NAV_ITEMS" :key="item" class="app-preview-nav" - :style="{ color: i === 0 ? previewChrome.accent : previewChrome.muted }" + :style="{ color: i === 0 ? previewChrome.menuIconActive : previewChrome.menuIcon }" > {{ item }} +
+ توسعه و طراحی توسط +
@@ -399,6 +424,40 @@ onMounted(load) class="palette-hex" /> + + + + @@ -582,6 +641,13 @@ onMounted(load) gap: 12px; } +.app-preview-brand { + padding: 6px 10px; + text-align: center; + font-size: 10px; + font-weight: 600; +} + @media (max-width: 768px) { .palette-grid { grid-template-columns: 1fr;