feat: integrate site display type into pricing components

Add siteDisplayType prop across various pricing components to conditionally render pricing information based on the selected display type. This update enhances the user experience by ensuring that pricing details are accurately represented according to the chosen display mode, particularly for token-based views.
This commit is contained in:
CaIon
2026-03-07 00:23:36 +08:00
parent aa89ea2db5
commit 287af7ebee
26 changed files with 963 additions and 663 deletions

View File

@@ -150,7 +150,9 @@ export const useHeaderBar = ({ onMobileMenuToggle, drawerOpen }) => {
const handleLanguageChange = useCallback(
async (lang) => {
// Change language immediately for responsive UX
const previousLang = normalizeLanguage(i18n.language);
i18n.changeLanguage(lang);
localStorage.setItem('i18nextLng', lang);
// If user is logged in, save preference to backend
if (userState?.user?.id) {
@@ -159,25 +161,34 @@ export const useHeaderBar = ({ onMobileMenuToggle, drawerOpen }) => {
language: lang,
});
if (res.data.success) {
// Update user context with new setting
// Keep user preference and local cache in sync so route changes
// don't reapply an older remembered language.
let settings = {};
if (userState?.user?.setting) {
try {
const settings = JSON.parse(userState.user.setting);
settings.language = lang;
userDispatch({
type: 'login',
payload: {
...userState.user,
setting: JSON.stringify(settings),
},
});
settings = JSON.parse(userState.user.setting) || {};
} catch (e) {
// Ignore parse errors
settings = {};
}
}
settings.language = lang;
const nextUser = {
...userState.user,
setting: JSON.stringify(settings),
};
userDispatch({
type: 'login',
payload: nextUser,
});
localStorage.setItem('user', JSON.stringify(nextUser));
}
} catch (error) {
// Silently ignore errors - language was already changed locally
if (previousLang) {
i18n.changeLanguage(previousLang);
localStorage.setItem('i18nextLng', previousLang);
}
console.error('Failed to save language preference:', error);
}
}

View File

@@ -73,7 +73,7 @@ export const useModelPricingData = () => {
[statusState],
);
// 默认货币与站点展示类型同步USD/CNYTOKENS 时仍允许切换视图内货币
// 默认货币与站点展示类型同步TOKENS 由视图层走倍率展示
const siteDisplayType = useMemo(
() => statusState?.status?.quota_display_type || 'USD',
[statusState],
@@ -88,6 +88,13 @@ export const useModelPricingData = () => {
}
}, [siteDisplayType]);
useEffect(() => {
if (siteDisplayType === 'TOKENS') {
setShowWithRecharge(false);
setCurrency('USD');
}
}, [siteDisplayType]);
const filteredModels = useMemo(() => {
let result = models;
@@ -356,6 +363,7 @@ export const useModelPricingData = () => {
setCurrentPage,
currency,
setCurrency,
siteDisplayType,
showWithRecharge,
setShowWithRecharge,
tokenUnit,

View File

@@ -152,7 +152,12 @@ export const useLogsData = () => {
const getInitialBillingDisplayMode = () => {
const savedMode = localStorage.getItem(BILLING_DISPLAY_MODE_STORAGE_KEY);
return savedMode === 'price' || savedMode === 'ratio' ? savedMode : 'price';
if (savedMode === 'price' || savedMode === 'ratio') {
return savedMode;
}
return localStorage.getItem('quota_display_type') === 'TOKENS'
? 'ratio'
: 'price';
};
// Column visibility state