/* 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 { create } from 'zustand' import { persist } from 'zustand/middleware' import { DEFAULT_SYSTEM_NAME, DEFAULT_LOGO } from '@/lib/constants' export type CurrencyDisplayType = 'USD' | 'CNY' | 'TOKENS' | 'CUSTOM' export interface CurrencyConfig { /** Whether to render quota values as currency instead of raw units */ displayInCurrency: boolean /** Currency presentation strategy configured by the admin */ quotaDisplayType: CurrencyDisplayType /** Number of quota units that equal one USD */ quotaPerUnit: number /** Exchange rate from USD to the configured local currency */ usdExchangeRate: number /** Custom currency symbol configured by the admin (used when type === CUSTOM) */ customCurrencySymbol: string /** Exchange rate from USD to the custom currency (used when type === CUSTOM) */ customCurrencyExchangeRate: number } export interface SystemConfig { systemName: string logo: string footerHtml?: string demoSiteEnabled?: boolean displayTokenStatEnabled?: boolean currency: CurrencyConfig } export const DEFAULT_CURRENCY_CONFIG: CurrencyConfig = { displayInCurrency: true, quotaDisplayType: 'USD', quotaPerUnit: 500000, usdExchangeRate: 1, customCurrencySymbol: 'ยค', customCurrencyExchangeRate: 1, } interface SystemConfigState { config: SystemConfig loading: boolean loadedLogoUrl: string setConfig: (config: Partial) => void setLoadedLogoUrl: (url: string) => void setLoading: (loading: boolean) => void } /** * System configuration store with automatic persistence * Manages system name, logo, footer HTML and loading states */ export const useSystemConfigStore = create()( persist( (set) => ({ config: { systemName: DEFAULT_SYSTEM_NAME, logo: DEFAULT_LOGO, currency: { ...DEFAULT_CURRENCY_CONFIG }, }, loading: true, loadedLogoUrl: DEFAULT_LOGO, setConfig: (newConfig) => set((state) => ({ config: { ...state.config, ...newConfig, currency: { ...state.config.currency, ...(newConfig.currency ?? {}), }, }, })), setLoadedLogoUrl: (url) => set({ loadedLogoUrl: url }), setLoading: (loading) => set({ loading }), }), { name: 'system-config-storage', partialize: (state) => ({ config: state.config, loadedLogoUrl: state.loadedLogoUrl, }), } ) ) // Selector helpers for convenience export const getSystemName = () => useSystemConfigStore.getState().config.systemName export const getLogo = () => useSystemConfigStore.getState().config.logo export const getFooterHtml = () => useSystemConfigStore.getState().config.footerHtml