/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
import { getStatus } from '@/lib/api'
export type ModuleAccess = { enabled: boolean; requireAuth: boolean }
export type HeaderNavModule = 'rankings' | 'pricing'
export type HeaderNavModules = {
home: boolean
console: boolean
pricing: ModuleAccess
rankings: ModuleAccess
docs: boolean
about: boolean
[key: string]: boolean | ModuleAccess
}
const DEFAULT_HEADER_NAV_MODULES: HeaderNavModules = {
home: true,
console: true,
pricing: { enabled: true, requireAuth: false },
rankings: { enabled: true, requireAuth: false },
docs: true,
about: true,
}
const DEFAULTS: Record = {
pricing: DEFAULT_HEADER_NAV_MODULES.pricing,
rankings: DEFAULT_HEADER_NAV_MODULES.rankings,
}
function cloneHeaderNavDefaults(): HeaderNavModules {
return {
...DEFAULT_HEADER_NAV_MODULES,
pricing: { ...DEFAULT_HEADER_NAV_MODULES.pricing },
rankings: { ...DEFAULT_HEADER_NAV_MODULES.rankings },
}
}
export function parseHeaderNavBoolean(
raw: unknown,
fallback: boolean
): boolean {
if (typeof raw === 'boolean') return raw
if (typeof raw === 'number') {
if (raw === 1) return true
if (raw === 0) return false
return fallback
}
if (typeof raw === 'string') {
const normalized = raw.trim().toLowerCase()
if (normalized === 'true' || normalized === '1') return true
if (normalized === 'false' || normalized === '0') return false
}
return fallback
}
function parseAccess(raw: unknown, fallback: ModuleAccess): ModuleAccess {
if (
typeof raw === 'boolean' ||
typeof raw === 'number' ||
typeof raw === 'string'
) {
return {
enabled: parseHeaderNavBoolean(raw, fallback.enabled),
requireAuth: fallback.requireAuth,
}
}
if (raw && typeof raw === 'object') {
const r = raw as Record
return {
enabled: parseHeaderNavBoolean(r.enabled, fallback.enabled),
requireAuth: parseHeaderNavBoolean(r.requireAuth, fallback.requireAuth),
}
}
return { ...fallback }
}
function parseHeaderNavRecord(raw: unknown): Record | null {
if (!raw || String(raw).trim() === '') return null
if (raw && typeof raw === 'object') return raw as Record
try {
return JSON.parse(String(raw)) as Record
} catch {
return null
}
}
export function parseHeaderNavModules(raw: unknown): HeaderNavModules {
const result = cloneHeaderNavDefaults()
const parsed = parseHeaderNavRecord(raw)
if (!parsed) return result
Object.entries(parsed).forEach(([key, value]) => {
if (key === 'pricing') {
result.pricing = parseAccess(value, result.pricing)
return
}
if (key === 'rankings') {
result.rankings = parseAccess(value, result.rankings)
return
}
const fallback = result[key]
if (
typeof fallback === 'boolean' ||
typeof value === 'boolean' ||
typeof value === 'number' ||
typeof value === 'string'
) {
result[key] = parseHeaderNavBoolean(
value,
typeof fallback === 'boolean' ? fallback : true
)
}
})
return result
}
export function parseHeaderNavModulesFromStatus(
status: Record | null
): HeaderNavModules {
return parseHeaderNavModules(status?.HeaderNavModules)
}
function getCachedStatus(): Record | null {
try {
if (typeof window === 'undefined') return null
const raw = window.localStorage.getItem('status')
return raw ? (JSON.parse(raw) as Record) : null
} catch {
return null
}
}
function cacheStatus(status: Record | null): void {
try {
if (typeof window !== 'undefined' && status) {
window.localStorage.setItem('status', JSON.stringify(status))
}
} catch {
/* empty */
}
}
export function getModuleAccessFromStatus(
status: Record | null,
module: HeaderNavModule
): ModuleAccess {
return parseHeaderNavModulesFromStatus(status)[module] ?? DEFAULTS[module]
}
export function getModuleAccess(module: HeaderNavModule): ModuleAccess {
return getModuleAccessFromStatus(getCachedStatus(), module)
}
export async function getFreshModuleAccess(
module: HeaderNavModule
): Promise {
try {
const status = (await getStatus()) as Record | null
cacheStatus(status)
return getModuleAccessFromStatus(status, module)
} catch {
return { enabled: false, requireAuth: true }
}
}
export function isSidebarModuleEnabled(
section: string,
module: string
): boolean {
const status = getCachedStatus()
if (!status) return true
const raw = status.SidebarModulesAdmin
if (!raw || String(raw).trim() === '') return true
try {
const parsed = JSON.parse(String(raw)) as Record<
string,
Record
>
const sectionConfig = parsed[section]
if (!sectionConfig) return true
if (sectionConfig.enabled === false) return false
if (sectionConfig[module] === false) return false
return true
} catch {
return true
}
}