182 lines
5.8 KiB
TypeScript
182 lines
5.8 KiB
TypeScript
import type { IBenefits } from '@/model/banner'
|
|
|
|
/** کلید واحد همهٔ بنرهای اپ (اسلایدر + تم لایت/دارک) */
|
|
export const APP_BANNERS_CONST_KEY = 'app_banners'
|
|
|
|
/** کلید قدیمی تم — فقط برای مهاجرت خواندن */
|
|
export const LEGACY_THEME_BANNERS_CONST_KEY = 'settings_profile_banners'
|
|
|
|
/** کلید قدیمی اسلایدر — فقط برای مهاجرت خواندن */
|
|
export const LEGACY_SLIDER_BANNERS_CONST_KEY = 'header_banner'
|
|
|
|
export type AppThemeBannerKey =
|
|
| 'homeAsset'
|
|
| 'piggyCreate'
|
|
| 'referral'
|
|
| 'share'
|
|
| 'invite'
|
|
|
|
/** @deprecated از AppThemeBannerKey استفاده کنید */
|
|
export type SettingsProfileBannerKey = AppThemeBannerKey
|
|
|
|
export interface ThemeImagePair {
|
|
light: string | null
|
|
dark: string | null
|
|
}
|
|
|
|
export interface AppBannersValue {
|
|
slider: IBenefits[]
|
|
homeAsset: ThemeImagePair
|
|
piggyCreate: ThemeImagePair
|
|
/** اسلایدر بنر بالای صفحهٔ محصولات — تعداد آزاد */
|
|
productsHero: ThemeImagePair[]
|
|
referral: ThemeImagePair
|
|
share: ThemeImagePair
|
|
invite: ThemeImagePair
|
|
}
|
|
|
|
/** @deprecated از AppBannersValue استفاده کنید */
|
|
export type SettingsProfileBannersValue = Omit<AppBannersValue, 'slider'>
|
|
|
|
export const SETTINGS_PROFILE_BANNERS_CONST_KEY = APP_BANNERS_CONST_KEY
|
|
|
|
export function emptyThemePair(): ThemeImagePair {
|
|
return { light: null, dark: null }
|
|
}
|
|
|
|
export function emptyAppBanners(): AppBannersValue {
|
|
return {
|
|
slider: [],
|
|
homeAsset: emptyThemePair(),
|
|
piggyCreate: emptyThemePair(),
|
|
productsHero: [],
|
|
referral: emptyThemePair(),
|
|
share: emptyThemePair(),
|
|
invite: emptyThemePair(),
|
|
}
|
|
}
|
|
|
|
export function emptySettingsProfileBanners(): SettingsProfileBannersValue {
|
|
const { slider: _slider, ...themes } = emptyAppBanners()
|
|
return themes
|
|
}
|
|
|
|
function normalizePair(raw: unknown): ThemeImagePair {
|
|
if (!raw || typeof raw !== 'object') return emptyThemePair()
|
|
const obj = raw as Record<string, unknown>
|
|
return {
|
|
light: typeof obj.light === 'string' && obj.light.trim() ? obj.light : null,
|
|
dark: typeof obj.dark === 'string' && obj.dark.trim() ? obj.dark : null,
|
|
}
|
|
}
|
|
|
|
function pairHasImage(pair: ThemeImagePair): boolean {
|
|
return Boolean(pair.light || pair.dark)
|
|
}
|
|
|
|
/** همهٔ اسلاتهای تم خالیاند (رکورد app_banners پوچ که روی legacy سایه انداخته) */
|
|
export function isThemeBannersEmpty(data: AppBannersValue): boolean {
|
|
return (
|
|
!pairHasImage(data.homeAsset) &&
|
|
!pairHasImage(data.piggyCreate) &&
|
|
!(data.productsHero ?? []).some(pairHasImage) &&
|
|
!pairHasImage(data.referral) &&
|
|
!pairHasImage(data.share) &&
|
|
!pairHasImage(data.invite)
|
|
)
|
|
}
|
|
|
|
function mergePair(primary: ThemeImagePair, legacy: ThemeImagePair): ThemeImagePair {
|
|
return {
|
|
light: primary.light || legacy.light,
|
|
dark: primary.dark || legacy.dark,
|
|
}
|
|
}
|
|
|
|
/** اسلات خالی primary را از legacy پر میکند؛ اسلایدر/محصولات اگر آرایه خالی باشد از legacy میآید */
|
|
export function mergeAppBannersFromLegacy(
|
|
primary: AppBannersValue,
|
|
legacy: AppBannersValue,
|
|
): AppBannersValue {
|
|
return {
|
|
slider: primary.slider.length ? primary.slider : legacy.slider,
|
|
homeAsset: mergePair(primary.homeAsset, legacy.homeAsset),
|
|
piggyCreate: mergePair(primary.piggyCreate, legacy.piggyCreate),
|
|
productsHero: (primary.productsHero ?? []).some(pairHasImage)
|
|
? primary.productsHero
|
|
: legacy.productsHero ?? [],
|
|
referral: mergePair(primary.referral, legacy.referral),
|
|
share: mergePair(primary.share, legacy.share),
|
|
invite: mergePair(primary.invite, legacy.invite),
|
|
}
|
|
}
|
|
|
|
/** آرایهٔ جدید یا سه اسلات قدیمی productsHero1/2/3 */
|
|
export function normalizeProductsHero(parsed: Record<string, unknown>): ThemeImagePair[] {
|
|
if (Array.isArray(parsed.productsHero)) {
|
|
return parsed.productsHero.map(normalizePair)
|
|
}
|
|
|
|
return [parsed.productsHero1, parsed.productsHero2, parsed.productsHero3]
|
|
.map(normalizePair)
|
|
.filter(pairHasImage)
|
|
}
|
|
|
|
function parseSlider(raw: unknown): IBenefits[] {
|
|
if (!raw) return []
|
|
if (Array.isArray(raw)) return raw as IBenefits[]
|
|
if (typeof raw === 'string') {
|
|
try {
|
|
const parsed = JSON.parse(raw)
|
|
return Array.isArray(parsed) ? (parsed as IBenefits[]) : []
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
return []
|
|
}
|
|
|
|
export function parseAppBanners(value: string | Record<string, unknown> | null | undefined): AppBannersValue {
|
|
const fallback = emptyAppBanners()
|
|
if (!value) return fallback
|
|
try {
|
|
const parsed = typeof value === 'string' ? JSON.parse(value) : value
|
|
if (!parsed || typeof parsed !== 'object') return fallback
|
|
|
|
// فرمت قدیمی: فقط آرایهٔ اسلایدر (header_banner)
|
|
if (Array.isArray(parsed)) {
|
|
return { ...fallback, slider: parsed as IBenefits[] }
|
|
}
|
|
|
|
const obj = parsed as Record<string, unknown>
|
|
return {
|
|
slider: parseSlider(obj.slider),
|
|
homeAsset: normalizePair(obj.homeAsset),
|
|
piggyCreate: normalizePair(obj.piggyCreate),
|
|
productsHero: normalizeProductsHero(obj),
|
|
referral: normalizePair(obj.referral),
|
|
share: normalizePair(obj.share),
|
|
invite: normalizePair(obj.invite),
|
|
}
|
|
} catch {
|
|
return fallback
|
|
}
|
|
}
|
|
|
|
export function parseSettingsProfileBanners(value: string | null | undefined): SettingsProfileBannersValue {
|
|
const { slider: _slider, ...themes } = parseAppBanners(value)
|
|
return themes
|
|
}
|
|
|
|
export function serializeAppBanners(data: AppBannersValue): string {
|
|
return JSON.stringify({
|
|
slider: data.slider ?? [],
|
|
homeAsset: { ...data.homeAsset },
|
|
piggyCreate: { ...data.piggyCreate },
|
|
productsHero: (data.productsHero ?? []).map((pair) => ({ ...pair })),
|
|
referral: { ...data.referral },
|
|
share: { ...data.share },
|
|
invite: { ...data.invite },
|
|
})
|
|
}
|